forked from Minki/linux
[POWERPC] spufs: use cancel_rearming_delayed_workqueue when stopping spu contexts
The scheduler workqueue may rearm itself and deadlock when we try to stop it. Put a flag in place to avoid skip the work if we're tearing down the context. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
This commit is contained in:
parent
390cbb56a7
commit
0887309589
@ -71,14 +71,25 @@ static inline int node_allowed(int node)
|
||||
|
||||
void spu_start_tick(struct spu_context *ctx)
|
||||
{
|
||||
if (ctx->policy == SCHED_RR)
|
||||
if (ctx->policy == SCHED_RR) {
|
||||
/*
|
||||
* Make sure the exiting bit is cleared.
|
||||
*/
|
||||
clear_bit(SPU_SCHED_EXITING, &ctx->sched_flags);
|
||||
queue_delayed_work(spu_sched_wq, &ctx->sched_work, SPU_TIMESLICE);
|
||||
}
|
||||
}
|
||||
|
||||
void spu_stop_tick(struct spu_context *ctx)
|
||||
{
|
||||
if (ctx->policy == SCHED_RR)
|
||||
if (ctx->policy == SCHED_RR) {
|
||||
/*
|
||||
* While the work can be rearming normally setting this flag
|
||||
* makes sure it does not rearm itself anymore.
|
||||
*/
|
||||
set_bit(SPU_SCHED_EXITING, &ctx->sched_flags);
|
||||
cancel_delayed_work(&ctx->sched_work);
|
||||
}
|
||||
}
|
||||
|
||||
void spu_sched_tick(struct work_struct *work)
|
||||
@ -88,6 +99,14 @@ void spu_sched_tick(struct work_struct *work)
|
||||
struct spu *spu;
|
||||
int rearm = 1;
|
||||
|
||||
/*
|
||||
* If this context is being stopped avoid rescheduling from the
|
||||
* scheduler tick because we would block on the state_mutex.
|
||||
* The caller will yield the spu later on anyway.
|
||||
*/
|
||||
if (test_bit(SPU_SCHED_EXITING, &ctx->sched_flags))
|
||||
return;
|
||||
|
||||
mutex_lock(&ctx->state_mutex);
|
||||
spu = ctx->spu;
|
||||
if (spu) {
|
||||
@ -377,7 +396,7 @@ static struct spu *find_victim(struct spu_context *ctx)
|
||||
* @ctx: spu context to schedule
|
||||
* @flags: flags (currently ignored)
|
||||
*
|
||||
* Tries to find a free spu to run @ctx. If no free spu is availble
|
||||
* Tries to find a free spu to run @ctx. If no free spu is available
|
||||
* add the context to the runqueue so it gets woken up once an spu
|
||||
* is available.
|
||||
*/
|
||||
|
@ -41,7 +41,7 @@ struct spu_gang;
|
||||
|
||||
/* ctx->sched_flags */
|
||||
enum {
|
||||
SPU_SCHED_WAKE = 0, /* currently unused */
|
||||
SPU_SCHED_EXITING = 0,
|
||||
};
|
||||
|
||||
struct spu_context {
|
||||
|
Loading…
Reference in New Issue
Block a user