aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Galbraith <efault@gmx.de>2009-11-04 11:53:50 -0500
committerIngo Molnar <mingo@elte.hu>2009-11-04 13:13:48 -0500
commit1b9508f6831e10d53256825de8904caa22d1ca2c (patch)
tree1b9f62947a75432000cfe46b22071d2b09e5899a
parenta1f84a3ab8e002159498814eaa7e48c33752b04b (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>
-rw-r--r--kernel/sched.c22
-rw-r--r--kernel/sched_debug.c4
2 files changed, 25 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 /*
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c
index efb84409bc43..6988cf08f705 100644
--- a/kernel/sched_debug.c
+++ b/kernel/sched_debug.c
@@ -285,12 +285,16 @@ static void print_cpu(struct seq_file *m, int cpu)
285 285
286#ifdef CONFIG_SCHEDSTATS 286#ifdef CONFIG_SCHEDSTATS
287#define P(n) SEQ_printf(m, " .%-30s: %d\n", #n, rq->n); 287#define P(n) SEQ_printf(m, " .%-30s: %d\n", #n, rq->n);
288#define P64(n) SEQ_printf(m, " .%-30s: %Ld\n", #n, rq->n);
288 289
289 P(yld_count); 290 P(yld_count);
290 291
291 P(sched_switch); 292 P(sched_switch);
292 P(sched_count); 293 P(sched_count);
293 P(sched_goidle); 294 P(sched_goidle);
295#ifdef CONFIG_SMP
296 P64(avg_idle);
297#endif
294 298
295 P(ttwu_count); 299 P(ttwu_count);
296 P(ttwu_local); 300 P(ttwu_local);