Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 15 May 2013 21:05:17 +0000 (14:05 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 15 May 2013 21:05:17 +0000 (14:05 -0700)
Pull timer fixes from Thomas Gleixner:

 - Cure for not using zalloc in the first place, which leads to random
   crashes with CPUMASK_OFF_STACK.

 - Revert a user space visible change which broke udev

 - Add a missing cpu_online early return introduced by the new full
   dyntick conversions

 - Plug a long standing race in the timer wheel cpu hotplug code.
   Sigh...

 - Cleanup NOHZ per cpu data on cpu down to prevent stale data on cpu
   up.

* 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  time: Revert ALWAYS_USE_PERSISTENT_CLOCK compile time optimizaitons
  timer: Don't reinitialize the cpu base lock during CPU_UP_PREPARE
  tick: Don't invoke tick_nohz_stop_sched_tick() if the cpu is offline
  tick: Cleanup NOHZ per cpu data on cpu down
  tick: Use zalloc_cpumask_var for allocating offstack cpumasks

1  2 
arch/x86/Kconfig
kernel/time/Kconfig
kernel/time/tick-broadcast.c
kernel/time/tick-sched.c
kernel/timer.c

diff --combined arch/x86/Kconfig
index 6a154a91c7e746342f35cf6aa13bdae24f544a88,45c41249321f3ffaacdc733dabbdc9bd22e27648..685692c94f051a8a7ad582442efcc3fa11173332
@@@ -108,7 -108,6 +108,6 @@@ config X8
        select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && X86_LOCAL_APIC)
        select GENERIC_TIME_VSYSCALL if X86_64
        select KTIME_SCALAR if X86_32
-       select ALWAYS_USE_PERSISTENT_CLOCK
        select GENERIC_STRNCPY_FROM_USER
        select GENERIC_STRNLEN_USER
        select HAVE_CONTEXT_TRACKING if X86_64
@@@ -174,6 -173,9 +173,6 @@@ config GENERIC_BUG_RELATIVE_POINTER
  config GENERIC_HWEIGHT
        def_bool y
  
 -config GENERIC_GPIO
 -      bool
 -
  config ARCH_MAY_HAVE_PC_FDC
        def_bool y
        depends on ISA_DMA_API
diff --combined kernel/time/Kconfig
index e4c07b0692bbba4a79676ffceed77324fd6087bf,b69692250af4a3ca47078e62d21c6ad2069e56af..70f27e89012b29d18b4aeb9c6e5c367d1b3955a5
@@@ -12,11 -12,6 +12,6 @@@ config CLOCKSOURCE_WATCHDO
  config ARCH_CLOCKSOURCE_DATA
        bool
  
- # Platforms has a persistent clock
- config ALWAYS_USE_PERSISTENT_CLOCK
-       bool
-       default n
  # Timekeeping vsyscall support
  config GENERIC_TIME_VSYSCALL
        bool
