[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:
parent
f3f59bec0c
commit
2cf2b3b49f
|
@ -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:
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue