diff options
author | Christoph Hellwig <hch@lst.de> | 2007-06-29 10:57:55 +1000 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-07-03 15:24:45 +1000 |
commit | 2cf2b3b49f10d2f4a0703070fc54ce1cd84a6cda (patch) | |
tree | d8b19ec2df628df8b5b10e2ac4576c28d51b9548 /arch/powerpc | |
parent | f3f59bec0c7ad083e9c95a550bcb1e9ca27e25f4 (diff) |
[POWERPC] spusched: Update scheduling paramters on every spu_run
Update scheduling information on every spu_run to allow for setting
threads to realtime priority just before running them. This requires
some slightly ugly code in spufs_run_spu because we can just update
the information unlocked if the spu is not runnable, but we need to
acquire the active_mutex when it is runnable to protect against
find_victim. This locking scheme requires opencoding
spu_acquire_runnable in spufs_run_spu which actually is a nice cleanup
all by itself.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/context.c | 11 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/run.c | 19 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/sched.c | 27 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/spufs.h | 2 |
4 files changed, 45 insertions, 14 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c index c5ec7cfc24b..c778d9178e0 100644 --- a/arch/powerpc/platforms/cell/spufs/context.c +++ b/arch/powerpc/platforms/cell/spufs/context.c @@ -54,17 +54,6 @@ struct spu_context *alloc_spu_context(struct spu_gang *gang) if (gang) spu_gang_add_ctx(gang, ctx); - /* - * We do our own priority calculations, so we normally want - * ->static_prio to start with. Unfortunately thies field - * contains junk for threads with a realtime scheduling - * policy so we have to look at ->prio in this case. - */ - if (rt_prio(current->prio)) - ctx->prio = current->prio; - else - ctx->prio = current->static_prio; - ctx->policy = current->policy; spu_set_timeslice(ctx); goto out; out_free: diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index 89b02b6bfc5..4e0db6ae0d5 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -301,9 +301,22 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx, ctx->ops->master_start(ctx); ctx->event_return = 0; - ret = spu_acquire_runnable(ctx, 0); - if (ret) - return ret; + spu_acquire(ctx); + if (ctx->state == SPU_STATE_SAVED) { + __spu_update_sched_info(ctx); + + ret = spu_activate(ctx, 0); + if (ret) { + spu_release(ctx); + goto out; + } + } else { + /* + * We have to update the scheduling priority under active_mutex + * to protect against find_victim(). + */ + spu_update_sched_info(ctx); + } ret = spu_run_init(ctx, npc); if (ret) { diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 002b40af4a7..3707c7fdbde 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -96,6 +96,33 @@ void spu_set_timeslice(struct spu_context *ctx) ctx->time_slice = SCALE_PRIO(DEF_SPU_TIMESLICE, ctx->prio); } +/* + * Update scheduling information from the owning thread. + */ +void __spu_update_sched_info(struct spu_context *ctx) +{ + /* + * We do our own priority calculations, so we normally want + * ->static_prio to start with. Unfortunately thies field + * contains junk for threads with a realtime scheduling + * policy so we have to look at ->prio in this case. + */ + if (rt_prio(current->prio)) + ctx->prio = current->prio; + else + ctx->prio = current->static_prio; + ctx->policy = current->policy; +} + +void spu_update_sched_info(struct spu_context *ctx) +{ + int node = ctx->spu->node; + + mutex_lock(&spu_prio->active_mutex[node]); + __spu_update_sched_info(ctx); + mutex_unlock(&spu_prio->active_mutex[node]); +} + static inline int node_allowed(int node) { cpumask_t mask; diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index fddc59c204b..ff77f904fa3 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -195,6 +195,8 @@ int spu_activate(struct spu_context *ctx, unsigned long flags); void spu_deactivate(struct spu_context *ctx); void spu_yield(struct spu_context *ctx); void spu_set_timeslice(struct spu_context *ctx); +void spu_update_sched_info(struct spu_context *ctx); +void __spu_update_sched_info(struct spu_context *ctx); int __init spu_sched_init(void); void __exit spu_sched_exit(void); |