aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/spufs/switch.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd.bergmann@de.ibm.com>2007-04-23 15:08:15 -0400
committerArnd Bergmann <arnd@klappe.arndb.de>2007-04-23 15:18:55 -0400
commit57dace2391ba10135e38457904121e7ef34d0c83 (patch)
tree1be720be47bd6f1d929e9242b8a89a8f2e5fe61d /arch/powerpc/platforms/cell/spufs/switch.c
parent62c05d583ec016c40011462d5f03b072bfbd3dc7 (diff)
[POWERPC] spufs: make spu page faults not block scheduling
Until now, we have always entered the spu page fault handler with a mutex for the spu context held. This has multiple bad side-effects: - it becomes impossible to suspend the context during page faults - if an spu program attempts to access its own mmio areas through DMA, we get an immediate livelock when the nopage function tries to acquire the same mutex This patch makes the page fault logic operate on a struct spu_context instead of a struct spu, and moves it from spu_base.c to a new file fault.c inside of spufs. We now also need to copy the dar and dsisr contents of the last fault into the saved context to have it accessible in case we schedule out the context before activating the page fault handler. Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Diffstat (limited to 'arch/powerpc/platforms/cell/spufs/switch.c')
-rw-r--r--arch/powerpc/platforms/cell/spufs/switch.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index fd91c73de34e..8347c4a3f894 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -2084,6 +2084,10 @@ int spu_save(struct spu_state *prev, struct spu *spu)
2084 int rc; 2084 int rc;
2085 2085
2086 acquire_spu_lock(spu); /* Step 1. */ 2086 acquire_spu_lock(spu); /* Step 1. */
2087 prev->dar = spu->dar;
2088 prev->dsisr = spu->dsisr;
2089 spu->dar = 0;
2090 spu->dsisr = 0;
2087 rc = __do_spu_save(prev, spu); /* Steps 2-53. */ 2091 rc = __do_spu_save(prev, spu); /* Steps 2-53. */
2088 release_spu_lock(spu); 2092 release_spu_lock(spu);
2089 if (rc != 0 && rc != 2 && rc != 6) { 2093 if (rc != 0 && rc != 2 && rc != 6) {
@@ -2109,9 +2113,9 @@ int spu_restore(struct spu_state *new, struct spu *spu)
2109 2113
2110 acquire_spu_lock(spu); 2114 acquire_spu_lock(spu);
2111 harvest(NULL, spu); 2115 harvest(NULL, spu);
2112 spu->dar = 0;
2113 spu->dsisr = 0;
2114 spu->slb_replace = 0; 2116 spu->slb_replace = 0;
2117 new->dar = 0;
2118 new->dsisr = 0;
2115 spu->class_0_pending = 0; 2119 spu->class_0_pending = 0;
2116 rc = __do_spu_restore(new, spu); 2120 rc = __do_spu_restore(new, spu);
2117 release_spu_lock(spu); 2121 release_spu_lock(spu);