aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/run.c9
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c43
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h5
4 files changed, 56 insertions, 3 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index d581f4ec99ba..04ad2e364e97 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -54,7 +54,9 @@ 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 ctx->rt_priority = current->rt_priority; 56 ctx->rt_priority = current->rt_priority;
57 ctx->policy = current->policy;
57 ctx->prio = current->prio; 58 ctx->prio = current->prio;
59 INIT_DELAYED_WORK(&ctx->sched_work, spu_sched_tick);
58 goto out; 60 goto out;
59out_free: 61out_free:
60 kfree(ctx); 62 kfree(ctx);
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index a973e79e9fdc..353a8fa07ab8 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -164,8 +164,10 @@ static inline int spu_run_init(struct spu_context *ctx, u32 * npc)
164 (SPU_RUNCNTL_RUNNABLE | SPU_RUNCNTL_ISOLATE); 164 (SPU_RUNCNTL_RUNNABLE | SPU_RUNCNTL_ISOLATE);
165 if (runcntl == 0) 165 if (runcntl == 0)
166 runcntl = SPU_RUNCNTL_RUNNABLE; 166 runcntl = SPU_RUNCNTL_RUNNABLE;
167 } else 167 } else {
168 spu_start_tick(ctx);
168 ctx->ops->npc_write(ctx, *npc); 169 ctx->ops->npc_write(ctx, *npc);
170 }
169 171
170 ctx->ops->runcntl_write(ctx, runcntl); 172 ctx->ops->runcntl_write(ctx, runcntl);
171 return ret; 173 return ret;
@@ -176,6 +178,7 @@ static inline int spu_run_fini(struct spu_context *ctx, u32 * npc,
176{ 178{
177 int ret = 0; 179 int ret = 0;
178 180
181 spu_stop_tick(ctx);
179 *status = ctx->ops->status_read(ctx); 182 *status = ctx->ops->status_read(ctx);
180 *npc = ctx->ops->npc_read(ctx); 183 *npc = ctx->ops->npc_read(ctx);
181 spu_release(ctx); 184 spu_release(ctx);
@@ -329,8 +332,10 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx,
329 } 332 }
330 if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) { 333 if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) {
331 ret = spu_reacquire_runnable(ctx, npc, &status); 334 ret = spu_reacquire_runnable(ctx, npc, &status);
332 if (ret) 335 if (ret) {
336 spu_stop_tick(ctx);
333 goto out2; 337 goto out2;
338 }
334 continue; 339 continue;
335 } 340 }
336 ret = spu_process_events(ctx); 341 ret = spu_process_events(ctx);
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index ba4b01e01ace..2f25e68b4bac 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -44,7 +44,7 @@
44#include <asm/spu_priv1.h> 44#include <asm/spu_priv1.h>
45#include "spufs.h" 45#include "spufs.h"
46 46
47#define SPU_MIN_TIMESLICE (100 * HZ / 1000) 47#define SPU_TIMESLICE (HZ)
48 48
49struct spu_prio_array { 49struct spu_prio_array {
50 DECLARE_BITMAP(bitmap, MAX_PRIO); 50 DECLARE_BITMAP(bitmap, MAX_PRIO);
@@ -55,6 +55,7 @@ struct spu_prio_array {
55}; 55};
56 56
57static struct spu_prio_array *spu_prio; 57static struct spu_prio_array *spu_prio;
58static struct workqueue_struct *spu_sched_wq;
58 59
59static inline int node_allowed(int node) 60static inline int node_allowed(int node)
60{ 61{
@@ -68,6 +69,40 @@ static inline int node_allowed(int node)
68 return 1; 69 return 1;
69} 70}
70 71
72void spu_start_tick(struct spu_context *ctx)
73{
74 if (ctx->policy == SCHED_RR)
75 queue_delayed_work(spu_sched_wq, &ctx->sched_work, SPU_TIMESLICE);
76}
77
78void spu_stop_tick(struct spu_context *ctx)
79{
80 if (ctx->policy == SCHED_RR)
81 cancel_delayed_work(&ctx->sched_work);
82}
83
84void spu_sched_tick(struct work_struct *work)
85{
86 struct spu_context *ctx =
87 container_of(work, struct spu_context, sched_work.work);
88 struct spu *spu;
89 int rearm = 1;
90
91 mutex_lock(&ctx->state_mutex);
92 spu = ctx->spu;
93 if (spu) {
94 int best = sched_find_first_bit(spu_prio->bitmap);
95 if (best <= ctx->prio) {
96 spu_deactivate(ctx);
97 rearm = 0;
98 }
99 }
100 mutex_unlock(&ctx->state_mutex);
101
102 if (rearm)
103 spu_start_tick(ctx);
104}
105
71/** 106/**
72 * spu_add_to_active_list - add spu to active list 107 * spu_add_to_active_list - add spu to active list
73 * @spu: spu to add to the active list 108 * @spu: spu to add to the active list
@@ -437,10 +472,15 @@ int __init spu_sched_init(void)
437{ 472{
438 int i; 473 int i;
439 474
475 spu_sched_wq = create_singlethread_workqueue("spusched");
476 if (!spu_sched_wq)
477 return 1;
478
440 spu_prio = kzalloc(sizeof(struct spu_prio_array), GFP_KERNEL); 479 spu_prio = kzalloc(sizeof(struct spu_prio_array), GFP_KERNEL);
441 if (!spu_prio) { 480 if (!spu_prio) {
442 printk(KERN_WARNING "%s: Unable to allocate priority queue.\n", 481 printk(KERN_WARNING "%s: Unable to allocate priority queue.\n",
443 __FUNCTION__); 482 __FUNCTION__);
483 destroy_workqueue(spu_sched_wq);
444 return 1; 484 return 1;
445 } 485 }
446 for (i = 0; i < MAX_PRIO; i++) { 486 for (i = 0; i < MAX_PRIO; i++) {
@@ -471,4 +511,5 @@ void __exit spu_sched_exit(void)
471 mutex_unlock(&spu_prio->active_mutex[node]); 511 mutex_unlock(&spu_prio->active_mutex[node]);
472 } 512 }
473 kfree(spu_prio); 513 kfree(spu_prio);
514 destroy_workqueue(spu_sched_wq);
474} 515}
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 85b182d16464..0c437891dfd5 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -82,8 +82,10 @@ struct spu_context {
82 82
83 /* scheduler fields */ 83 /* scheduler fields */
84 struct list_head rq; 84 struct list_head rq;
85 struct delayed_work sched_work;
85 unsigned long sched_flags; 86 unsigned long sched_flags;
86 unsigned long rt_priority; 87 unsigned long rt_priority;
88 int policy;
87 int prio; 89 int prio;
88}; 90};
89 91
@@ -195,6 +197,9 @@ enum {
195int spu_activate(struct spu_context *ctx, unsigned long flags); 197int spu_activate(struct spu_context *ctx, unsigned long flags);
196void spu_deactivate(struct spu_context *ctx); 198void spu_deactivate(struct spu_context *ctx);
197void spu_yield(struct spu_context *ctx); 199void spu_yield(struct spu_context *ctx);
200void spu_start_tick(struct spu_context *ctx);
201void spu_stop_tick(struct spu_context *ctx);
202void spu_sched_tick(struct work_struct *work);
198int __init spu_sched_init(void); 203int __init spu_sched_init(void);
199void __exit spu_sched_exit(void); 204void __exit spu_sched_exit(void);
200 205