summaryrefslogtreecommitdiffstats
path: root/kernel/sched_fair.c
diff options
context:
space:
mode:
authorPeter Williams <pwil3058@bigpond.net.au>2007-10-24 18:23:51 +0200
committerIngo Molnar <mingo@elte.hu>2007-10-24 18:23:51 +0200
commite1d1484f72127a5580d37c379f6a5b2c2786434c (patch)
treee3e6529c5b9079f35b2c60bbd346a3c51c2b2c13 /kernel/sched_fair.c
parenta0f846aa76c3e03d54c1700a87cab3a46ccd71e2 (diff)
sched: reduce balance-tasks overhead
At the moment, balance_tasks() provides low level functionality for both move_tasks() and move_one_task() (indirectly) via the load_balance() function (in the sched_class interface) which also provides dual functionality. This dual functionality complicates the interfaces and internal mechanisms and makes the run time overhead of operations that are called with two run queue locks held. This patch addresses this issue and reduces the overhead of these operations. Signed-off-by: Peter Williams <pwil3058@bigpond.net.au> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/sched_fair.c')
-rw-r--r--kernel/sched_fair.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 166ed6db600..a90d0457d60 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -936,12 +936,11 @@ static int cfs_rq_best_prio(struct cfs_rq *cfs_rq)
static unsigned long
load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
- unsigned long max_nr_move, unsigned long max_load_move,
+ unsigned long max_load_move,
struct sched_domain *sd, enum cpu_idle_type idle,
int *all_pinned, int *this_best_prio)
{
struct cfs_rq *busy_cfs_rq;
- unsigned long load_moved, total_nr_moved = 0, nr_moved;
long rem_load_move = max_load_move;
struct rq_iterator cfs_rq_iterator;
@@ -969,25 +968,47 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
#else
# define maxload rem_load_move
#endif
- /* pass busy_cfs_rq argument into
+ /*
+ * pass busy_cfs_rq argument into
* load_balance_[start|next]_fair iterators
*/
cfs_rq_iterator.arg = busy_cfs_rq;
- nr_moved = balance_tasks(this_rq, this_cpu, busiest,
- max_nr_move, maxload, sd, idle, all_pinned,
- &load_moved, this_best_prio, &cfs_rq_iterator);
-
- total_nr_moved += nr_moved;
- max_nr_move -= nr_moved;
- rem_load_move -= load_moved;
+ rem_load_move -= balance_tasks(this_rq, this_cpu, busiest,
+ maxload, sd, idle, all_pinned,
+ this_best_prio,
+ &cfs_rq_iterator);
- if (max_nr_move <= 0 || rem_load_move <= 0)
+ if (rem_load_move <= 0)
break;
}
return max_load_move - rem_load_move;
}
+static int
+move_one_task_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
+ struct sched_domain *sd, enum cpu_idle_type idle)
+{
+ struct cfs_rq *busy_cfs_rq;
+ struct rq_iterator cfs_rq_iterator;
+
+ cfs_rq_iterator.start = load_balance_start_fair;
+ cfs_rq_iterator.next = load_balance_next_fair;
+
+ for_each_leaf_cfs_rq(busiest, busy_cfs_rq) {
+ /*
+ * pass busy_cfs_rq argument into
+ * load_balance_[start|next]_fair iterators
+ */
+ cfs_rq_iterator.arg = busy_cfs_rq;
+ if (iter_move_one_task(this_rq, this_cpu, busiest, sd, idle,
+ &cfs_rq_iterator))
+ return 1;
+ }
+
+ return 0;
+}
+
/*
* scheduler tick hitting a task of our scheduling class:
*/
@@ -1064,6 +1085,7 @@ static const struct sched_class fair_sched_class = {
.put_prev_task = put_prev_task_fair,
.load_balance = load_balance_fair,
+ .move_one_task = move_one_task_fair,
.set_curr_task = set_curr_task_fair,
.task_tick = task_tick_fair,