aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched_rt.c49
1 files changed, 36 insertions, 13 deletions
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index 52d88f193afc..61d198845f00 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -296,29 +296,36 @@ static struct task_struct *pick_next_highest_task_rt(struct rq *rq,
296} 296}
297 297
298static DEFINE_PER_CPU(cpumask_t, local_cpu_mask); 298static DEFINE_PER_CPU(cpumask_t, local_cpu_mask);
299static DEFINE_PER_CPU(cpumask_t, valid_cpu_mask);
300 299
301static int find_lowest_cpus(struct task_struct *task, cpumask_t *lowest_mask) 300static int find_lowest_cpus(struct task_struct *task, cpumask_t *lowest_mask)
302{ 301{
303 int cpu;
304 cpumask_t *valid_mask = &__get_cpu_var(valid_cpu_mask);
305 int lowest_prio = -1; 302 int lowest_prio = -1;
303 int lowest_cpu = -1;
306 int count = 0; 304 int count = 0;
305 int cpu;
307 306
308 cpus_clear(*lowest_mask); 307 cpus_and(*lowest_mask, cpu_online_map, task->cpus_allowed);
309 cpus_and(*valid_mask, cpu_online_map, task->cpus_allowed);
310 308
311 /* 309 /*
312 * Scan each rq for the lowest prio. 310 * Scan each rq for the lowest prio.
313 */ 311 */
314 for_each_cpu_mask(cpu, *valid_mask) { 312 for_each_cpu_mask(cpu, *lowest_mask) {
315 struct rq *rq = cpu_rq(cpu); 313 struct rq *rq = cpu_rq(cpu);
316 314
317 /* We look for lowest RT prio or non-rt CPU */ 315 /* We look for lowest RT prio or non-rt CPU */
318 if (rq->rt.highest_prio >= MAX_RT_PRIO) { 316 if (rq->rt.highest_prio >= MAX_RT_PRIO) {
319 if (count) 317 /*
318 * if we already found a low RT queue
319 * and now we found this non-rt queue
320 * clear the mask and set our bit.
321 * Otherwise just return the queue as is
322 * and the count==1 will cause the algorithm
323 * to use the first bit found.
324 */
325 if (lowest_cpu != -1) {
320 cpus_clear(*lowest_mask); 326 cpus_clear(*lowest_mask);
321 cpu_set(rq->cpu, *lowest_mask); 327 cpu_set(rq->cpu, *lowest_mask);
328 }
322 return 1; 329 return 1;
323 } 330 }
324 331
@@ -328,13 +335,29 @@ static int find_lowest_cpus(struct task_struct *task, cpumask_t *lowest_mask)
328 if (rq->rt.highest_prio > lowest_prio) { 335 if (rq->rt.highest_prio > lowest_prio) {
329 /* new low - clear old data */ 336 /* new low - clear old data */
330 lowest_prio = rq->rt.highest_prio; 337 lowest_prio = rq->rt.highest_prio;
331 if (count) { 338 lowest_cpu = cpu;
332 cpus_clear(*lowest_mask); 339 count = 0;
333 count = 0;
334 }
335 } 340 }
336 cpu_set(rq->cpu, *lowest_mask);
337 count++; 341 count++;
342 } else
343 cpu_clear(cpu, *lowest_mask);
344 }
345
346 /*
347 * Clear out all the set bits that represent
348 * runqueues that were of higher prio than
349 * the lowest_prio.
350 */
351 if (lowest_cpu > 0) {
352 /*
353 * Perhaps we could add another cpumask op to
354 * zero out bits. Like cpu_zero_bits(cpumask, nrbits);
355 * Then that could be optimized to use memset and such.
356 */
357 for_each_cpu_mask(cpu, *lowest_mask) {
358 if (cpu >= lowest_cpu)
359 break;
360 cpu_clear(cpu, *lowest_mask);
338 } 361 }
339 } 362 }
340 363