diff options
author | Christoph Hellwig <hch@lst.de> | 2007-06-28 20:57:55 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-07-03 01:24:45 -0400 |
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 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; |
70 | out_free: | 59 | out_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 | */ | ||
102 | void __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 | |||
117 | void 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 | |||
99 | static inline int node_allowed(int node) | 126 | static 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); | |||
195 | void spu_deactivate(struct spu_context *ctx); | 195 | void spu_deactivate(struct spu_context *ctx); |
196 | void spu_yield(struct spu_context *ctx); | 196 | void spu_yield(struct spu_context *ctx); |
197 | void spu_set_timeslice(struct spu_context *ctx); | 197 | void spu_set_timeslice(struct spu_context *ctx); |
198 | void spu_update_sched_info(struct spu_context *ctx); | ||
199 | void __spu_update_sched_info(struct spu_context *ctx); | ||
198 | int __init spu_sched_init(void); | 200 | int __init spu_sched_init(void); |
199 | void __exit spu_sched_exit(void); | 201 | void __exit spu_sched_exit(void); |
200 | 202 | ||