aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched_rt.c
diff options
context:
space:
mode:
authorPeter Williams <pwil3058@bigpond.net.au>2007-08-09 05:16:46 -0400
committerIngo Molnar <mingo@elte.hu>2007-08-09 05:16:46 -0400
commita4ac01c36e286dd1b9a1d5cd7422c5af51dc55f8 (patch)
tree0c275d58a4835a3d604d9cac4e1dd7c25714e150 /kernel/sched_rt.c
parentaea25401c3347d9f3a64ebdc81043be246a9f631 (diff)
sched: fix bug in balance_tasks()
There are two problems with balance_tasks() and how it used: 1. The variables best_prio and best_prio_seen (inherited from the old move_tasks()) were only required to handle problems caused by the active/expired arrays, the order in which they were processed and the possibility that the task with the highest priority could be on either. These issues are no longer present and the extra overhead associated with their use is unnecessary (and possibly wrong). 2. In the absence of CONFIG_FAIR_GROUP_SCHED being set, the same this_best_prio variable needs to be used by all scheduling classes or there is a risk of moving too much load. E.g. if the highest priority task on this at the beginning is a fairly low priority task and the rt class migrates a task (during its turn) then that moved task becomes the new highest priority task on this_rq but when the sched_fair class initializes its copy of this_best_prio it will get the priority of the original highest priority task as, due to the run queue locks being held, the reschedule triggered by pull_task() will not have taken place. This could result in inappropriate overriding of skip_for_load and excessive load being moved. The attached patch addresses these problems by deleting all reference to best_prio and best_prio_seen and making this_best_prio a reference parameter to the various functions involved. load_balance_fair() has also been modified so that this_best_prio is only reset (in the loop) if CONFIG_FAIR_GROUP_SCHED is set. This should preserve the effect of helping spread groups' higher priority tasks around the available CPUs while improving system performance when CONFIG_FAIR_GROUP_SCHED isn't set. Signed-off-by: Peter Williams <pwil3058@bigpond.net.au> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/sched_rt.c')
-rw-r--r--kernel/sched_rt.c19
1 files changed, 2 insertions, 17 deletions
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index 2b0626a43cb8..5b559e8c8aa6 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -176,26 +176,12 @@ static unsigned long
176load_balance_rt(struct rq *this_rq, int this_cpu, struct rq *busiest, 176load_balance_rt(struct rq *this_rq, int this_cpu, struct rq *busiest,
177 unsigned long max_nr_move, unsigned long max_load_move, 177 unsigned long max_nr_move, unsigned long max_load_move,
178 struct sched_domain *sd, enum cpu_idle_type idle, 178 struct sched_domain *sd, enum cpu_idle_type idle,
179 int *all_pinned) 179 int *all_pinned, int *this_best_prio)
180{ 180{
181 int this_best_prio, best_prio, best_prio_seen = 0;
182 int nr_moved; 181 int nr_moved;
183 struct rq_iterator rt_rq_iterator; 182 struct rq_iterator rt_rq_iterator;
184 unsigned long load_moved; 183 unsigned long load_moved;
185 184
186 best_prio = sched_find_first_bit(busiest->rt.active.bitmap);
187 this_best_prio = sched_find_first_bit(this_rq->rt.active.bitmap);
188
189 /*
190 * Enable handling of the case where there is more than one task
191 * with the best priority. If the current running task is one
192 * of those with prio==best_prio we know it won't be moved
193 * and therefore it's safe to override the skip (based on load)
194 * of any task we find with that prio.
195 */
196 if (busiest->curr->prio == best_prio)
197 best_prio_seen = 1;
198
199 rt_rq_iterator.start = load_balance_start_rt; 185 rt_rq_iterator.start = load_balance_start_rt;
200 rt_rq_iterator.next = load_balance_next_rt; 186 rt_rq_iterator.next = load_balance_next_rt;
201 /* pass 'busiest' rq argument into 187 /* pass 'busiest' rq argument into
@@ -205,8 +191,7 @@ load_balance_rt(struct rq *this_rq, int this_cpu, struct rq *busiest,
205 191
206 nr_moved = balance_tasks(this_rq, this_cpu, busiest, max_nr_move, 192 nr_moved = balance_tasks(this_rq, this_cpu, busiest, max_nr_move,
207 max_load_move, sd, idle, all_pinned, &load_moved, 193 max_load_move, sd, idle, all_pinned, &load_moved,
208 this_best_prio, best_prio, best_prio_seen, 194 this_best_prio, &rt_rq_iterator);
209 &rt_rq_iterator);
210 195
211 return load_moved; 196 return load_moved;
212} 197}