diff options
-rw-r--r-- | kernel/sched.c | 22 | ||||
-rw-r--r-- | kernel/sched_debug.c | 4 |
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); |