81 lines
3.0 KiB
Diff
81 lines
3.0 KiB
Diff
|
From a9235b7a3e0b3d7ca3874f88940b056df7d4088a Mon Sep 17 00:00:00 2001
|
||
|
From: Peter Zijlstra <peterz@infradead.org>
|
||
|
Date: Fri, 21 Aug 2009 11:56:45 +0200
|
||
|
Subject: [PATCH 119/365] timer: delay waking softirqs from the jiffy tick
|
||
|
|
||
|
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>
|
||
|
---
|
||
|
kernel/time/timer.c | 2 +-
|
||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
|
||
|
index 1a7b5f87a006..4686736fc986 100644
|
||
|
--- a/kernel/time/timer.c
|
||
|
+++ b/kernel/time/timer.c
|
||
|
@@ -1661,13 +1661,13 @@ 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(user_tick);
|
||
|
#ifdef CONFIG_IRQ_WORK
|
||
|
if (in_irq())
|
||
|
irq_work_tick();
|
||
|
#endif
|
||
|
- scheduler_tick();
|
||
|
run_posix_cpu_timers(p);
|
||
|
}
|
||
|
|
||
|
--
|
||
|
2.28.0
|
||
|
|