Skip to content

Commit

Permalink
Merge branch 'timers-nohz-for-linus' of git://git.kernel.org/pub/scm/…
Browse files Browse the repository at this point in the history
…linux/kernel/git/tip/tip

Pull timer fixes from Ingo Molnar:
 "Main changes:

  - Fix the deadlock reported by Dave Jones et al
  - Clean up and fix nohz_full interaction with arch abilities
  - nohz init code consolidation/cleanup"

* 'timers-nohz-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  nohz: nohz full depends on irq work self IPI support
  nohz: Consolidate nohz full init code
  arm64: Tell irq work about self IPI support
  arm: Tell irq work about self IPI support
  x86: Tell irq work about self IPI support
  irq_work: Force raised irq work to run on irq work interrupt
  irq_work: Introduce arch_irq_work_has_interrupt()
  nohz: Move nohz full init call to tick init
  • Loading branch information
torvalds committed Oct 9, 2014
2 parents 35a9ad8 + 9b01f5b commit afa3536
Show file tree
Hide file tree
Showing 43 changed files with 133 additions and 29 deletions.
1 change: 1 addition & 0 deletions arch/alpha/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ generic-y += clkdev.h
generic-y += cputime.h
generic-y += exec.h
generic-y += hash.h
generic-y += irq_work.h
generic-y += mcs_spinlock.h
generic-y += preempt.h
generic-y += scatterlist.h
Expand Down
1 change: 1 addition & 0 deletions arch/arc/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ generic-y += ioctl.h
generic-y += ioctls.h
generic-y += ipcbuf.h
generic-y += irq_regs.h
generic-y += irq_work.h
generic-y += kmap_types.h
generic-y += kvm_para.h
generic-y += local.h
Expand Down
11 changes: 11 additions & 0 deletions arch/arm/include/asm/irq_work.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef __ASM_ARM_IRQ_WORK_H
#define __ASM_ARM_IRQ_WORK_H

#include <asm/smp_plat.h>

static inline bool arch_irq_work_has_interrupt(void)
{
return is_smp();
}

#endif /* _ASM_ARM_IRQ_WORK_H */
2 changes: 1 addition & 1 deletion arch/arm/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ void arch_send_call_function_single_ipi(int cpu)
#ifdef CONFIG_IRQ_WORK
void arch_irq_work_raise(void)
{
if (is_smp())
if (arch_irq_work_has_interrupt())
smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ generic-y += current.h
generic-y += delay.h
generic-y += div64.h
generic-y += dma.h
generic-y += emergency-restart.h
generic-y += early_ioremap.h
generic-y += emergency-restart.h
generic-y += errno.h
generic-y += ftrace.h
generic-y += hash.h
Expand Down
11 changes: 11 additions & 0 deletions arch/arm64/include/asm/irq_work.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef __ASM_IRQ_WORK_H
#define __ASM_IRQ_WORK_H

#include <asm/smp.h>

static inline bool arch_irq_work_has_interrupt(void)
{
return !!__smp_cross_call;
}

#endif /* __ASM_IRQ_WORK_H */
2 changes: 2 additions & 0 deletions arch/arm64/include/asm/smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ extern void smp_init_cpus(void);
*/
extern void set_smp_cross_call(void (*)(const struct cpumask *, unsigned int));

extern void (*__smp_cross_call)(const struct cpumask *, unsigned int);

/*
* Called from the secondary holding pen, this is the secondary CPU entry point.
*/
Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
}
}

static void (*__smp_cross_call)(const struct cpumask *, unsigned int);
void (*__smp_cross_call)(const struct cpumask *, unsigned int);

