Commit fe0f4976 authored by Martin Schwidefsky's avatar Martin Schwidefsky

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: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent a9b16499
...@@ -166,7 +166,6 @@ static inline clock_t cputime64_to_clock_t(cputime64_t cputime) ...@@ -166,7 +166,6 @@ static inline clock_t cputime64_to_clock_t(cputime64_t cputime)
} }
struct s390_idle_data { struct s390_idle_data {
int nohz_delay;
unsigned int sequence; unsigned int sequence;
unsigned long long idle_count; unsigned long long idle_count;
unsigned long long idle_time; unsigned long long idle_time;
...@@ -182,11 +181,4 @@ cputime64_t s390_get_idle_time(int cpu); ...@@ -182,11 +181,4 @@ cputime64_t s390_get_idle_time(int cpu);
#define arch_idle_time(cpu) s390_get_idle_time(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 */ #endif /* _S390_CPUTIME_H */
...@@ -13,9 +13,11 @@ ...@@ -13,9 +13,11 @@
#define CIF_MCCK_PENDING 0 /* machine check handling is pending */ #define CIF_MCCK_PENDING 0 /* machine check handling is pending */
#define CIF_ASCE 1 /* user asce needs fixup / uaccess */ #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_MCCK_PENDING (1<<CIF_MCCK_PENDING)
#define _CIF_ASCE (1<<CIF_ASCE) #define _CIF_ASCE (1<<CIF_ASCE)
#define _CIF_NOHZ_DELAY (1<<CIF_NOHZ_DELAY)
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
...@@ -43,6 +45,8 @@ static inline int test_cpu_flag(int flag) ...@@ -43,6 +45,8 @@ static inline int test_cpu_flag(int flag)
return !!(S390_lowcore.cpu_flags & (1U << 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 * Default implementation of macro that returns current
* instruction pointer ("program counter"). * instruction pointer ("program counter").
......
...@@ -259,7 +259,7 @@ static irqreturn_t do_ext_interrupt(int irq, void *dummy) ...@@ -259,7 +259,7 @@ static irqreturn_t do_ext_interrupt(int irq, void *dummy)
ext_code = *(struct ext_code *) &regs->int_code; ext_code = *(struct ext_code *) &regs->int_code;
if (ext_code.code != EXT_IRQ_CLK_COMP) 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); index = ext_hash(ext_code.code);
rcu_read_lock(); rcu_read_lock();
......
...@@ -720,6 +720,7 @@ int __cpu_disable(void) ...@@ -720,6 +720,7 @@ int __cpu_disable(void)
cregs[6] &= ~0xff000000UL; /* disable all I/O interrupts */ cregs[6] &= ~0xff000000UL; /* disable all I/O interrupts */
cregs[14] &= ~0x1f000000UL; /* disable most machine checks */ cregs[14] &= ~0x1f000000UL; /* disable most machine checks */
__ctl_load(cregs, 0, 15); __ctl_load(cregs, 0, 15);
clear_cpu_flag(CIF_NOHZ_DELAY);
return 0; return 0;
} }
......
...@@ -163,7 +163,7 @@ void __kprobes vtime_stop_cpu(void) ...@@ -163,7 +163,7 @@ void __kprobes vtime_stop_cpu(void)
/* Wait for external, I/O or machine check interrupt. */ /* Wait for external, I/O or machine check interrupt. */
psw_mask = PSW_KERNEL_BITS | PSW_MASK_WAIT | PSW_MASK_DAT | psw_mask = PSW_KERNEL_BITS | PSW_MASK_WAIT | PSW_MASK_DAT |
PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; 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 */ /* Call the assembler magic in entry.S */
psw_idle(idle, psw_mask); psw_idle(idle, psw_mask);
...@@ -378,25 +378,8 @@ void init_cpu_vtimer(void) ...@@ -378,25 +378,8 @@ void init_cpu_vtimer(void)
set_vtimer(VTIMER_MAX_SLICE); 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) void __init vtime_init(void)
{ {
/* Enable cpu timer interrupts on the boot cpu. */ /* Enable cpu timer interrupts on the boot cpu. */
init_cpu_vtimer(); init_cpu_vtimer();
cpu_notifier(s390_nohz_notify, 0);
} }
...@@ -87,7 +87,7 @@ static irqreturn_t do_airq_interrupt(int irq, void *dummy) ...@@ -87,7 +87,7 @@ static irqreturn_t do_airq_interrupt(int irq, void *dummy)
struct airq_struct *airq; struct airq_struct *airq;
struct hlist_head *head; 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; tpi_info = (struct tpi_info *) &get_irq_regs()->int_code;
head = &airq_lists[tpi_info->isc]; head = &airq_lists[tpi_info->isc];
rcu_read_lock(); rcu_read_lock();
......
...@@ -561,7 +561,7 @@ static irqreturn_t do_cio_interrupt(int irq, void *dummy) ...@@ -561,7 +561,7 @@ static irqreturn_t do_cio_interrupt(int irq, void *dummy)
struct subchannel *sch; struct subchannel *sch;
struct irb *irb; 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; tpi_info = (struct tpi_info *) &get_irq_regs()->int_code;
irb = &__get_cpu_var(cio_irb); irb = &__get_cpu_var(cio_irb);
sch = (struct subchannel *)(unsigned long) tpi_info->intparm; sch = (struct subchannel *)(unsigned long) tpi_info->intparm;
......
...@@ -108,7 +108,7 @@ extern struct tick_sched *tick_get_tick_sched(int cpu); ...@@ -108,7 +108,7 @@ extern struct tick_sched *tick_get_tick_sched(int cpu);
extern void tick_irq_enter(void); extern void tick_irq_enter(void);
extern int tick_oneshot_mode_active(void); extern int tick_oneshot_mode_active(void);
# ifndef arch_needs_cpu # ifndef arch_needs_cpu
# define arch_needs_cpu(cpu) (0) # define arch_needs_cpu() (0)
# endif # endif
# else # else
static inline void tick_clock_notify(void) { } static inline void tick_clock_notify(void) { }
......
...@@ -572,7 +572,7 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts, ...@@ -572,7 +572,7 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts,
} while (read_seqretry(&jiffies_lock, seq)); } while (read_seqretry(&jiffies_lock, seq));
if (rcu_needs_cpu(cpu, &rcu_delta_jiffies) || 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; next_jiffies = last_jiffies + 1;
delta_jiffies = 1; delta_jiffies = 1;
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment