]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.32.19/nohz-introduce-arch_needs_cpu.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 2.6.32.19 / nohz-introduce-arch_needs_cpu.patch
CommitLineData
8de80845
GKH
1From 3c5d92a0cfb5103c0d5ab74d4ae6373d3af38148 Mon Sep 17 00:00:00 2001
2From: Martin Schwidefsky <schwidefsky@de.ibm.com>
3Date: Tue, 29 Sep 2009 14:25:16 +0200
4Subject: nohz: Introduce arch_needs_cpu
5
6From: Martin Schwidefsky <schwidefsky@de.ibm.com>
7
8commit 3c5d92a0cfb5103c0d5ab74d4ae6373d3af38148 upstream.
9
10Allow the architecture to request a normal jiffy tick when the system
11goes idle and tick_nohz_stop_sched_tick is called . On s390 the hook is
12used to prevent the system going fully idle if there has been an
13interrupt other than a clock comparator interrupt since the last wakeup.
14
15On s390 the HiperSockets response time for 1 connection ping-pong goes
16down from 42 to 34 microseconds. The CPU cost decreases by 27%.
17
18Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
19LKML-Reference: <20090929122533.402715150@de.ibm.com>
20Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
21Acked-by: John Jolly <jjolly@suse.de>
22Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
23
24---
25 arch/s390/include/asm/cputime.h | 8 ++++++++
26 arch/s390/kernel/s390_ext.c | 2 ++
27 arch/s390/kernel/vtime.c | 2 ++
28 drivers/s390/cio/cio.c | 1 +
29 include/linux/tick.h | 3 +++
30 kernel/time/tick-sched.c | 13 ++++++++-----
31 6 files changed, 24 insertions(+), 5 deletions(-)
32
33--- a/arch/s390/include/asm/cputime.h
34+++ b/arch/s390/include/asm/cputime.h
35@@ -183,6 +183,7 @@ struct s390_idle_data {
36 unsigned long long idle_count;
37 unsigned long long idle_enter;
38 unsigned long long idle_time;
39+ int nohz_delay;
40 };
41
42 DECLARE_PER_CPU(struct s390_idle_data, s390_idle);
43@@ -198,4 +199,11 @@ static inline void s390_idle_check(void)
44 vtime_start_cpu();
45 }
46
47+static inline int s390_nohz_delay(int cpu)
48+{
49+ return per_cpu(s390_idle, cpu).nohz_delay != 0;
50+}
51+
52+#define arch_needs_cpu(cpu) s390_nohz_delay(cpu)
53+
54 #endif /* _S390_CPUTIME_H */
55--- a/arch/s390/kernel/s390_ext.c
56+++ b/arch/s390/kernel/s390_ext.c
57@@ -126,6 +126,8 @@ void __irq_entry do_extint(struct pt_reg
58 /* Serve timer interrupts first. */
59 clock_comparator_work();
60 kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
61+ if (code != 0x1004)
62+ __get_cpu_var(s390_idle).nohz_delay = 1;
63 index = ext_hash(code);
64 for (p = ext_int_hash[index]; p; p = p->next) {
65 if (likely(p->code == code))
66--- a/arch/s390/kernel/vtime.c
67+++ b/arch/s390/kernel/vtime.c
68@@ -167,6 +167,8 @@ void vtime_stop_cpu(void)
69 /* Wait for external, I/O or machine check interrupt. */
70 psw.mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_IO | PSW_MASK_EXT;
71
72+ idle->nohz_delay = 0;
73+
74 /* Check if the CPU timer needs to be reprogrammed. */
75 if (vq->do_spt) {
76 __u64 vmax = VTIMER_MAX_SLICE;
77--- a/drivers/s390/cio/cio.c
78+++ b/drivers/s390/cio/cio.c
79@@ -618,6 +618,7 @@ void __irq_entry do_IRQ(struct pt_regs *
80 old_regs = set_irq_regs(regs);
81 s390_idle_check();
82 irq_enter();
83+ __get_cpu_var(s390_idle).nohz_delay = 1;
84 if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
85 /* Serve timer interrupts first. */
86 clock_comparator_work();
87--- a/include/linux/tick.h
88+++ b/include/linux/tick.h
89@@ -98,6 +98,9 @@ extern int tick_check_oneshot_change(int
90 extern struct tick_sched *tick_get_tick_sched(int cpu);
91 extern void tick_check_idle(int cpu);
92 extern int tick_oneshot_mode_active(void);
93+# ifndef arch_needs_cpu
94+# define arch_needs_cpu(cpu) (0)
95+# endif
96 # else
97 static inline void tick_clock_notify(void) { }
98 static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
99--- a/kernel/time/tick-sched.c
100+++ b/kernel/time/tick-sched.c
101@@ -289,12 +289,15 @@ void tick_nohz_stop_sched_tick(int inidl
102 time_delta = KTIME_MAX;
103 } while (read_seqretry(&xtime_lock, seq));
104
105- /* Get the next timer wheel timer */
106- next_jiffies = get_next_timer_interrupt(last_jiffies);
107- delta_jiffies = next_jiffies - last_jiffies;
108-
109- if (rcu_needs_cpu(cpu) || printk_needs_cpu(cpu))
110+ if (rcu_needs_cpu(cpu) || printk_needs_cpu(cpu) ||
111+ arch_needs_cpu(cpu)) {
112+ next_jiffies = last_jiffies + 1;
113 delta_jiffies = 1;
114+ } else {
115+ /* Get the next timer wheel timer */
116+ next_jiffies = get_next_timer_interrupt(last_jiffies);
117+ delta_jiffies = next_jiffies - last_jiffies;
118+ }
119 /*
120 * Do not stop the tick, if we are only one off
121 * or if the cpu is required for rcu