@@@ -64,88 -59,20 +59,88 @@@ config GENERIC_CMOS_UPDAT
  if GENERIC_CLOCKEVENTS
  menu "Timers subsystem"
  
 -# Core internal switch. Selected by NO_HZ / HIGH_RES_TIMERS. This is
 +# Core internal switch. Selected by NO_HZ_COMMON / HIGH_RES_TIMERS. This is
  # only related to the tick functionality. Oneshot clockevent devices
  # are supported independ of this.
  config TICK_ONESHOT
        bool
  
 -config NO_HZ
 -      bool "Tickless System (Dynamic Ticks)"
 +config NO_HZ_COMMON
 +      bool
        depends on !ARCH_USES_GETTIMEOFFSET && GENERIC_CLOCKEVENTS
        select TICK_ONESHOT
 +
 +choice
 +      prompt "Timer tick handling"
 +      default NO_HZ_IDLE if NO_HZ
 +
 +config HZ_PERIODIC
 +      bool "Periodic timer ticks (constant rate, no dynticks)"
 +      help
 +        This option keeps the tick running periodically at a constant
 +        rate, even when the CPU doesn't need it.
 +
 +config NO_HZ_IDLE
 +      bool "Idle dynticks system (tickless idle)"
 +      depends on !ARCH_USES_GETTIMEOFFSET && GENERIC_CLOCKEVENTS
 +      select NO_HZ_COMMON
 +      help
 +        This option enables a tickless idle system: timer interrupts
 +        will only trigger on an as-needed basis when the system is idle.
 +        This is usually interesting for energy saving.
 +
 +        Most of the time you want to say Y here.
 +
 +config NO_HZ_FULL
 +      bool "Full dynticks system (tickless)"
 +      # NO_HZ_COMMON dependency
 +      depends on !ARCH_USES_GETTIMEOFFSET && GENERIC_CLOCKEVENTS
 +      # We need at least one periodic CPU for timekeeping
 +      depends on SMP
 +      # RCU_USER_QS dependency
 +      depends on HAVE_CONTEXT_TRACKING
 +      # VIRT_CPU_ACCOUNTING_GEN dependency
 +      depends on 64BIT
 +      select NO_HZ_COMMON
 +      select RCU_USER_QS
 +      select RCU_NOCB_CPU
 +      select VIRT_CPU_ACCOUNTING_GEN
 +      select CONTEXT_TRACKING_FORCE
 +      select IRQ_WORK
 +      help
 +       Adaptively try to shutdown the tick whenever possible, even when
 +       the CPU is running tasks. Typically this requires running a single
 +       task on the CPU. Chances for running tickless are maximized when
 +       the task mostly runs in userspace and has few kernel activity.
 +
 +       You need to fill up the nohz_full boot parameter with the
 +       desired range of dynticks CPUs.
 +
 +       This is implemented at the expense of some overhead in user <-> kernel
 +       transitions: syscalls, exceptions and interrupts. Even when it's
 +       dynamically off.
 +
 +       Say N.
 +
 +endchoice
 +
 +config NO_HZ_FULL_ALL
 +       bool "Full dynticks system on all CPUs by default"
 +       depends on NO_HZ_FULL
 +       help
 +         If the user doesn't pass the nohz_full boot option to
 +       define the range of full dynticks CPUs, consider that all
 +       CPUs in the system are full dynticks by default.
 +       Note the boot CPU will still be kept outside the range to
 +       handle the timekeeping duty.
 +
 +config NO_HZ
 +      bool "Old Idle dynticks config"
 +      depends on !ARCH_USES_GETTIMEOFFSET && GENERIC_CLOCKEVENTS
        help
 -        This option enables a tickless system: timer interrupts will
 -        only trigger on an as-needed basis both when the system is
 -        busy and when the system is idle.
 +        This is the old config entry that enables dynticks idle.
 +        We keep it around for a little while to enforce backward
 +        compatibility with older config files.
  
  config HIGH_RES_TIMERS
        bool "High Resolution Timer Support"
