aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2007-06-28 20:57:55 -0400
committerPaul Mackerras <paulus@samba.org>2007-07-03 01:24:45 -0400
commit2cf2b3b49f10d2f4a0703070fc54ce1cd84a6cda (patch)
treed8b19ec2df628df8b5b10e2ac4576c28d51b9548
parentf3f59bec0c7ad083e9c95a550bcb1e9ca27e25f4 (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>
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c11
-rw-r--r--arch/powerpc/platforms/cell/spufs/run.c19
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c27
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h2
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 c5ec7cfc24b5..c778d9178e0f 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)
54 if (gang) 54 if (gang)
55 spu_gang_add_ctx(gang, ctx); 55 spu_gang_add_ctx(gang, ctx);
56 56
57 /*
58 * We do our own priority calculations, so we normally want
59 * ->static_prio to start with. Unfortunately thies field
60 * contains junk for threads with a realtime scheduling
61 * policy so we have to look at ->prio in this case.
62 */
63 if (rt_prio(current->prio))
64 ctx->prio = current->prio;
65 else
66 ctx->prio = current->static_prio;
67 ctx->policy = current->policy;
68 spu_set_timeslice(ctx); 57 spu_set_timeslice(ctx);
69 goto out; 58 goto out;
70out_free: 59out_free:
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index 89b02b6bfc55..4e0db6ae0d5e 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,
301 ctx->ops->master_start(ctx); 301 ctx->ops->master_start(ctx);
302 ctx->event_return = 0; 302 ctx->event_return = 0;
303 303
304 ret = spu_acquire_runnable(ctx, 0); 304 spu_acquire(ctx);
305 if (ret) 305 if (ctx->state == SPU_STATE_SAVED) {
306 return ret; 306 __spu_update_sched_info(ctx);
307
308 ret = spu_activate(ctx, 0);
309 if (ret) {
310 spu_release(ctx);
311 goto out;
312 }
313 } else {
314 /*
315 * We have to update the scheduling priority under active_mutex
316 * to protect against find_victim().
317 */
318 spu_update_sched_info(ctx);
319 }
307 320
308 ret = spu_run_init(ctx, npc); 321 ret = spu_run_init(ctx, npc);
309 if (ret) { 322 if (ret) {
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 002b40af4a77..3707c7fdbdee 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)
96 ctx->time_slice = SCALE_PRIO(DEF_SPU_TIMESLICE, ctx->prio); 96 ctx->time_slice = SCALE_PRIO(DEF_SPU_TIMESLICE, ctx->prio);
97} 97}
98 98
99/*
100 * Update scheduling information from the owning thread.
101 */
102void __spu_update_sched_info(struct spu_context *ctx)
103{
104 /*
105 * We do our own priority calculations, so we normally want
106 * ->static_prio to start with. Unfortunately thies field
107 * contains junk for threads with a realtime scheduling
108 * policy so we have to look at ->prio in this case.
109 */
110 if (rt_prio(current->prio))
111 ctx->prio = current->prio;
112 else
113 ctx->prio = current->static_prio;
114 ctx->policy = current->policy;
115}
116
117void spu_update_sched_info(struct spu_context *ctx)
118{
119 int node = ctx->spu->node;
120
121 mutex_lock(&spu_prio->active_mutex[node]);
122 __spu_update_sched_info(ctx);
123 mutex_unlock(&spu_prio->active_mutex[node]);
124}
125
99static inline int node_allowed(int node) 126static inline int node_allowed(int node)
100{ 127{
101 cpumask_t mask; 128 cpumask_t mask;
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index fddc59c204b5..ff77f904fa31 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);
195void spu_deactivate(struct spu_context *ctx); 195void spu_deactivate(struct spu_context *ctx);
196void spu_yield(struct spu_context *ctx); 196void spu_yield(struct spu_context *ctx);
197void spu_set_timeslice(struct spu_context *ctx); 197void spu_set_timeslice(struct spu_context *ctx);
198void spu_update_sched_info(struct spu_context *ctx);
199void __spu_update_sched_info(struct spu_context *ctx);
198int __init spu_sched_init(void); 200int __init spu_sched_init(void);
199void __exit spu_sched_exit(void); 201void __exit spu_sched_exit(void);
200 202