s390/nohz: use a per-cpu flag for arch_needs_cpu
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 30 Sep 2014 15:37:52 +0000 (17:37 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Thu, 9 Oct 2014 07:14:02 +0000 (09:14 +0200)
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>
arch/s390/include/asm/cputime.h
arch/s390/include/asm/processor.h
arch/s390/kernel/irq.c
arch/s390/kernel/smp.c
arch/s390/kernel/vtime.c
drivers/s390/cio/airq.c
drivers/s390/cio/cio.c
include/linux/tick.h
kernel/time/tick-sched.c

index f65bd36345194db88b71bca1f3740cca8744fa33..01887b1fade593d8d0627b620872e6f23edbee62 100644 (file)
@@ -166,7 +166,6 @@ static inline clock_t cputime64_to_clock_t(cputime64_t cputime)
 }
 
 struct s390_idle_data {
-       int nohz_delay;
        unsigned int sequence;
        unsigned long long idle_count;
        unsigned long long idle_time;
@@ -182,11 +181,4 @@ cputime64_t s390_get_idle_time(int cpu);
 
 #define arch_idle_time(cpu) s390_get_idle_time(cpu)
 
-static inline int s390_nohz_delay(int cpu)
-{
-       return __get_cpu_var(s390_idle).nohz_delay != 0;
-}
-
-#define arch_needs_cpu(cpu) s390_nohz_delay(cpu)
-
 #endif /* _S390_CPUTIME_H */
index e568fc8a725062f707b7875c7c4010a21bd0fcfa..bc796d73129bf1668cf1f0dda8a44a19b486fe2d 100644 (file)
 
 #define CIF_MCCK_PENDING       0       /* machine check handling is pending */
 #define CIF_ASCE               1       /* user asce needs fixup / uaccess */
+#define CIF_NOHZ_DELAY         2       /* delay HZ disable for a tick */
 
 #define _CIF_MCCK_PENDING      (1<<CIF_MCCK_PENDING)
 #define _CIF_ASCE              (1<<CIF_ASCE)
+#define _CIF_NOHZ_DELAY                (1<<CIF_NOHZ_DELAY)
 
 
 #ifndef __ASSEMBLY__
@@ -43,6 +45,8 @@ static inline int test_cpu_flag(int flag)
        return !!(S390_lowcore.cpu_flags & (1U << flag));
 }
 
+#define arch_needs_cpu() test_cpu_flag(CIF_NOHZ_DELAY)
+
 /*
  * Default implementation of macro that returns current
  * instruction pointer ("program counter").
index 051574ee53661001cafee5c7db38ab95c939af5a..1b8a38ab7861c685af7d9b1b7f593a9733135909 100644 (file)
@@ -259,7 +259,7 @@ static irqreturn_t do_ext_interrupt(int irq, void *dummy)
 
        ext_code = *(struct ext_code *) &regs->int_code;
        if (ext_code.code != EXT_IRQ_CLK_COMP)
-               __get_cpu_var(s390_idle).nohz_delay = 1;
+               set_cpu_flag(CIF_NOHZ_DELAY);
 
        index = ext_hash(ext_code.code);
        rcu_read_lock();
index abec97b4ddbf403b054136f5274dc47d604ee6c3..46317d6951c4f10c5db30c1d7c6f8386da4481a6 100644 (file)
@@ -720,6 +720,7 @@ int __cpu_disable(void)
        cregs[6]  &= ~0xff000000UL;     /* disable all I/O interrupts */
        cregs[14] &= ~0x1f000000UL;     /* disable most machine checks */
        __ctl_load(cregs, 0, 15);
+       clear_cpu_flag(CIF_NOHZ_DELAY);
        return 0;
 }
 
index 8c34363d6f1e88571074b01593b1efaa80c007d0..40709821abde61b614370d83158087e4c82de48e 100644 (file)
@@ -163,7 +163,7 @@ void __kprobes vtime_stop_cpu(void)
        /* Wait for external, I/O or machine check interrupt. */
        psw_mask = PSW_KERNEL_BITS | PSW_MASK_WAIT | PSW_MASK_DAT |
                PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
-       idle->nohz_delay = 0;
+       clear_cpu_flag(CIF_NOHZ_DELAY);
 
        /* Call the assembler magic in entry.S */
        psw_idle(idle, psw_mask);
@@ -378,25 +378,8 @@ void init_cpu_vtimer(void)
        set_vtimer(VTIMER_MAX_SLICE);
 }
 
-static int s390_nohz_notify(struct notifier_block *self, unsigned long action,
-                           void *hcpu)
-{
-       struct s390_idle_data *idle;
-       long cpu = (long) hcpu;
-
-       idle = &per_cpu(s390_idle, cpu);
-       switch (action & ~CPU_TASKS_FROZEN) {
-       case CPU_DYING:
-               idle->nohz_delay = 0;
-       default:
-               break;
-       }
-       return NOTIFY_OK;
-}
-
 void __init vtime_init(void)
 {
        /* Enable cpu timer interrupts on the boot cpu. */
        init_cpu_vtimer();
-       cpu_notifier(s390_nohz_notify, 0);
 }
index 00bfbee0af9e0ebf54defb9759801337ec3dc8e7..56eb4ee4deba05e4a5d1bd59d50ab6408d219000 100644 (file)
@@ -87,7 +87,7 @@ static irqreturn_t do_airq_interrupt(int irq, void *dummy)
        struct airq_struct *airq;
        struct hlist_head *head;
 
-       __this_cpu_write(s390_idle.nohz_delay, 1);
+       set_cpu_flag(CIF_NOHZ_DELAY);
        tpi_info = (struct tpi_info *) &get_irq_regs()->int_code;
        head = &airq_lists[tpi_info->isc];
        rcu_read_lock();
index 2905d8b0ec95b7db0e14b7e2e129af202b5c12ab..d5a6f287d2fed8ef18c3702c0ec1ab1684cbe79f 100644 (file)
@@ -561,7 +561,7 @@ static irqreturn_t do_cio_interrupt(int irq, void *dummy)
        struct subchannel *sch;
        struct irb *irb;
 
-       __this_cpu_write(s390_idle.nohz_delay, 1);
+       set_cpu_flag(CIF_NOHZ_DELAY);
        tpi_info = (struct tpi_info *) &get_irq_regs()->int_code;
        irb = &__get_cpu_var(cio_irb);
        sch = (struct subchannel *)(unsigned long) tpi_info->intparm;
index 9a82c7dc3fdd9f1fd35d62fb2ab0734516c9ad6c..e5832d03da19dacabb8faa035ca8316ac989db6e 100644 (file)
@@ -108,7 +108,7 @@ extern struct tick_sched *tick_get_tick_sched(int cpu);
 extern void tick_irq_enter(void);
 extern int tick_oneshot_mode_active(void);
 #  ifndef arch_needs_cpu
-#   define arch_needs_cpu(cpu) (0)
+#   define arch_needs_cpu() (0)
 #  endif
 # else
 static inline void tick_clock_notify(void) { }
index f654a8a298fad5cac36465bdcb23fddeb854f2ef..01d512fd45f1b2777585b645060995f52c54bfb7 100644 (file)
@@ -572,7 +572,7 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts,
        } while (read_seqretry(&jiffies_lock, seq));
 
        if (rcu_needs_cpu(cpu, &rcu_delta_jiffies) ||
-           arch_needs_cpu(cpu) || irq_work_needs_cpu()) {
+           arch_needs_cpu() || irq_work_needs_cpu()) {
                next_jiffies = last_jiffies + 1;
                delta_jiffies = 1;
        } else {