index 206bbfb34e091d21f5928a846f4e1a53ab984663,d70cdc42c8294bdafe4f654e27aaeeaa9fa99c24..24938d57766948646e567ba4814129d3d74b7112
@@@ -693,8 -693,7 +693,8 @@@ void tick_broadcast_setup_oneshot(struc
                bc->event_handler = tick_handle_oneshot_broadcast;
  
                /* Take the do_timer update */
 -              tick_do_timer_cpu = cpu;
 +              if (!tick_nohz_full_cpu(cpu))
 +                      tick_do_timer_cpu = cpu;
  
                /*
                 * We must be careful here. There might be other CPUs
@@@ -786,11 -785,11 +786,11 @@@ bool tick_broadcast_oneshot_available(v
  
  void __init tick_broadcast_init(void)
  {
-       alloc_cpumask_var(&tick_broadcast_mask, GFP_NOWAIT);
-       alloc_cpumask_var(&tmpmask, GFP_NOWAIT);
+       zalloc_cpumask_var(&tick_broadcast_mask, GFP_NOWAIT);
+       zalloc_cpumask_var(&tmpmask, GFP_NOWAIT);
  #ifdef CONFIG_TICK_ONESHOT
-       alloc_cpumask_var(&tick_broadcast_oneshot_mask, GFP_NOWAIT);
-       alloc_cpumask_var(&tick_broadcast_pending_mask, GFP_NOWAIT);
-       alloc_cpumask_var(&tick_broadcast_force_mask, GFP_NOWAIT);
+       zalloc_cpumask_var(&tick_broadcast_oneshot_mask, GFP_NOWAIT);
+       zalloc_cpumask_var(&tick_broadcast_pending_mask, GFP_NOWAIT);
+       zalloc_cpumask_var(&tick_broadcast_force_mask, GFP_NOWAIT);
  #endif
  }
diff --combined kernel/time/tick-sched.c
index bc67d4245e1d130b523fd36482d50ebe4cbab763,012142187db9bb16db56f671aa9d02a0b0749bf0..f4208138fbf4cd1a72791f99c31adcbea9180e3e
  #include <linux/sched.h>
  #include <linux/module.h>
  #include <linux/irq_work.h>
 +#include <linux/posix-timers.h>
 +#include <linux/perf_event.h>
  
  #include <asm/irq_regs.h>
  
  #include "tick-internal.h"
  
 +#include <trace/events/timer.h>
 +
  /*
   * Per cpu nohz control structure
   */
@@@ -108,7 -104,7 +108,7 @@@ static void tick_sched_do_timer(ktime_
  {
        int cpu = smp_processor_id();
  
 -#ifdef CONFIG_NO_HZ
 +#ifdef CONFIG_NO_HZ_COMMON
        /*
         * Check if the do_timer duty was dropped. We don't care about
         * concurrency: This happens only when the cpu in charge went
         * this duty, then the jiffies update is still serialized by
         * jiffies_lock.
         */
 -      if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE))
 +      if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE)
 +          && !tick_nohz_full_cpu(cpu))
                tick_do_timer_cpu = cpu;
  #endif
  
  
  static void tick_sched_handle(struct tick_sched *ts, struct pt_regs *regs)
  {
 -#ifdef CONFIG_NO_HZ
 +#ifdef CONFIG_NO_HZ_COMMON
        /*
         * When we are idle and the tick is stopped, we have to touch
         * the watchdog as we might not schedule for a really long
        profile_tick(CPU_PROFILING);
  }
  
 +#ifdef CONFIG_NO_HZ_FULL
 +static cpumask_var_t nohz_full_mask;
 +bool have_nohz_full_mask;
 +
 +static bool can_stop_full_tick(void)
 +{
 +      WARN_ON_ONCE(!irqs_disabled());
 +
 +      if (!sched_can_stop_tick()) {
 +              trace_tick_stop(0, "more than 1 task in runqueue\n");
 +              return false;
 +      }
 +
 +      if (!posix_cpu_timers_can_stop_tick(current)) {
 +              trace_tick_stop(0, "posix timers running\n");
 +              return false;
 +      }
 +
 +      if (!perf_event_can_stop_tick()) {
 +              trace_tick_stop(0, "perf events running\n");
 +              return false;
 +      }
 +
 +      /* sched_clock_tick() needs us? */
 +#ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK
 +      /*
 +       * TODO: kick full dynticks CPUs when
 +       * sched_clock_stable is set.
 +       */
 +      if (!sched_clock_stable) {
 +              trace_tick_stop(0, "unstable sched clock\n");
 +              return false;
 +      }
 +#endif
 +
 +      return true;
 +}
 +
 +static void tick_nohz_restart_sched_tick(struct tick_sched *ts, ktime_t now);
 +
 +/*
 + * Re-evaluate the need for the tick on the current CPU
 + * and restart it if necessary.
 + */
 +void tick_nohz_full_check(void)
 +{
 +      struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
 +
 +      if (tick_nohz_full_cpu(smp_processor_id())) {
 +              if (ts->tick_stopped && !is_idle_task(current)) {
 +                      if (!can_stop_full_tick())
 +                              tick_nohz_restart_sched_tick(ts, ktime_get());
 +              }
 +      }
 +}
 +
 +static void nohz_full_kick_work_func(struct irq_work *work)
 +{
 +      tick_nohz_full_check();
 +}
 +
 +static DEFINE_PER_CPU(struct irq_work, nohz_full_kick_work) = {
 +      .func = nohz_full_kick_work_func,
 +};
 +
 +/*
 + * Kick the current CPU if it's full dynticks in order to force it to
 + * re-evaluate its dependency on the tick and restart it if necessary.
 + */
 +void tick_nohz_full_kick(void)
 +{
 +      if (tick_nohz_full_cpu(smp_processor_id()))
 +              irq_work_queue(&__get_cpu_var(nohz_full_kick_work));
 +}
 +
 +static void nohz_full_kick_ipi(void *info)
 +{
 +      tick_nohz_full_check();
 +}
 +
 +/*
 + * Kick all full dynticks CPUs in order to force these to re-evaluate
 + * their dependency on the tick and restart it if necessary.
 + */
 +void tick_nohz_full_kick_all(void)
 +{
 +      if (!have_nohz_full_mask)
 +              return;
 +
 +      preempt_disable();
 +      smp_call_function_many(nohz_full_mask,
 +                             nohz_full_kick_ipi, NULL, false);
 +      preempt_enable();
 +}
 +
 +/*
 + * Re-evaluate the need for the tick as we switch the current task.
 + * It might need the tick due to per task/process properties:
 + * perf events, posix cpu timers, ...
 + */
 +void tick_nohz_task_switch(struct task_struct *tsk)
 +{
 +      unsigned long flags;
 +
 +      local_irq_save(flags);
 +
 +      if (!tick_nohz_full_cpu(smp_processor_id()))
 +              goto out;
 +
 +      if (tick_nohz_tick_stopped() && !can_stop_full_tick())
 +              tick_nohz_full_kick();
 +
 +out:
 +      local_irq_restore(flags);
 +}
 +
 +int tick_nohz_full_cpu(int cpu)
 +{
 +      if (!have_nohz_full_mask)
 +              return 0;
 +
 +      return cpumask_test_cpu(cpu, nohz_full_mask);
 +}
 +
 +/* Parse the boot-time nohz CPU list from the kernel parameters. */
 +static int __init tick_nohz_full_setup(char *str)
 +{
 +      int cpu;
 +
 +      alloc_bootmem_cpumask_var(&nohz_full_mask);
 +      if (cpulist_parse(str, nohz_full_mask) < 0) {
 +              pr_warning("NOHZ: Incorrect nohz_full cpumask\n");
 +              return 1;
 +      }
 +
 +      cpu = smp_processor_id();
 +      if (cpumask_test_cpu(cpu, nohz_full_mask)) {
 +              pr_warning("NO_HZ: Clearing %d from nohz_full range for timekeeping\n", cpu);
 +              cpumask_clear_cpu(cpu, nohz_full_mask);
 +      }
 +      have_nohz_full_mask = true;
 +
 +      return 1;
 +}
 +__setup("nohz_full=", tick_nohz_full_setup);
 +
 +static int __cpuinit tick_nohz_cpu_down_callback(struct notifier_block *nfb,
 +                                               unsigned long action,
 +                                               void *hcpu)
 +{
 +      unsigned int cpu = (unsigned long)hcpu;
 +
 +      switch (action & ~CPU_TASKS_FROZEN) {
 +      case CPU_DOWN_PREPARE:
 +              /*
 +               * If we handle the timekeeping duty for full dynticks CPUs,
 +               * we can't safely shutdown that CPU.
 +               */
 +              if (have_nohz_full_mask && tick_do_timer_cpu == cpu)
 +                      return -EINVAL;
 +              break;
 +      }
 +      return NOTIFY_OK;
 +}
 +
 +/*
 + * Worst case string length in chunks of CPU range seems 2 steps
 + * separations: 0,2,4,6,...
 + * This is NR_CPUS + sizeof('\0')
 + */
 +static char __initdata nohz_full_buf[NR_CPUS + 1];
 +
 +static int tick_nohz_init_all(void)
 +{
 +      int err = -1;
 +
 +#ifdef CONFIG_NO_HZ_FULL_ALL
 +      if (!alloc_cpumask_var(&nohz_full_mask, GFP_KERNEL)) {
 +              pr_err("NO_HZ: Can't allocate full dynticks cpumask\n");
 +              return err;
 +      }
 +      err = 0;
 +      cpumask_setall(nohz_full_mask);
 +      cpumask_clear_cpu(smp_processor_id(), nohz_full_mask);
 +      have_nohz_full_mask = true;
 +#endif
 +      return err;
 +}
 +
 +void __init tick_nohz_init(void)
 +{
 +      int cpu;
 +
 +      if (!have_nohz_full_mask) {
 +              if (tick_nohz_init_all() < 0)
 +                      return;
 +      }
 +
 +      cpu_notifier(tick_nohz_cpu_down_callback, 0);
 +
 +      /* Make sure full dynticks CPU are also RCU nocbs */
 +      for_each_cpu(cpu, nohz_full_mask) {
 +              if (!rcu_is_nocb_cpu(cpu)) {
 +                      pr_warning("NO_HZ: CPU %d is not RCU nocb: "
 +                                 "cleared from nohz_full range", cpu);
 +                      cpumask_clear_cpu(cpu, nohz_full_mask);
 +              }
 +      }
 +
 +      cpulist_scnprintf(nohz_full_buf, sizeof(nohz_full_buf), nohz_full_mask);
 +      pr_info("NO_HZ: Full dynticks CPUs: %s.\n", nohz_full_buf);
 +}
 +#else
 +#define have_nohz_full_mask (0)
 +#endif
 +
  /*
   * NOHZ - aka dynamic tick functionality
   */
 -#ifdef CONFIG_NO_HZ
 +#ifdef CONFIG_NO_HZ_COMMON
  /*
   * NO HZ enabled ?
   */
