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>
This commit is contained in:
@@ -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);
|
|||||||
|
|
||||||
#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 @@
|
|||||||
|
|
||||||
#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)
|
|||||||
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)
|
|||||||
|
|
||||||
ext_code = *(struct ext_code *) ®s->int_code;
|
ext_code = *(struct ext_code *) ®s->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)
|
|||||||
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)
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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);
|
|||||||
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,
|
|||||||
} 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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user