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