@@@ -566,12 -345,11 +566,12 @@@ static ktime_t tick_nohz_stop_sched_tic
                        delta_jiffies = rcu_delta_jiffies;
                }
        }
 +
        /*
 -       * Do not stop the tick, if we are only one off
 -       * or if the cpu is required for rcu
 +       * Do not stop the tick, if we are only one off (or less)
 +       * or if the cpu is required for RCU:
         */
 -      if (!ts->tick_stopped && delta_jiffies == 1)
 +      if (!ts->tick_stopped && delta_jiffies <= 1)
                goto out;
  
        /* Schedule the tick, if we are at least one jiffie off */
                        time_delta = KTIME_MAX;
                }
  
 +#ifdef CONFIG_NO_HZ_FULL
 +              if (!ts->inidle) {
 +                      time_delta = min(time_delta,
 +                                       scheduler_tick_max_deferment());
 +              }
 +#endif
 +
                /*
                 * calculate the expiry time for the next timer wheel
                 * timer. delta_jiffies >= NEXT_TIMER_MAX_DELTA signals
  
                        ts->last_tick = hrtimer_get_expires(&ts->sched_timer);
                        ts->tick_stopped = 1;
 +                      trace_tick_stop(1, " ");
                }
  
                /*
@@@ -687,24 -457,6 +687,24 @@@ out
        return ret;
  }
  
 +static void tick_nohz_full_stop_tick(struct tick_sched *ts)
 +{
 +#ifdef CONFIG_NO_HZ_FULL
 +       int cpu = smp_processor_id();
 +
 +       if (!tick_nohz_full_cpu(cpu) || is_idle_task(current))
 +               return;
 +
 +       if (!ts->tick_stopped && ts->nohz_mode == NOHZ_MODE_INACTIVE)
 +             return;
 +
 +       if (!can_stop_full_tick())
 +               return;
 +
 +       tick_nohz_stop_sched_tick(ts, ktime_get(), cpu);
 +#endif
 +}
 +
  static bool can_stop_idle_tick(int cpu, struct tick_sched *ts)
  {
        /*
        if (unlikely(!cpu_online(cpu))) {
                if (cpu == tick_do_timer_cpu)
                        tick_do_timer_cpu = TICK_DO_TIMER_NONE;
+               return false;
        }
  
        if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE))
                return false;
        }
  
 +      if (have_nohz_full_mask) {
 +              /*
 +               * Keep the tick alive to guarantee timekeeping progression
 +               * if there are full dynticks CPUs around
 +               */
 +              if (tick_do_timer_cpu == cpu)
 +                      return false;
 +              /*
 +               * Boot safety: make sure the timekeeping duty has been
 +               * assigned before entering dyntick-idle mode,
 +               */
 +              if (tick_do_timer_cpu == TICK_DO_TIMER_NONE)
 +                      return false;
 +      }
 +
        return true;
  }
  
