diff options
| author | Luke Browning <lukebrowning@us.ibm.com> | 2008-06-15 20:42:38 -0400 |
|---|---|---|
| committer | Jeremy Kerr <jk@ozlabs.org> | 2008-06-16 00:35:01 -0400 |
| commit | 028fda0a6c80c26f1d9f403b4490b9ddc74ffa3b (patch) | |
| tree | bb8c8977b4b4991919d8995c01f197fb4e5f00dd | |
| parent | 2c911a14b74fa9cf815a936f310e4fa85bee77ce (diff) | |
powerpc/spufs: fix missed stop-and-signal event
There is a delay in the transition to the stopped state for class 2
interrupts. In some cases, the controlling thread detects the state of
the spu as running, and goes back to sleep resulting in a hung
application as the event is missed.
This change detects the stop condition and re-generates the wakeup event
after a context save.
Signed-off-by: Luke Browning <lukebrowning@us.ibm.com>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
| -rw-r--r-- | arch/powerpc/platforms/cell/spufs/sched.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index cd725670b1b5..e929e70a84e3 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c | |||
| @@ -407,6 +407,8 @@ static int has_affinity(struct spu_context *ctx) | |||
| 407 | */ | 407 | */ |
| 408 | static void spu_unbind_context(struct spu *spu, struct spu_context *ctx) | 408 | static void spu_unbind_context(struct spu *spu, struct spu_context *ctx) |
| 409 | { | 409 | { |
| 410 | u32 status; | ||
| 411 | |||
| 410 | spu_context_trace(spu_unbind_context__enter, ctx, spu); | 412 | spu_context_trace(spu_unbind_context__enter, ctx, spu); |
| 411 | 413 | ||
| 412 | spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); | 414 | spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); |
| @@ -452,6 +454,9 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx) | |||
| 452 | /* This maps the underlying spu state to idle */ | 454 | /* This maps the underlying spu state to idle */ |
| 453 | spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED); | 455 | spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED); |
| 454 | ctx->spu = NULL; | 456 | ctx->spu = NULL; |
| 457 | |||
| 458 | if (spu_stopped(ctx, &status)) | ||
| 459 | wake_up_all(&ctx->stop_wq); | ||
| 455 | } | 460 | } |
| 456 | 461 | ||
| 457 | /** | 462 | /** |
