diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-09-30 11:37:52 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-10-09 03:14:02 -0400 |
commit | fe0f49768d807a8fe6336b097feb8c4441951710 (patch) | |
tree | 5473c103c550bfa72871b4418521f7836a24d6b1 | |
parent | a9b1649917f0d2058022eda06082f9d299a06354 (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.h | 8 | ||||
-rw-r--r-- | arch/s390/include/asm/processor.h | 4 | ||||
-rw-r--r-- | arch/s390/kernel/irq.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/smp.c | 1 | ||||
-rw-r--r-- | arch/s390/kernel/vtime.c | 19 | ||||
-rw-r--r-- | drivers/s390/cio/airq.c | 2 | ||||
-rw-r--r-- | drivers/s390/cio/cio.c | 2 | ||||
-rw-r--r-- | include/linux/tick.h | 2 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 2 |
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 | ||
168 | struct s390_idle_data { | 168 | struct 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 | ||
185 | static 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 *) ®s->int_code; | 260 | ext_code = *(struct ext_code *) ®s->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 | ||
381 | static 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 | |||
397 | void __init vtime_init(void) | 381 | void __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); | |||
108 | extern void tick_irq_enter(void); | 108 | extern void tick_irq_enter(void); |
109 | extern int tick_oneshot_mode_active(void); | 109 | extern 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 |
114 | static inline void tick_clock_notify(void) { } | 114 | static 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 { |