| From 8cc90562209997e79805163f82c9d70eccc216e6 Mon Sep 17 00:00:00 2001 |
| From: Peter Zijlstra <peterz@infradead.org> |
| Date: Fri, 21 Aug 2009 11:56:45 +0200 |
| Subject: [PATCH] timer: delay waking softirqs from the jiffy tick |
| |
| commit 3e46534547eb908c70314c173b22ae17c2e8b8e3 in tip. |
| |
| People were complaining about broken balancing with the recent -rt |
| series. |
| |
| A look at /proc/sched_debug yielded: |
| |
| cpu#0, 2393.874 MHz |
| .nr_running : 0 |
| .load : 0 |
| .cpu_load[0] : 177522 |
| .cpu_load[1] : 177522 |
| .cpu_load[2] : 177522 |
| .cpu_load[3] : 177522 |
| .cpu_load[4] : 177522 |
| cpu#1, 2393.874 MHz |
| .nr_running : 4 |
| .load : 4096 |
| .cpu_load[0] : 181618 |
| .cpu_load[1] : 180850 |
| .cpu_load[2] : 180274 |
| .cpu_load[3] : 179938 |
| .cpu_load[4] : 179758 |
| |
| Which indicated the cpu_load computation was hosed, the 177522 value |
| indicates that there is one RT task runnable. Initially I thought the |
| old problem of calculating the cpu_load from a softirq had re-surfaced, |
| however looking at the code shows its being done from scheduler_tick(). |
| |
| [ we really should fix this RT/cfs interaction some day... ] |
| |
| A few trace_printk()s later: |
| |
| sirq-timer/1-19 [001] 174.289744: 19: 50:S ==> [001] 0:140:R <idle> |
| <idle>-0 [001] 174.290724: enqueue_task_rt: adding task: 19/sirq-timer/1 with load: 177522 |
| <idle>-0 [001] 174.290725: 0:140:R + [001] 19: 50:S sirq-timer/1 |
| <idle>-0 [001] 174.290730: scheduler_tick: current load: 177522 |
| <idle>-0 [001] 174.290732: scheduler_tick: current: 0/swapper |
| <idle>-0 [001] 174.290736: 0:140:R ==> [001] 19: 50:R sirq-timer/1 |
| sirq-timer/1-19 [001] 174.290741: dequeue_task_rt: removing task: 19/sirq-timer/1 with load: 177522 |
| sirq-timer/1-19 [001] 174.290743: 19: 50:S ==> [001] 0:140:R <idle> |
| |
| We see that we always raise the timer softirq before doing the load |
| calculation. Avoid this by re-ordering the scheduler_tick() call in |
| update_process_times() to occur before we deal with timers. |
| |
| This lowers the load back to sanity and restores regular load-balancing |
| behaviour. |
| |
| Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/kernel/timer.c b/kernel/timer.c |
| index 8f29bd0..f4978ac 100644 |
| --- a/kernel/timer.c |
| +++ b/kernel/timer.c |
| @@ -1262,10 +1262,10 @@ void update_process_times(int user_tick) |
| |
| /* Note: this timer irq context must be accounted for as well. */ |
| account_process_tick(p, user_tick); |
| + scheduler_tick(); |
| run_local_timers(); |
| rcu_check_callbacks(cpu, user_tick); |
| perf_event_do_pending(); |
| - scheduler_tick(); |
| run_posix_cpu_timers(p); |
| } |
| |
| -- |
| 1.7.1.1 |
| |