@@@ -831,13 -569,12 +832,13 @@@ void tick_nohz_irq_exit(void
  {
        struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
  
 -      if (!ts->inidle)
 -              return;
 -
 -      /* Cancel the timer because CPU already waken up from the C-states*/
 -      menu_hrtimer_cancel();
 -      __tick_nohz_idle_enter(ts);
 +      if (ts->inidle) {
 +              /* Cancel the timer because CPU already waken up from the C-states*/
 +              menu_hrtimer_cancel();
 +              __tick_nohz_idle_enter(ts);
 +      } else {
 +              tick_nohz_full_stop_tick(ts);
 +      }
  }
  
  /**
@@@ -1066,7 -803,7 +1067,7 @@@ static inline void tick_check_nohz(int 
  static inline void tick_nohz_switch_to_nohz(void) { }
  static inline void tick_check_nohz(int cpu) { }
  
 -#endif /* NO_HZ */
 +#endif /* CONFIG_NO_HZ_COMMON */
  
  /*
   * Called from irq_enter to notify about the possible interruption of idle()
@@@ -1151,14 -888,14 +1152,14 @@@ void tick_setup_sched_timer(void
                now = ktime_get();
        }
  
 -#ifdef CONFIG_NO_HZ
 +#ifdef CONFIG_NO_HZ_COMMON
        if (tick_nohz_enabled)
                ts->nohz_mode = NOHZ_MODE_HIGHRES;
  #endif
  }
  #endif /* HIGH_RES_TIMERS */
  
 -#if defined CONFIG_NO_HZ || defined CONFIG_HIGH_RES_TIMERS
 +#if defined CONFIG_NO_HZ_COMMON || defined CONFIG_HIGH_RES_TIMERS
  void tick_cancel_sched_timer(int cpu)
  {
        struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
                hrtimer_cancel(&ts->sched_timer);
  # endif
  
-       ts->nohz_mode = NOHZ_MODE_INACTIVE;
+       memset(ts, 0, sizeof(*ts));
  }
  #endif
  
diff --combined kernel/timer.c
index a860bba34412c0d8047ff4d81c54fb500fa5de9f,7376589adc2857a2e3101c021cdf06ce5a8af378..15ffdb3f1948b9468c2c04527beb8190b0d79d45
@@@ -739,7 -739,7 +739,7 @@@ __mod_timer(struct timer_list *timer, u
  
        cpu = smp_processor_id();
  
 -#if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP)
 +#if defined(CONFIG_NO_HZ_COMMON) && defined(CONFIG_SMP)
        if (!pinned && get_sysctl_timer_migration() && idle_cpu(cpu))
                cpu = get_nohz_timer_target();
  #endif
@@@ -931,14 -931,14 +931,14 @@@ void add_timer_on(struct timer_list *ti
        debug_activate(timer, timer->expires);
        internal_add_timer(base, timer);
        /*
 -       * Check whether the other CPU is idle and needs to be
 -       * triggered to reevaluate the timer wheel when nohz is
 -       * active. We are protected against the other CPU fiddling
 +       * Check whether the other CPU is in dynticks mode and needs
 +       * to be triggered to reevaluate the timer wheel.
 +       * We are protected against the other CPU fiddling
         * with the timer by holding the timer base lock. This also
 -       * makes sure that a CPU on the way to idle can not evaluate
 -       * the timer wheel.
 +       * makes sure that a CPU on the way to stop its tick can not
 +       * evaluate the timer wheel.
         */
 -      wake_up_idle_cpu(cpu);
 +      wake_up_nohz_cpu(cpu);
        spin_unlock_irqrestore(&base->lock, flags);
  }
  EXPORT_SYMBOL_GPL(add_timer_on);
@@@ -1189,7 -1189,7 +1189,7 @@@ static inline void __run_timers(struct 
        spin_unlock_irq(&base->lock);
  }
  
 -#ifdef CONFIG_NO_HZ
 +#ifdef CONFIG_NO_HZ_COMMON
  /*
   * Find out when the next timer event is due to happen. This
   * is used on S/390 to stop all activity when a CPU is idle.
@@@ -1539,12 -1539,12 +1539,12 @@@ static int __cpuinit init_timers_cpu(in
                        boot_done = 1;
                        base = &boot_tvec_bases;
                }
+               spin_lock_init(&base->lock);
                tvec_base_done[cpu] = 1;
        } else {
                base = per_cpu(tvec_bases, cpu);
        }
  
-       spin_lock_init(&base->lock);
  
        for (j = 0; j < TVN_SIZE; j++) {
                INIT_LIST_HEAD(base->tv5.vec + j);