aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2014-09-30 11:37:52 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2014-10-09 03:14:02 -0400
commitfe0f49768d807a8fe6336b097feb8c4441951710 (patch)
tree5473c103c550bfa72871b4418521f7836a24d6b1
parenta9b1649917f0d2058022eda06082f9d299a06354 (diff)
s390/nohz: use a per-cpu flag for arch_needs_cpu
Move the nohz_delay bit from the s390_idle data structure to the per-cpu flags. Clear the nohz delay flag in __cpu_disable and remove the cpu hotplug notifier that used to do this. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/include/asm/cputime.h8
-rw-r--r--arch/s390/include/asm/processor.h4
-rw-r--r--arch/s390/kernel/irq.c2
-rw-r--r--arch/s390/kernel/smp.c1
-rw-r--r--arch/s390/kernel/vtime.c19
-rw-r--r--drivers/s390/cio/airq.c2
-rw-r--r--drivers/s390/cio/cio.c2
-rw-r--r--include/linux/tick.h2
-rw-r--r--kernel/time/tick-sched.c2
9 files changed, 11 insertions, 31 deletions
diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h
index f65bd3634519..01887b1fade5 100644
--- a/arch/s390/include/asm/cputime.h
+++ b/arch/s390/include/asm/cputime.h
@@ -166,7 +166,6 @@ static inline clock_t cputime64_to_clock_t(cputime64_t cputime)
166} 166}
167 167
168struct s390_idle_data { 168struct s390_idle_data {
169 int nohz_delay;
170 unsigned int sequence; 169 unsigned int sequence;
171 unsigned long long idle_count; 170 unsigned long long idle_count;
172 unsigned long long idle_time; 171 unsigned long long idle_time;
@@ -182,11 +181,4 @@ cputime64_t s390_get_idle_time(int cpu);
182 181
183#define arch_idle_time(cpu) s390_get_idle_time(cpu) 182#define arch_idle_time(cpu) s390_get_idle_time(cpu)
184 183
185static inline int s390_nohz_delay(int cpu)
186{
187 return __get_cpu_var(s390_idle).nohz_delay != 0;
188}
189
190#define arch_needs_cpu(cpu) s390_nohz_delay(cpu)
191
192#endif /* _S390_CPUTIME_H */ 184#endif /* _S390_CPUTIME_H */
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index e568fc8a7250..bc796d73129b 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -13,9 +13,11 @@
13 13
14#define CIF_MCCK_PENDING 0 /* machine check handling is pending */ 14#define CIF_MCCK_PENDING 0 /* machine check handling is pending */
15#define CIF_ASCE 1 /* user asce needs fixup / uaccess */ 15#define CIF_ASCE 1 /* user asce needs fixup / uaccess */
16#define CIF_NOHZ_DELAY 2 /* delay HZ disable for a tick */
16 17
17#define _CIF_MCCK_PENDING (1<<CIF_MCCK_PENDING) 18#define _CIF_MCCK_PENDING (1<<CIF_MCCK_PENDING)
18#define _CIF_ASCE (1<<CIF_ASCE) 19#define _CIF_ASCE (1<<CIF_ASCE)
20#define _CIF_NOHZ_DELAY (1<<CIF_NOHZ_DELAY)
19 21
20 22
21#ifndef __ASSEMBLY__ 23#ifndef __ASSEMBLY__
@@ -43,6 +45,8 @@ static inline int test_cpu_flag(int flag)
43 return !!(S390_lowcore.cpu_flags & (1U << flag)); 45 return !!(S390_lowcore.cpu_flags & (1U << flag));
44} 46}
45 47
48#define arch_needs_cpu() test_cpu_flag(CIF_NOHZ_DELAY)
49
46/* 50/*
47 * Default implementation of macro that returns current 51 * Default implementation of macro that returns current
48 * instruction pointer ("program counter"). 52 * instruction pointer ("program counter").
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index 051574ee5366..1b8a38ab7861 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -259,7 +259,7 @@ static irqreturn_t do_ext_interrupt(int irq, void *dummy)
259 259
260 ext_code = *(struct ext_code *) &regs->int_code; 260 ext_code = *(struct ext_code *) &regs->int_code;
261 if (ext_code.code != EXT_IRQ_CLK_COMP) 261 if (ext_code.code != EXT_IRQ_CLK_COMP)
262 __get_cpu_var(s390_idle).nohz_delay = 1; 262 set_cpu_flag(CIF_NOHZ_DELAY);
263 263
264 index = ext_hash(ext_code.code); 264 index = ext_hash(ext_code.code);
265 rcu_read_lock(); 265 rcu_read_lock();
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index abec97b4ddbf..46317d6951c4 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -720,6 +720,7 @@ int __cpu_disable(void)
720 cregs[6] &= ~0xff000000UL; /* disable all I/O interrupts */ 720 cregs[6] &= ~0xff000000UL; /* disable all I/O interrupts */
721 cregs[14] &= ~0x1f000000UL; /* disable most machine checks */ 721 cregs[14] &= ~0x1f000000UL; /* disable most machine checks */
722 __ctl_load(cregs, 0, 15); 722 __ctl_load(cregs, 0, 15);
723 clear_cpu_flag(CIF_NOHZ_DELAY);
723 return 0; 724 return 0;
724} 725}
725 726
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 8c34363d6f1e..40709821abde 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -163,7 +163,7 @@ void __kprobes vtime_stop_cpu(void)
163 /* Wait for external, I/O or machine check interrupt. */ 163 /* Wait for external, I/O or machine check interrupt. */
164 psw_mask = PSW_KERNEL_BITS | PSW_MASK_WAIT | PSW_MASK_DAT | 164 psw_mask = PSW_KERNEL_BITS | PSW_MASK_WAIT | PSW_MASK_DAT |
165 PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; 165 PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
166 idle->nohz_delay = 0; 166 clear_cpu_flag(CIF_NOHZ_DELAY);
167 167
168 /* Call the assembler magic in entry.S */ 168 /* Call the assembler magic in entry.S */
169 psw_idle(idle, psw_mask); 169 psw_idle(idle, psw_mask);
@@ -378,25 +378,8 @@ void init_cpu_vtimer(void)
378 set_vtimer(VTIMER_MAX_SLICE); 378 set_vtimer(VTIMER_MAX_SLICE);
379} 379}
380 380
381static int s390_nohz_notify(struct notifier_block *self, unsigned long action,
382 void *hcpu)
383{
384 struct s390_idle_data *idle;
385 long cpu = (long) hcpu;
386
387 idle = &per_cpu(s390_idle, cpu);
388 switch (action & ~CPU_TASKS_FROZEN) {
389 case CPU_DYING:
390 idle->nohz_delay = 0;
391 default:
392 break;
393 }
394 return NOTIFY_OK;
395}
396
397void __init vtime_init(void) 381void __init vtime_init(void)
398{ 382{
399 /* Enable cpu timer interrupts on the boot cpu. */ 383 /* Enable cpu timer interrupts on the boot cpu. */
400 init_cpu_vtimer(); 384 init_cpu_vtimer();
401 cpu_notifier(s390_nohz_notify, 0);
402} 385}
diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c
index 00bfbee0af9e..56eb4ee4deba 100644
--- a/drivers/s390/cio/airq.c
+++ b/drivers/s390/cio/airq.c
@@ -87,7 +87,7 @@ static irqreturn_t do_airq_interrupt(int irq, void *dummy)
87 struct airq_struct *airq; 87 struct airq_struct *airq;
88 struct hlist_head *head; 88 struct hlist_head *head;
89 89
90 __this_cpu_write(s390_idle.nohz_delay, 1); 90 set_cpu_flag(CIF_NOHZ_DELAY);
91 tpi_info = (struct tpi_info *) &get_irq_regs()->int_code; 91 tpi_info = (struct tpi_info *) &get_irq_regs()->int_code;
92 head = &airq_lists[tpi_info->isc]; 92 head = &airq_lists[tpi_info->isc];
93 rcu_read_lock(); 93 rcu_read_lock();
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 2905d8b0ec95..d5a6f287d2fe 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -561,7 +561,7 @@ static irqreturn_t do_cio_interrupt(int irq, void *dummy)
561 struct subchannel *sch; 561 struct subchannel *sch;
562 struct irb *irb; 562 struct irb *irb;
563 563
564 __this_cpu_write(s390_idle.nohz_delay, 1); 564 set_cpu_flag(CIF_NOHZ_DELAY);
565 tpi_info = (struct tpi_info *) &get_irq_regs()->int_code; 565 tpi_info = (struct tpi_info *) &get_irq_regs()->int_code;
566 irb = &__get_cpu_var(cio_irb); 566 irb = &__get_cpu_var(cio_irb);
567 sch = (struct subchannel *)(unsigned long) tpi_info->intparm; 567 sch = (struct subchannel *)(unsigned long) tpi_info->intparm;
diff --git a/include/linux/tick.h b/include/linux/tick.h
index 9a82c7dc3fdd..e5832d03da19 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -108,7 +108,7 @@ extern struct tick_sched *tick_get_tick_sched(int cpu);
108extern void tick_irq_enter(void); 108extern void tick_irq_enter(void);
109extern int tick_oneshot_mode_active(void); 109extern int tick_oneshot_mode_active(void);
110# ifndef arch_needs_cpu 110# ifndef arch_needs_cpu
111# define arch_needs_cpu(cpu) (0) 111# define arch_needs_cpu() (0)
112# endif 112# endif
113# else 113# else
114static inline void tick_clock_notify(void) { } 114static inline void tick_clock_notify(void) { }
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index f654a8a298fa..01d512fd45f1 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -572,7 +572,7 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts,
572 } while (read_seqretry(&jiffies_lock, seq)); 572 } while (read_seqretry(&jiffies_lock, seq));
573 573
574 if (rcu_needs_cpu(cpu, &rcu_delta_jiffies) || 574 if (rcu_needs_cpu(cpu, &rcu_delta_jiffies) ||
575 arch_needs_cpu(cpu) || irq_work_needs_cpu()) { 575 arch_needs_cpu() || irq_work_needs_cpu()) {
576 next_jiffies = last_jiffies + 1; 576 next_jiffies = last_jiffies + 1;
577 delta_jiffies = 1; 577 delta_jiffies = 1;
578 } else { 578 } else {