[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>
This commit is contained in:
Christoph Hellwig 2007-06-29 10:57:55 +10:00 committed by Paul Mackerras
parent f3f59bec0c
commit 2cf2b3b49f
4 changed files with 45 additions and 14 deletions

View File

@ -54,17 +54,6 @@ struct spu_context *alloc_spu_context(struct spu_gang *gang)
if (gang) if (gang)
spu_gang_add_ctx(gang, ctx); 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); spu_set_timeslice(ctx);
goto out; goto out;
out_free: out_free:

View File

@ -301,9 +301,22 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx,
ctx->ops->master_start(ctx); ctx->ops->master_start(ctx);
ctx->event_return = 0; ctx->event_return = 0;
ret = spu_acquire_runnable(ctx, 0); spu_acquire(ctx);
if (ret) if (ctx->state == SPU_STATE_SAVED) {
return ret; __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); ret = spu_run_init(ctx, npc);
if (ret) { if (ret) {

View File

@ -96,6 +96,33 @@ void spu_set_timeslice(struct spu_context *ctx)
ctx->time_slice = SCALE_PRIO(DEF_SPU_TIMESLICE, ctx->prio); 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) static inline int node_allowed(int node)
{ {
cpumask_t mask; cpumask_t mask;

View File

@ -195,6 +195,8 @@ int spu_activate(struct spu_context *ctx, unsigned long flags);
void spu_deactivate(struct spu_context *ctx); void spu_deactivate(struct spu_context *ctx);
void spu_yield(struct spu_context *ctx); void spu_yield(struct spu_context *ctx);
void spu_set_timeslice(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); int __init spu_sched_init(void);
void __exit spu_sched_exit(void); void __exit spu_sched_exit(void);