void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
{
Expand Down
1 change: 1 addition & 0 deletions arch/avr32/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ generic-y += exec.h
generic-y += futex.h
generic-y += hash.h
generic-y += irq_regs.h
generic-y += irq_work.h
generic-y += local.h
generic-y += local64.h
generic-y += mcs_spinlock.h
Expand Down
1 change: 1 addition & 0 deletions arch/blackfin/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ generic-y += hw_irq.h
generic-y += ioctl.h
generic-y += ipcbuf.h
generic-y += irq_regs.h
generic-y += irq_work.h
generic-y += kdebug.h
generic-y += kmap_types.h
generic-y += kvm_para.h
Expand Down
1 change: 1 addition & 0 deletions arch/c6x/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ generic-y += ioctl.h
generic-y += ioctls.h
generic-y += ipcbuf.h
generic-y += irq_regs.h
generic-y += irq_work.h
generic-y += kdebug.h
generic-y += kmap_types.h
generic-y += local.h
Expand Down
1 change: 1 addition & 0 deletions arch/cris/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ generic-y += clkdev.h
generic-y += cputime.h
generic-y += exec.h
generic-y += hash.h
generic-y += irq_work.h
generic-y += kvm_para.h
generic-y += linkage.h
generic-y += mcs_spinlock.h
Expand Down
1 change: 1 addition & 0 deletions arch/frv/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ generic-y += clkdev.h
generic-y += cputime.h
generic-y += exec.h
generic-y += hash.h
generic-y += irq_work.h
generic-y += mcs_spinlock.h
generic-y += preempt.h
generic-y += scatterlist.h
Expand Down
1 change: 1 addition & 0 deletions arch/hexagon/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ generic-y += ioctls.h
generic-y += iomap.h
generic-y += ipcbuf.h
generic-y += irq_regs.h
generic-y += irq_work.h
generic-y += kdebug.h
generic-y += kmap_types.h
generic-y += local.h
Expand Down
1 change: 1 addition & 0 deletions arch/ia64/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
generic-y += clkdev.h
generic-y += exec.h
generic-y += hash.h
generic-y += irq_work.h
generic-y += kvm_para.h
generic-y += mcs_spinlock.h
generic-y += preempt.h
Expand Down
1 change: 1 addition & 0 deletions arch/m32r/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ generic-y += clkdev.h
generic-y += cputime.h
generic-y += exec.h
generic-y += hash.h
generic-y += irq_work.h
generic-y += mcs_spinlock.h
generic-y += module.h
generic-y += preempt.h
Expand Down
1 change: 1 addition & 0 deletions arch/m68k/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ generic-y += hw_irq.h
generic-y += ioctl.h
generic-y += ipcbuf.h
generic-y += irq_regs.h
generic-y += irq_work.h
generic-y += kdebug.h
generic-y += kmap_types.h
generic-y += kvm_para.h
Expand Down
1 change: 1 addition & 0 deletions arch/metag/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ generic-y += ioctl.h
generic-y += ioctls.h
generic-y += ipcbuf.h
generic-y += irq_regs.h
generic-y += irq_work.h
generic-y += kdebug.h
generic-y += kmap_types.h
generic-y += kvm_para.h
Expand Down
1 change: 1 addition & 0 deletions arch/microblaze/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ generic-y += cputime.h
generic-y += device.h
generic-y += exec.h
generic-y += hash.h
generic-y += irq_work.h
generic-y += mcs_spinlock.h
generic-y += preempt.h
generic-y += scatterlist.h
Expand Down
1 change: 1 addition & 0 deletions arch/mips/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ generic-y += cputime.h
generic-y += current.h
generic-y += emergency-restart.h
generic-y += hash.h
generic-y += irq_work.h
generic-y += local64.h
generic-y += mcs_spinlock.h
generic-y += mutex.h
Expand Down
1 change: 1 addition & 0 deletions arch/mn10300/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ generic-y += clkdev.h
generic-y += cputime.h
generic-y += exec.h
generic-y += hash.h
generic-y += irq_work.h
generic-y += mcs_spinlock.h
generic-y += preempt.h
generic-y += scatterlist.h
Expand Down
1 change: 1 addition & 0 deletions arch/openrisc/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ generic-y += ioctl.h
generic-y += ioctls.h
generic-y += ipcbuf.h
generic-y += irq_regs.h
generic-y += irq_work.h
generic-y += kdebug.h
generic-y += kmap_types.h
generic-y += kvm_para.h
Expand Down
1 change: 1 addition & 0 deletions arch/parisc/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ generic-y += exec.h
generic-y += hash.h
generic-y += hw_irq.h
generic-y += irq_regs.h
generic-y += irq_work.h
generic-y += kdebug.h
generic-y += kvm_para.h
generic-y += local.h
Expand Down
1 change: 1 addition & 0 deletions arch/powerpc/include/asm/Kbuild
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

generic-y += clkdev.h
generic-y += hash.h
generic-y += irq_work.h
generic-y += mcs_spinlock.h
generic-y += preempt.h
generic-y += rwsem.h
Expand Down
1 change: 1 addition & 0 deletions arch/s390/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

generic-y += clkdev.h
generic-y += hash.h
generic-y += irq_work.h
generic-y += mcs_spinlock.h
generic-y += preempt.h
generic-y += scatterlist.h
Expand Down
1 change: 1 addition & 0 deletions arch/score/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ generic-y += barrier.h
generic-y += clkdev.h
generic-y += cputime.h
generic-y += hash.h
generic-y += irq_work.h
generic-y += mcs_spinlock.h
generic-y += preempt.h
generic-y += scatterlist.h
Expand Down
1 change: 1 addition & 0 deletions arch/sh/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ generic-y += hash.h
generic-y += ioctl.h
generic-y += ipcbuf.h
generic-y += irq_regs.h
generic-y += irq_work.h
generic-y += kvm_para.h
generic-y += local.h
generic-y += local64.h
Expand Down
1 change: 1 addition & 0 deletions arch/sparc/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ generic-y += emergency-restart.h
generic-y += exec.h
generic-y += hash.h
generic-y += irq_regs.h
generic-y += irq_work.h
generic-y += linkage.h
generic-y += local.h
generic-y += local64.h
Expand Down
1 change: 1 addition & 0 deletions arch/tile/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ generic-y += ioctl.h
generic-y += ioctls.h
generic-y += ipcbuf.h
generic-y += irq_regs.h
generic-y += irq_work.h
generic-y += local.h
generic-y += local64.h
generic-y += mcs_spinlock.h
Expand Down
1 change: 1 addition & 0 deletions arch/um/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ generic-y += hash.h
generic-y += hw_irq.h
generic-y += io.h
generic-y += irq_regs.h
generic-y += irq_work.h
generic-y += kdebug.h
generic-y += mcs_spinlock.h
generic-y += mutex.h
Expand Down
1 change: 1 addition & 0 deletions arch/unicore32/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ generic-y += ioctl.h
generic-y += ioctls.h
generic-y += ipcbuf.h
generic-y += irq_regs.h
generic-y += irq_work.h
generic-y += kdebug.h
generic-y += kmap_types.h
generic-y += local.h
Expand Down
11 changes: 11 additions & 0 deletions arch/x86/include/asm/irq_work.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef _ASM_IRQ_WORK_H
#define _ASM_IRQ_WORK_H

#include <asm/processor.h>

static inline bool arch_irq_work_has_interrupt(void)
{
return cpu_has_apic;
}

#endif /* _ASM_IRQ_WORK_H */
2 changes: 1 addition & 1 deletion arch/x86/kernel/irq_work.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ __visible void smp_trace_irq_work_interrupt(struct pt_regs *regs)
void arch_irq_work_raise(void)
{
#ifdef CONFIG_X86_LOCAL_APIC
if (!cpu_has_apic)
if (!arch_irq_work_has_interrupt())
return;

apic->send_IPI_self(IRQ_WORK_VECTOR);
Expand Down
1 change: 1 addition & 0 deletions arch/xtensa/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ generic-y += hardirq.h
generic-y += hash.h
generic-y += ioctl.h
generic-y += irq_regs.h
generic-y += irq_work.h
generic-y += kdebug.h
generic-y += kmap_types.h
generic-y += kvm_para.h
Expand Down
10 changes: 10 additions & 0 deletions include/asm-generic/irq_work.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef __ASM_IRQ_WORK_H
#define __ASM_IRQ_WORK_H

static inline bool arch_irq_work_has_interrupt(void)
{
return false;
}

#endif /* __ASM_IRQ_WORK_H */

3 changes: 3 additions & 0 deletions include/linux/irq_work.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@ bool irq_work_queue_on(struct irq_work *work, int cpu);
#endif

void irq_work_run(void);
void irq_work_tick(void);
void irq_work_sync(struct irq_work *work);

#ifdef CONFIG_IRQ_WORK
#include <asm/irq_work.h>

bool irq_work_needs_cpu(void);
#else
static inline bool irq_work_needs_cpu(void) { return false; }
Expand Down
2 changes: 0 additions & 2 deletions include/linux/tick.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,12 @@ static inline bool tick_nohz_full_cpu(int cpu)
return cpumask_test_cpu(cpu, tick_nohz_full_mask);
}

extern void tick_nohz_init(void);
extern void __tick_nohz_full_check(void);
extern void tick_nohz_full_kick(void);
extern void tick_nohz_full_kick_cpu(int cpu);
extern void tick_nohz_full_kick_all(void);
extern void __tick_nohz_task_switch(struct task_struct *tsk);
#else
static inline void tick_nohz_init(void) { }
static inline bool tick_nohz_full_enabled(void) { return false; }
static inline bool tick_nohz_full_cpu(int cpu) { return false; }
static inline void __tick_nohz_full_check(void) { }
Expand Down
1 change: 0 additions & 1 deletion init/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,6 @@ asmlinkage __visible void __init start_kernel(void)
local_irq_disable();
idr_init_cache();
rcu_init();
tick_nohz_init();
context_tracking_init();
radix_tree_init();
/* init some links before init_ISA_irqs() */
Expand Down
15 changes: 13 additions & 2 deletions kernel/irq_work.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,10 @@ bool irq_work_needs_cpu(void)

raised = &__get_cpu_var(raised_list);
lazy = &__get_cpu_var(lazy_list);
if (llist_empty(raised) && llist_empty(lazy))
return false;

if (llist_empty(raised) || arch_irq_work_has_interrupt())
if (llist_empty(lazy))
return false;

/* All work should have been flushed before going offline */
WARN_ON_ONCE(cpu_is_offline(smp_processor_id()));
Expand Down Expand Up @@ -171,6 +173,15 @@ void irq_work_run(void)
}
EXPORT_SYMBOL_GPL(irq_work_run);

void irq_work_tick(void)
{
struct llist_head *raised = &__get_cpu_var(raised_list);

if (!llist_empty(raised) && !arch_irq_work_has_interrupt())
irq_work_run_list(raised);
irq_work_run_list(&__get_cpu_var(lazy_list));
}

/*
* Synchronize against the irq_work @entry, ensures the entry is not
* currently in use.
Expand Down
1 change: 1 addition & 0 deletions kernel/time/tick-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,4 +400,5 @@ void tick_resume(void)
void __init tick_init(void)
{
tick_broadcast_init();
tick_nohz_init();
}
7 changes: 7 additions & 0 deletions kernel/time/tick-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ static inline int tick_broadcast_oneshot_active(void) { return 0; }
static inline bool tick_broadcast_oneshot_available(void) { return false; }
#endif /* !TICK_ONESHOT */

/* NO_HZ_FULL internal */
#ifdef CONFIG_NO_HZ_FULL
extern void tick_nohz_init(void);
# else
static inline void tick_nohz_init(void) { }
#endif

/*
* Broadcasting support
*/
Expand Down
Loading

0 comments on commit afa3536

Please sign in to comment.