b/arch/powerpc/platforms/cell/spufs/fault.c
@@ -149,8 +149,16 @@ int spufs_handle_class1(struct spu_context *ctx)
local_irq_restore(flags);
/* hashing failed, so try the actual fault handler */
- if (ret)
+ if (ret) {
+ struct spu_gang *gang = ctx->gang;
+
+ atomic_inc(&gang->nfaulting);
+ if (atomic_read(&gang->nrunnable) ==
+ atomic_read(&gang->nfaulting))
+ spu_yield(ctx);
ret = spu_handle_mm_fault(current->mm, ea, dsisr, &flt);
+ atomic_dec(&gang->nfaulting);
+ }
/*
* This is nasty: we need the state_mutex for all the bookkeeping even
@@ -166,8 +174,7 @@ int spufs_handle_class1(struct spu_context *ctx)
ctx->csa.class_1_dar = ctx->csa.class_1_dsisr = 0;
/*
- * If we handled the fault successfully and are in runnable
- * state, restart the DMA.
+ * If we handled the fault successfully, restart the DMA.
* In case of unhandled error report the problem to user space.
*/
if (!ret) {
b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -168,6 +168,7 @@ struct spu_gang {
int prio;
atomic_t nstarted;
atomic_t nrunnable;
+ atomic_t nfaulting;
unsigned long sched_flags;
struct list_head rq;