aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c98
1 files changed, 61 insertions, 37 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 7e9657eb690c..1d330f67f5ae 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -68,6 +68,43 @@ static inline int node_allowed(int node)
68 return 1; 68 return 1;
69} 69}
70 70
71/**
72 * spu_add_to_active_list - add spu to active list
73 * @spu: spu to add to the active list
74 */
75static void spu_add_to_active_list(struct spu *spu)
76{
77 mutex_lock(&spu_prio->active_mutex[spu->node]);
78 list_add_tail(&spu->list, &spu_prio->active_list[spu->node]);
79 mutex_unlock(&spu_prio->active_mutex[spu->node]);
80}
81
82/**
83 * spu_remove_from_active_list - remove spu from active list
84 * @spu: spu to remove from the active list
85 *
86 * This function removes an spu from the active list. If the spu was
87 * found on the active list the function returns 1, else it doesn't do
88 * anything and returns 0.
89 */
90static int spu_remove_from_active_list(struct spu *spu)
91{
92 int node = spu->node;
93 struct spu *tmp;
94 int rc = 0;
95
96 mutex_lock(&spu_prio->active_mutex[node]);
97 list_for_each_entry(tmp, &spu_prio->active_list[node], list) {
98 if (tmp == spu) {
99 list_del_init(&spu->list);
100 rc = 1;
101 break;
102 }
103 }
104 mutex_unlock(&spu_prio->active_mutex[node]);
105 return rc;
106}
107
71static inline void mm_needs_global_tlbie(struct mm_struct *mm) 108static inline void mm_needs_global_tlbie(struct mm_struct *mm)
72{ 109{
73 int nr = (NR_CPUS > 1) ? NR_CPUS : NR_CPUS + 1; 110 int nr = (NR_CPUS > 1) ? NR_CPUS : NR_CPUS + 1;
@@ -94,8 +131,12 @@ int spu_switch_event_unregister(struct notifier_block * n)
94 return blocking_notifier_chain_unregister(&spu_switch_notifier, n); 131 return blocking_notifier_chain_unregister(&spu_switch_notifier, n);
95} 132}
96 133
97 134/**
98static inline void bind_context(struct spu *spu, struct spu_context *ctx) 135 * spu_bind_context - bind spu context to physical spu
136 * @spu: physical spu to bind to
137 * @ctx: context to bind
138 */
139static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
99{ 140{
100 pr_debug("%s: pid=%d SPU=%d NODE=%d\n", __FUNCTION__, current->pid, 141 pr_debug("%s: pid=%d SPU=%d NODE=%d\n", __FUNCTION__, current->pid,
101 spu->number, spu->node); 142 spu->number, spu->node);
@@ -118,14 +159,24 @@ static inline void bind_context(struct spu *spu, struct spu_context *ctx)
118 spu->timestamp = jiffies; 159 spu->timestamp = jiffies;
119 spu_cpu_affinity_set(spu, raw_smp_processor_id()); 160 spu_cpu_affinity_set(spu, raw_smp_processor_id());
120 spu_switch_notify(spu, ctx); 161 spu_switch_notify(spu, ctx);
121 162 spu_add_to_active_list(spu);
122 ctx->state = SPU_STATE_RUNNABLE; 163 ctx->state = SPU_STATE_RUNNABLE;
123} 164}
124 165
125static inline void unbind_context(struct spu *spu, struct spu_context *ctx) 166/**
167 * spu_unbind_context - unbind spu context from physical spu
168 * @spu: physical spu to unbind from
169 * @ctx: context to unbind
170 *
171 * If the spu was on the active list the function returns 1, else 0.
172 */
173static int spu_unbind_context(struct spu *spu, struct spu_context *ctx)
126{ 174{
175 int was_active = spu_remove_from_active_list(spu);
176
127 pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__, 177 pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__,
128 spu->pid, spu->number, spu->node); 178 spu->pid, spu->number, spu->node);
179
129 spu_switch_notify(spu, NULL); 180 spu_switch_notify(spu, NULL);
130 spu_unmap_mappings(ctx); 181 spu_unmap_mappings(ctx);
131 spu_save(&ctx->csa, spu); 182 spu_save(&ctx->csa, spu);
@@ -143,6 +194,8 @@ static inline void unbind_context(struct spu *spu, struct spu_context *ctx)
143 ctx->spu = NULL; 194 ctx->spu = NULL;
144 spu->flags = 0; 195 spu->flags = 0;
145 spu->ctx = NULL; 196 spu->ctx = NULL;
197
198 return was_active;
146} 199}
147 200
148static inline void spu_add_wq(wait_queue_head_t * wq, wait_queue_t * wait, 201static inline void spu_add_wq(wait_queue_head_t * wq, wait_queue_t * wait,
@@ -199,33 +252,6 @@ static void spu_prio_wakeup(void)
199 } 252 }
200} 253}
201 254
202static int get_active_spu(struct spu *spu)
203{
204 int node = spu->node;
205 struct spu *tmp;
206 int rc = 0;
207
208 mutex_lock(&spu_prio->active_mutex[node]);
209 list_for_each_entry(tmp, &spu_prio->active_list[node], list) {
210 if (tmp == spu) {
211 list_del_init(&spu->list);
212 rc = 1;
213 break;
214 }
215 }
216 mutex_unlock(&spu_prio->active_mutex[node]);
217 return rc;
218}
219
220static void put_active_spu(struct spu *spu)
221{
222 int node = spu->node;
223
224 mutex_lock(&spu_prio->active_mutex[node]);
225 list_add_tail(&spu->list, &spu_prio->active_list[node]);
226 mutex_unlock(&spu_prio->active_mutex[node]);
227}
228
229static struct spu *spu_get_idle(struct spu_context *ctx, u64 flags) 255static struct spu *spu_get_idle(struct spu_context *ctx, u64 flags)
230{ 256{
231 struct spu *spu = NULL; 257 struct spu *spu = NULL;
@@ -275,8 +301,7 @@ int spu_activate(struct spu_context *ctx, u64 flags)
275 spu_prio_wakeup(); 301 spu_prio_wakeup();
276 break; 302 break;
277 } 303 }
278 bind_context(spu, ctx); 304 spu_bind_context(spu, ctx);
279 put_active_spu(spu);
280 break; 305 break;
281 } 306 }
282 spu_prio_wait(ctx, flags); 307 spu_prio_wait(ctx, flags);
@@ -292,14 +317,13 @@ int spu_activate(struct spu_context *ctx, u64 flags)
292void spu_deactivate(struct spu_context *ctx) 317void spu_deactivate(struct spu_context *ctx)
293{ 318{
294 struct spu *spu; 319 struct spu *spu;
295 int needs_idle; 320 int was_active;
296 321
297 spu = ctx->spu; 322 spu = ctx->spu;
298 if (!spu) 323 if (!spu)
299 return; 324 return;
300 needs_idle = get_active_spu(spu); 325 was_active = spu_unbind_context(spu, ctx);
301 unbind_context(spu, ctx); 326 if (was_active) {
302 if (needs_idle) {
303 spu_free(spu); 327 spu_free(spu);
304 spu_prio_wakeup(); 328 spu_prio_wakeup();
305 } 329 }