Merge branch 'core-v28-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6.git] / kernel / timer.c
index 1258371..510fe69 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
+#include <linux/pid_namespace.h>
 #include <linux/notifier.h>
 #include <linux/thread_info.h>
 #include <linux/time.h>
@@ -57,60 +58,58 @@ EXPORT_SYMBOL(jiffies_64);
 #define TVN_MASK (TVN_SIZE - 1)
 #define TVR_MASK (TVR_SIZE - 1)
 
-typedef struct tvec_s {
+struct tvec {
        struct list_head vec[TVN_SIZE];
-} tvec_t;
+};
 
-typedef struct tvec_root_s {
+struct tvec_root {
        struct list_head vec[TVR_SIZE];
-} tvec_root_t;
+};
 
-struct tvec_t_base_s {
+struct tvec_base {
        spinlock_t lock;
        struct timer_list *running_timer;
        unsigned long timer_jiffies;
-       tvec_root_t tv1;
-       tvec_t tv2;
-       tvec_t tv3;
-       tvec_t tv4;
-       tvec_t tv5;
+       struct tvec_root tv1;
+       struct tvec tv2;
+       struct tvec tv3;
+       struct tvec tv4;
+       struct tvec tv5;
 } ____cacheline_aligned;
 
-typedef struct tvec_t_base_s tvec_base_t;
-
-tvec_base_t boot_tvec_bases;
+struct tvec_base boot_tvec_bases;
 EXPORT_SYMBOL(boot_tvec_bases);
-static DEFINE_PER_CPU(tvec_base_t *, tvec_bases) = &boot_tvec_bases;
+static DEFINE_PER_CPU(struct tvec_base *, tvec_bases) = &boot_tvec_bases;
 
 /*
- * Note that all tvec_bases is 2 byte aligned and lower bit of
+ * Note that all tvec_bases are 2 byte aligned and lower bit of
  * base in timer_list is guaranteed to be zero. Use the LSB for
  * the new flag to indicate whether the timer is deferrable
  */
 #define TBASE_DEFERRABLE_FLAG          (0x1)
 
 /* Functions below help us manage 'deferrable' flag */
-static inline unsigned int tbase_get_deferrable(tvec_base_t *base)
+static inline unsigned int tbase_get_deferrable(struct tvec_base *base)
 {
        return ((unsigned int)(unsigned long)base & TBASE_DEFERRABLE_FLAG);
 }
 
-static inline tvec_base_t *tbase_get_base(tvec_base_t *base)
+static inline struct tvec_base *tbase_get_base(struct tvec_base *base)
 {
-       return ((tvec_base_t *)((unsigned long)base & ~TBASE_DEFERRABLE_FLAG));
+       return ((struct tvec_base *)((unsigned long)base & ~TBASE_DEFERRABLE_FLAG));
 }
 
 static inline void timer_set_deferrable(struct timer_list *timer)
 {
-       timer->base = ((tvec_base_t *)((unsigned long)(timer->base) |
-                                      TBASE_DEFERRABLE_FLAG));
+       timer->base = ((struct tvec_base *)((unsigned long)(timer->base) |
+                                      TBASE_DEFERRABLE_FLAG));
 }
 
 static inline void
-timer_set_base(struct timer_list *timer, tvec_base_t *new_base)
+timer_set_base(struct timer_list *timer, struct tvec_base *new_base)
 {
-       timer->base = (tvec_base_t *)((unsigned long)(new_base) |
-                                     tbase_get_deferrable(timer->base));
+       timer->base = (struct tvec_base *)((unsigned long)(new_base) |
+                                     tbase_get_deferrable(timer->base));
 }
 
 /**
@@ -245,7 +244,7 @@ unsigned long round_jiffies_relative(unsigned long j)
 EXPORT_SYMBOL_GPL(round_jiffies_relative);
 
 
-static inline void set_running_timer(tvec_base_t *base,
+static inline void set_running_timer(struct tvec_base *base,
                                        struct timer_list *timer)
 {
 #ifdef CONFIG_SMP
@@ -253,7 +252,7 @@ static inline void set_running_timer(tvec_base_t *base,
 #endif
 }
 
-static void internal_add_timer(tvec_base_t *base, struct timer_list *timer)
+static void internal_add_timer(struct tvec_base *base, struct timer_list *timer)
 {
        unsigned long expires = timer->expires;
        unsigned long idx = expires - base->timer_jiffies;
@@ -321,14 +320,130 @@ static void timer_stats_account_timer(struct timer_list *timer)
 static void timer_stats_account_timer(struct timer_list *timer) {}
 #endif
 
-/**
- * init_timer - initialize a timer.
- * @timer: the timer to be initialized
- *
- * init_timer() must be done to a timer prior calling *any* of the
- * other timer functions.
+#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
+
+static struct debug_obj_descr timer_debug_descr;
+
+/*
+ * fixup_init is called when:
+ * - an active object is initialized
+ */
+static int timer_fixup_init(void *addr, enum debug_obj_state state)
+{
+       struct timer_list *timer = addr;
+
+       switch (state) {
+       case ODEBUG_STATE_ACTIVE:
+               del_timer_sync(timer);
+               debug_object_init(timer, &timer_debug_descr);
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+/*
+ * fixup_activate is called when:
+ * - an active object is activated
+ * - an unknown object is activated (might be a statically initialized object)
  */
-void fastcall init_timer(struct timer_list *timer)
+static int timer_fixup_activate(void *addr, enum debug_obj_state state)
+{
+       struct timer_list *timer = addr;
+
+       switch (state) {
+
+       case ODEBUG_STATE_NOTAVAILABLE:
+               /*
+                * This is not really a fixup. The timer was
+                * statically initialized. We just make sure that it
+                * is tracked in the object tracker.
+                */
+               if (timer->entry.next == NULL &&
+                   timer->entry.prev == TIMER_ENTRY_STATIC) {
+                       debug_object_init(timer, &timer_debug_descr);
+                       debug_object_activate(timer, &timer_debug_descr);
+                       return 0;
+               } else {
+                       WARN_ON_ONCE(1);
+               }
+               return 0;
+
+       case ODEBUG_STATE_ACTIVE:
+               WARN_ON(1);
+
+       default:
+               return 0;
+       }
+}
+
+/*
+ * fixup_free is called when:
+ * - an active object is freed
+ */
+static int timer_fixup_free(void *addr, enum debug_obj_state state)
+{
+       struct timer_list *timer = addr;
+
+       switch (state) {
+       case ODEBUG_STATE_ACTIVE:
+               del_timer_sync(timer);
+               debug_object_free(timer, &timer_debug_descr);
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+static struct debug_obj_descr timer_debug_descr = {
+       .name           = "timer_list",
+       .fixup_init     = timer_fixup_init,
+       .fixup_activate = timer_fixup_activate,
+       .fixup_free     = timer_fixup_free,
+};
+
+static inline void debug_timer_init(struct timer_list *timer)
+{
+       debug_object_init(timer, &timer_debug_descr);
+}
+
+static inline void debug_timer_activate(struct timer_list *timer)
+{
+       debug_object_activate(timer, &timer_debug_descr);
+}
+
+static inline void debug_timer_deactivate(struct timer_list *timer)
+{
+       debug_object_deactivate(timer, &timer_debug_descr);
+}
+
+static inline void debug_timer_free(struct timer_list *timer)
+{
+       debug_object_free(timer, &timer_debug_descr);
+}
+
+static void __init_timer(struct timer_list *timer);
+
+void init_timer_on_stack(struct timer_list *timer)
+{
+       debug_object_init_on_stack(timer, &timer_debug_descr);
+       __init_timer(timer);
+}
+EXPORT_SYMBOL_GPL(init_timer_on_stack);
+
+void destroy_timer_on_stack(struct timer_list *timer)
+{
+       debug_object_free(timer, &timer_debug_descr);
+}
+EXPORT_SYMBOL_GPL(destroy_timer_on_stack);
+
+#else
+static inline void debug_timer_init(struct timer_list *timer) { }
+static inline void debug_timer_activate(struct timer_list *timer) { }
+static inline void debug_timer_deactivate(struct timer_list *timer) { }
+#endif
+
+static void __init_timer(struct timer_list *timer)
 {
        timer->entry.next = NULL;
        timer->base = __raw_get_cpu_var(tvec_bases);
@@ -338,9 +453,22 @@ void fastcall init_timer(struct timer_list *timer)
        memset(timer->start_comm, 0, TASK_COMM_LEN);
 #endif
 }
+
+/**
+ * init_timer - initialize a timer.
+ * @timer: the timer to be initialized
+ *
+ * init_timer() must be done to a timer prior calling *any* of the
+ * other timer functions.
+ */
+void init_timer(struct timer_list *timer)
+{
+       debug_timer_init(timer);
+       __init_timer(timer);
+}
 EXPORT_SYMBOL(init_timer);
 
-void fastcall init_timer_deferrable(struct timer_list *timer)
+void init_timer_deferrable(struct timer_list *timer)
 {
        init_timer(timer);
        timer_set_deferrable(timer);
@@ -352,6 +480,8 @@ static inline void detach_timer(struct timer_list *timer,
 {
        struct list_head *entry = &timer->entry;
 
+       debug_timer_deactivate(timer);
+
        __list_del(entry->prev, entry->next);
        if (clear_pending)
                entry->next = NULL;
@@ -370,14 +500,14 @@ static inline void detach_timer(struct timer_list *timer,
  * possible to set timer->base = NULL and drop the lock: the timer remains
  * locked.
  */
-static tvec_base_t *lock_timer_base(struct timer_list *timer,
+static struct tvec_base *lock_timer_base(struct timer_list *timer,
                                        unsigned long *flags)
        __acquires(timer->base->lock)
 {
-       tvec_base_t *base;
+       struct tvec_base *base;
 
        for (;;) {
-               tvec_base_t *prelock_base = timer->base;
+               struct tvec_base *prelock_base = timer->base;
                base = tbase_get_base(prelock_base);
                if (likely(base != NULL)) {
                        spin_lock_irqsave(&base->lock, *flags);
@@ -392,7 +522,7 @@ static tvec_base_t *lock_timer_base(struct timer_list *timer,
 
 int __mod_timer(struct timer_list *timer, unsigned long expires)
 {
-       tvec_base_t *base, *new_base;
+       struct tvec_base *base, *new_base;
        unsigned long flags;
        int ret = 0;
 
@@ -406,6 +536,8 @@ int __mod_timer(struct timer_list *timer, unsigned long expires)
                ret = 1;
        }
 
+       debug_timer_activate(timer);
+
        new_base = __get_cpu_var(tvec_bases);
 
        if (base != new_base) {
@@ -444,18 +576,27 @@ EXPORT_SYMBOL(__mod_timer);
  */
 void add_timer_on(struct timer_list *timer, int cpu)
 {
-       tvec_base_t *base = per_cpu(tvec_bases, cpu);
-       unsigned long flags;
+       struct tvec_base *base = per_cpu(tvec_bases, cpu);
+       unsigned long flags;
 
        timer_stats_timer_set_start_info(timer);
-       BUG_ON(timer_pending(timer) || !timer->function);
+       BUG_ON(timer_pending(timer) || !timer->function);
        spin_lock_irqsave(&base->lock, flags);
        timer_set_base(timer, base);
+       debug_timer_activate(timer);
        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
+        * 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.
+        */
+       wake_up_idle_cpu(cpu);
        spin_unlock_irqrestore(&base->lock, flags);
 }
 
-
 /**
  * mod_timer - modify a timer's timeout
  * @timer: the timer to be modified
@@ -507,7 +648,7 @@ EXPORT_SYMBOL(mod_timer);
  */
 int del_timer(struct timer_list *timer)
 {
-       tvec_base_t *base;
+       struct tvec_base *base;
        unsigned long flags;
        int ret = 0;
 
@@ -538,7 +679,7 @@ EXPORT_SYMBOL(del_timer);
  */
 int try_to_del_timer_sync(struct timer_list *timer)
 {
-       tvec_base_t *base;
+       struct tvec_base *base;
        unsigned long flags;
        int ret = -1;
 
@@ -590,7 +731,7 @@ int del_timer_sync(struct timer_list *timer)
 EXPORT_SYMBOL(del_timer_sync);
 #endif
 
-static int cascade(tvec_base_t *base, tvec_t *tv, int index)
+static int cascade(struct tvec_base *base, struct tvec *tv, int index)
 {
        /* cascade all the timers from tv up one level */
        struct timer_list *timer, *tmp;
@@ -619,7 +760,7 @@ static int cascade(tvec_base_t *base, tvec_t *tv, int index)
  * This function cascades all vectors and executes all expired timer
  * vectors.
  */
-static inline void __run_timers(tvec_base_t *base)
+static inline void __run_timers(struct tvec_base *base)
 {
        struct timer_list *timer;
 
@@ -627,7 +768,7 @@ static inline void __run_timers(tvec_base_t *base)
        while (time_after_eq(jiffies, base->timer_jiffies)) {
                struct list_head work_list;
                struct list_head *head = &work_list;
-               int index = base->timer_jiffies & TVR_MASK;
+               int index = base->timer_jiffies & TVR_MASK;
 
                /*
                 * Cascade timers:
@@ -644,8 +785,8 @@ static inline void __run_timers(tvec_base_t *base)
                        unsigned long data;
 
                        timer = list_first_entry(head, struct timer_list,entry);
-                       fn = timer->function;
-                       data = timer->data;
+                       fn = timer->function;
+                       data = timer->data;
 
                        timer_stats_account_timer(timer);
 
@@ -656,7 +797,7 @@ static inline void __run_timers(tvec_base_t *base)
                                int preempt_count = preempt_count();
                                fn(data);
                                if (preempt_count != preempt_count()) {
-                                       printk(KERN_WARNING "huh, entered %p "
+                                       printk(KERN_ERR "huh, entered %p "
                                               "with preempt_count %08x, exited"
                                               " with %08x?\n",
                                               fn, preempt_count,
@@ -671,26 +812,26 @@ static inline void __run_timers(tvec_base_t *base)
        spin_unlock_irq(&base->lock);
 }
 
-#if defined(CONFIG_NO_IDLE_HZ) || defined(CONFIG_NO_HZ)
+#ifdef CONFIG_NO_HZ
 /*
  * Find out when the next timer event is due to happen. This
  * is used on S/390 to stop all activity when a cpus is idle.
  * This functions needs to be called disabled.
  */
-static unsigned long __next_timer_interrupt(tvec_base_t *base)
+static unsigned long __next_timer_interrupt(struct tvec_base *base)
 {
        unsigned long timer_jiffies = base->timer_jiffies;
        unsigned long expires = timer_jiffies + NEXT_TIMER_MAX_DELTA;
        int index, slot, array, found = 0;
        struct timer_list *nte;
-       tvec_t *varray[4];
+       struct tvec *varray[4];
 
        /* Look for timer events in tv1. */
        index = slot = timer_jiffies & TVR_MASK;
        do {
                list_for_each_entry(nte, base->tv1.vec + slot, entry) {
-                       if (tbase_get_deferrable(nte->base))
-                               continue;
+                       if (tbase_get_deferrable(nte->base))
+                               continue;
 
                        found = 1;
                        expires = nte->expires;
@@ -715,7 +856,7 @@ cascade:
        varray[3] = &base->tv5;
 
        for (array = 0; array < 4; array++) {
-               tvec_t *varp = varray[array];
+               struct tvec *varp = varray[array];
 
                index = slot = timer_jiffies & TVN_MASK;
                do {
@@ -789,12 +930,12 @@ static unsigned long cmp_next_hrtimer_event(unsigned long now,
 }
 
 /**
- * next_timer_interrupt - return the jiffy of the next pending timer
+ * get_next_timer_interrupt - return the jiffy of the next pending timer
  * @now: current time (in jiffies)
  */
 unsigned long get_next_timer_interrupt(unsigned long now)
 {
-       tvec_base_t *base = __get_cpu_var(tvec_bases);
+       struct tvec_base *base = __get_cpu_var(tvec_bases);
        unsigned long expires;
 
        spin_lock(&base->lock);
@@ -806,18 +947,25 @@ unsigned long get_next_timer_interrupt(unsigned long now)
 
        return cmp_next_hrtimer_event(now, expires);
 }
+#endif
 
-#ifdef CONFIG_NO_IDLE_HZ
-unsigned long next_timer_interrupt(void)
+#ifndef CONFIG_VIRT_CPU_ACCOUNTING
+void account_process_tick(struct task_struct *p, int user_tick)
 {
-       return get_next_timer_interrupt(jiffies);
-}
-#endif
+       cputime_t one_jiffy = jiffies_to_cputime(1);
 
+       if (user_tick) {
+               account_user_time(p, one_jiffy);
+               account_user_time_scaled(p, cputime_to_scaled(one_jiffy));
+       } else {
+               account_system_time(p, HARDIRQ_OFFSET, one_jiffy);
+               account_system_time_scaled(p, cputime_to_scaled(one_jiffy));
+       }
+}
 #endif
 
 /*
- * Called from the timer interrupt handler to charge one tick to the current 
+ * Called from the timer interrupt handler to charge one tick to the current
  * process.  user_tick is 1 if the tick is user time, 0 for system.
  */
 void update_process_times(int user_tick)
@@ -826,15 +974,13 @@ void update_process_times(int user_tick)
        int cpu = smp_processor_id();
 
        /* Note: this timer irq context must be accounted for as well. */
-       if (user_tick)
-               account_user_time(p, jiffies_to_cputime(1));
-       else
-               account_system_time(p, HARDIRQ_OFFSET, jiffies_to_cputime(1));
+       account_process_tick(p, user_tick);
        run_local_timers();
        if (rcu_pending(cpu))
                rcu_check_callbacks(cpu, user_tick);
+       printk_tick();
        scheduler_tick();
-       run_posix_cpu_timers(p);
+       run_posix_cpu_timers(p);
 }
 
 /*
@@ -883,9 +1029,9 @@ static inline void calc_load(unsigned long ticks)
  */
 static void run_timer_softirq(struct softirq_action *h)
 {
-       tvec_base_t *base = __get_cpu_var(tvec_bases);
+       struct tvec_base *base = __get_cpu_var(tvec_bases);
 
-       hrtimer_run_queues();
+       hrtimer_run_pending();
 
        if (time_after_eq(jiffies, base->timer_jiffies))
                __run_timers(base);
@@ -896,6 +1042,7 @@ static void run_timer_softirq(struct softirq_action *h)
  */
 void run_local_timers(void)
 {
+       hrtimer_run_queues();
        raise_softirq(TIMER_SOFTIRQ);
        softlockup_tick();
 }
@@ -909,7 +1056,7 @@ static inline void update_times(unsigned long ticks)
        update_wall_time();
        calc_load(ticks);
 }
-  
+
 /*
  * The 64-bit jiffies value is not atomic - you MUST NOT read it
  * without sampling the sequence number in xtime_lock.
@@ -953,7 +1100,7 @@ asmlinkage unsigned long sys_alarm(unsigned int seconds)
  */
 asmlinkage long sys_getpid(void)
 {
-       return current->tgid;
+       return task_tgid_vnr(current);
 }
 
 /*
@@ -967,7 +1114,7 @@ asmlinkage long sys_getppid(void)
        int pid;
 
        rcu_read_lock();
-       pid = rcu_dereference(current->real_parent)->tgid;
+       pid = task_tgid_vnr(current->real_parent);
        rcu_read_unlock();
 
        return pid;
@@ -1030,7 +1177,7 @@ static void process_timeout(unsigned long __data)
  *
  * In all cases the return value is guaranteed to be non-negative.
  */
-fastcall signed long __sched schedule_timeout(signed long timeout)
+signed long __sched schedule_timeout(signed long timeout)
 {
        struct timer_list timer;
        unsigned long expire;
@@ -1066,11 +1213,14 @@ fastcall signed long __sched schedule_timeout(signed long timeout)
 
        expire = timeout + jiffies;
 
-       setup_timer(&timer, process_timeout, (unsigned long)current);
+       setup_timer_on_stack(&timer, process_timeout, (unsigned long)current);
        __mod_timer(&timer, expire);
        schedule();
        del_singleshot_timer_sync(&timer);
 
+       /* Remove the timer from the object tracker */
+       destroy_timer_on_stack(&timer);
+
        timeout = expire - jiffies;
 
  out:
@@ -1089,6 +1239,13 @@ signed long __sched schedule_timeout_interruptible(signed long timeout)
 }
 EXPORT_SYMBOL(schedule_timeout_interruptible);
 
+signed long __sched schedule_timeout_killable(signed long timeout)
+{
+       __set_current_state(TASK_KILLABLE);
+       return schedule_timeout(timeout);
+}
+EXPORT_SYMBOL(schedule_timeout_killable);
+
 signed long __sched schedule_timeout_uninterruptible(signed long timeout)
 {
        __set_current_state(TASK_UNINTERRUPTIBLE);
@@ -1099,13 +1256,13 @@ EXPORT_SYMBOL(schedule_timeout_uninterruptible);
 /* Thread ID - the internal kernel "pid" */
 asmlinkage long sys_gettid(void)
 {
-       return current->pid;
+       return task_pid_vnr(current);
 }
 
 /**
  * do_sysinfo - fill in sysinfo struct
  * @info: pointer to buffer to fill
- */ 
+ */
 int do_sysinfo(struct sysinfo *info)
 {
        unsigned long mem_total, sav_total;
@@ -1201,18 +1358,11 @@ asmlinkage long sys_sysinfo(struct sysinfo __user *info)
        return 0;
 }
 
-/*
- * lockdep: we want to track each per-CPU base as a separate lock-class,
- * but timer-bases are kmalloc()-ed, so we need to attach separate
- * keys to them:
- */
-static struct lock_class_key base_lock_keys[NR_CPUS];
-
-static int __devinit init_timers_cpu(int cpu)
+static int __cpuinit init_timers_cpu(int cpu)
 {
        int j;
-       tvec_base_t *base;
-       static char __devinitdata tvec_base_done[NR_CPUS];
+       struct tvec_base *base;
+       static char __cpuinitdata tvec_base_done[NR_CPUS];
 
        if (!tvec_base_done[cpu]) {
                static char boot_done;
@@ -1221,7 +1371,8 @@ static int __devinit init_timers_cpu(int cpu)
                        /*
                         * The APs use this path later in boot
                         */
-                       base = kmalloc_node(sizeof(*base), GFP_KERNEL,
+                       base = kmalloc_node(sizeof(*base),
+                                               GFP_KERNEL | __GFP_ZERO,
                                                cpu_to_node(cpu));
                        if (!base)
                                return -ENOMEM;
@@ -1232,7 +1383,6 @@ static int __devinit init_timers_cpu(int cpu)
                                kfree(base);
                                return -ENOMEM;
                        }
-                       memset(base, 0, sizeof(*base));
                        per_cpu(tvec_bases, cpu) = base;
                } else {
                        /*
@@ -1250,7 +1400,6 @@ static int __devinit init_timers_cpu(int cpu)
        }
 
        spin_lock_init(&base->lock);
-       lockdep_set_class(&base->lock, base_lock_keys + cpu);
 
        for (j = 0; j < TVN_SIZE; j++) {
                INIT_LIST_HEAD(base->tv5.vec + j);
@@ -1266,7 +1415,7 @@ static int __devinit init_timers_cpu(int cpu)
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-static void migrate_timer_list(tvec_base_t *new_base, struct list_head *head)
+static void migrate_timer_list(struct tvec_base *new_base, struct list_head *head)
 {
        struct timer_list *timer;
 
@@ -1278,10 +1427,10 @@ static void migrate_timer_list(tvec_base_t *new_base, struct list_head *head)
        }
 }
 
-static void __devinit migrate_timers(int cpu)
+static void __cpuinit migrate_timers(int cpu)
 {
-       tvec_base_t *old_base;
-       tvec_base_t *new_base;
+       struct tvec_base *old_base;
+       struct tvec_base *new_base;
        int i;
 
        BUG_ON(cpu_online(cpu));
@@ -1289,8 +1438,8 @@ static void __devinit migrate_timers(int cpu)
        new_base = get_cpu_var(tvec_bases);
 
        local_irq_disable();
-       double_spin_lock(&new_base->lock, &old_base->lock,
-                        smp_processor_id() < cpu);
+       spin_lock(&new_base->lock);
+       spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING);
 
        BUG_ON(old_base->running_timer);
 
@@ -1303,8 +1452,8 @@ static void __devinit migrate_timers(int cpu)
                migrate_timer_list(new_base, old_base->tv5.vec + i);
        }
 
-       double_spin_unlock(&new_base->lock, &old_base->lock,
-                          smp_processor_id() < cpu);
+       spin_unlock(&old_base->lock);
+       spin_unlock(&new_base->lock);
        local_irq_enable();
        put_cpu_var(tvec_bases);
 }
@@ -1346,196 +1495,8 @@ void __init init_timers(void)
 
        BUG_ON(err == NOTIFY_BAD);
        register_cpu_notifier(&timers_nb);
-       open_softirq(TIMER_SOFTIRQ, run_timer_softirq, NULL);
-}
-
-#ifdef CONFIG_TIME_INTERPOLATION
-
-struct time_interpolator *time_interpolator __read_mostly;
-static struct time_interpolator *time_interpolator_list __read_mostly;
-static DEFINE_SPINLOCK(time_interpolator_lock);
-
-static inline cycles_t time_interpolator_get_cycles(unsigned int src)
-{
-       unsigned long (*x)(void);
-
-       switch (src)
-       {
-               case TIME_SOURCE_FUNCTION:
-                       x = time_interpolator->addr;
-                       return x();
-
-               case TIME_SOURCE_MMIO64 :
-                       return readq_relaxed((void __iomem *)time_interpolator->addr);
-
-               case TIME_SOURCE_MMIO32 :
-                       return readl_relaxed((void __iomem *)time_interpolator->addr);
-
-               default: return get_cycles();
-       }
-}
-
-static inline u64 time_interpolator_get_counter(int writelock)
-{
-       unsigned int src = time_interpolator->source;
-
-       if (time_interpolator->jitter)
-       {
-               cycles_t lcycle;
-               cycles_t now;
-
-               do {
-                       lcycle = time_interpolator->last_cycle;
-                       now = time_interpolator_get_cycles(src);
-                       if (lcycle && time_after(lcycle, now))
-                               return lcycle;
-
-                       /* When holding the xtime write lock, there's no need
-                        * to add the overhead of the cmpxchg.  Readers are
-                        * force to retry until the write lock is released.
-                        */
-                       if (writelock) {
-                               time_interpolator->last_cycle = now;
-                               return now;
-                       }
-                       /* Keep track of the last timer value returned. The use of cmpxchg here
-                        * will cause contention in an SMP environment.
-                        */
-               } while (unlikely(cmpxchg(&time_interpolator->last_cycle, lcycle, now) != lcycle));
-               return now;
-       }
-       else
-               return time_interpolator_get_cycles(src);
-}
-
-void time_interpolator_reset(void)
-{
-       time_interpolator->offset = 0;
-       time_interpolator->last_counter = time_interpolator_get_counter(1);
-}
-
-#define GET_TI_NSECS(count,i) (((((count) - i->last_counter) & (i)->mask) * (i)->nsec_per_cyc) >> (i)->shift)
-
-unsigned long time_interpolator_get_offset(void)
-{
-       /* If we do not have a time interpolator set up then just return zero */
-       if (!time_interpolator)
-               return 0;
-
-       return time_interpolator->offset +
-               GET_TI_NSECS(time_interpolator_get_counter(0), time_interpolator);
-}
-
-#define INTERPOLATOR_ADJUST 65536
-#define INTERPOLATOR_MAX_SKIP 10*INTERPOLATOR_ADJUST
-
-void time_interpolator_update(long delta_nsec)
-{
-       u64 counter;
-       unsigned long offset;
-
-       /* If there is no time interpolator set up then do nothing */
-       if (!time_interpolator)
-               return;
-
-       /*
-        * The interpolator compensates for late ticks by accumulating the late
-        * time in time_interpolator->offset. A tick earlier than expected will
-        * lead to a reset of the offset and a corresponding jump of the clock
-        * forward. Again this only works if the interpolator clock is running
-        * slightly slower than the regular clock and the tuning logic insures
-        * that.
-        */
-
-       counter = time_interpolator_get_counter(1);
-       offset = time_interpolator->offset +
-                       GET_TI_NSECS(counter, time_interpolator);
-
-       if (delta_nsec < 0 || (unsigned long) delta_nsec < offset)
-               time_interpolator->offset = offset - delta_nsec;
-       else {
-               time_interpolator->skips++;
-               time_interpolator->ns_skipped += delta_nsec - offset;
-               time_interpolator->offset = 0;
-       }
-       time_interpolator->last_counter = counter;
-
-       /* Tuning logic for time interpolator invoked every minute or so.
-        * Decrease interpolator clock speed if no skips occurred and an offset is carried.
-        * Increase interpolator clock speed if we skip too much time.
-        */
-       if (jiffies % INTERPOLATOR_ADJUST == 0)
-       {
-               if (time_interpolator->skips == 0 && time_interpolator->offset > tick_nsec)
-                       time_interpolator->nsec_per_cyc--;
-               if (time_interpolator->ns_skipped > INTERPOLATOR_MAX_SKIP && time_interpolator->offset == 0)
-                       time_interpolator->nsec_per_cyc++;
-               time_interpolator->skips = 0;
-               time_interpolator->ns_skipped = 0;
-       }
-}
-
-static inline int
-is_better_time_interpolator(struct time_interpolator *new)
-{
-       if (!time_interpolator)
-               return 1;
-       return new->frequency > 2*time_interpolator->frequency ||
-           (unsigned long)new->drift < (unsigned long)time_interpolator->drift;
-}
-
-void
-register_time_interpolator(struct time_interpolator *ti)
-{
-       unsigned long flags;
-
-       /* Sanity check */
-       BUG_ON(ti->frequency == 0 || ti->mask == 0);
-
-       ti->nsec_per_cyc = ((u64)NSEC_PER_SEC << ti->shift) / ti->frequency;
-       spin_lock(&time_interpolator_lock);
-       write_seqlock_irqsave(&xtime_lock, flags);
-       if (is_better_time_interpolator(ti)) {
-               time_interpolator = ti;
-               time_interpolator_reset();
-       }
-       write_sequnlock_irqrestore(&xtime_lock, flags);
-
-       ti->next = time_interpolator_list;
-       time_interpolator_list = ti;
-       spin_unlock(&time_interpolator_lock);
-}
-
-void
-unregister_time_interpolator(struct time_interpolator *ti)
-{
-       struct time_interpolator *curr, **prev;
-       unsigned long flags;
-
-       spin_lock(&time_interpolator_lock);
-       prev = &time_interpolator_list;
-       for (curr = *prev; curr; curr = curr->next) {
-               if (curr == ti) {
-                       *prev = curr->next;
-                       break;
-               }
-               prev = &curr->next;
-       }
-
-       write_seqlock_irqsave(&xtime_lock, flags);
-       if (ti == time_interpolator) {
-               /* we lost the best time-interpolator: */
-               time_interpolator = NULL;
-               /* find the next-best interpolator */
-               for (curr = time_interpolator_list; curr; curr = curr->next)
-                       if (is_better_time_interpolator(curr))
-                               time_interpolator = curr;
-               time_interpolator_reset();
-       }
-       write_sequnlock_irqrestore(&xtime_lock, flags);
-       spin_unlock(&time_interpolator_lock);
+       open_softirq(TIMER_SOFTIRQ, run_timer_softirq);
 }
-#endif /* CONFIG_TIME_INTERPOLATION */
 
 /**
  * msleep - sleep safely even with waitqueue interruptions