diff options
author | Mike Galbraith <efault@gmx.de> | 2009-11-04 11:53:50 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-11-04 13:13:48 -0500 |
commit | 1b9508f6831e10d53256825de8904caa22d1ca2c (patch) | |
tree | 1b9f62947a75432000cfe46b22071d2b09e5899a /kernel/sched.c | |
parent | a1f84a3ab8e002159498814eaa7e48c33752b04b (diff) |
sched: Rate-limit newidle
Rate limit newidle to migration_cost. It's a win for all
stages of sysbench oltp tests.
Signed-off-by: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index ae026aad145b..f8492123b5d1 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -589,6 +589,8 @@ struct rq { | |||
589 | 589 | ||
590 | u64 rt_avg; | 590 | u64 rt_avg; |
591 | u64 age_stamp; | 591 | u64 age_stamp; |
592 | u64 idle_stamp; | ||
593 | u64 avg_idle; | ||
592 | #endif | 594 | #endif |
593 | 595 | ||
594 | /* calc_load related fields */ | 596 | /* calc_load related fields */ |
@@ -2353,6 +2355,17 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, | |||
2353 | if (rq != orig_rq) | 2355 | if (rq != orig_rq) |
2354 | update_rq_clock(rq); | 2356 | update_rq_clock(rq); |
2355 | 2357 | ||
2358 | if (rq->idle_stamp) { | ||
2359 | u64 delta = rq->clock - rq->idle_stamp; | ||
2360 | u64 max = 2*sysctl_sched_migration_cost; | ||
2361 | |||
2362 | if (delta > max) | ||
2363 | rq->avg_idle = max; | ||
2364 | else | ||
2365 | update_avg(&rq->avg_idle, delta); | ||
2366 | rq->idle_stamp = 0; | ||
2367 | } | ||
2368 | |||
2356 | WARN_ON(p->state != TASK_WAKING); | 2369 | WARN_ON(p->state != TASK_WAKING); |
2357 | cpu = task_cpu(p); | 2370 | cpu = task_cpu(p); |
2358 | 2371 | ||
@@ -4389,6 +4402,11 @@ static void idle_balance(int this_cpu, struct rq *this_rq) | |||
4389 | int pulled_task = 0; | 4402 | int pulled_task = 0; |
4390 | unsigned long next_balance = jiffies + HZ; | 4403 | unsigned long next_balance = jiffies + HZ; |
4391 | 4404 | ||
4405 | this_rq->idle_stamp = this_rq->clock; | ||
4406 | |||
4407 | if (this_rq->avg_idle < sysctl_sched_migration_cost) | ||
4408 | return; | ||
4409 | |||
4392 | for_each_domain(this_cpu, sd) { | 4410 | for_each_domain(this_cpu, sd) { |
4393 | unsigned long interval; | 4411 | unsigned long interval; |
4394 | 4412 | ||
@@ -4403,8 +4421,10 @@ static void idle_balance(int this_cpu, struct rq *this_rq) | |||
4403 | interval = msecs_to_jiffies(sd->balance_interval); | 4421 | interval = msecs_to_jiffies(sd->balance_interval); |
4404 | if (time_after(next_balance, sd->last_balance + interval)) | 4422 | if (time_after(next_balance, sd->last_balance + interval)) |
4405 | next_balance = sd->last_balance + interval; | 4423 | next_balance = sd->last_balance + interval; |
4406 | if (pulled_task) | 4424 | if (pulled_task) { |
4425 | this_rq->idle_stamp = 0; | ||
4407 | break; | 4426 | break; |
4427 | } | ||
4408 | } | 4428 | } |
4409 | if (pulled_task || time_after(jiffies, this_rq->next_balance)) { | 4429 | if (pulled_task || time_after(jiffies, this_rq->next_balance)) { |
4410 | /* | 4430 | /* |