Merge git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 28 Apr 2008 20:47:21 +0000 (13:47 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 28 Apr 2008 20:47:21 +0000 (13:47 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq:
  [CPUFREQ] Make acpi-cpufreq more robust against BIOS freq changes behind our back.
  [CPUFREQ] change cpu freq tables to per_cpu variables
  [CPUFREQ] fix show_trans_table
  [CPUFREQ] Warn when cpufreq_register_notifier called before pure initcalls
  [CPUFREQ] Refactor locking in cpufreq_add_dev
  [CPUFREQ] more CodingStyle
  [CPUFREQ] CodingStyle
  [CPUFREQ] Slightly shorten the error paths of cpufreq_suspend/cpufreq_resume

kernel/hrtimer.c
mm/memory_hotplug.c

index e379ef0..dea4c91 100644 (file)
@@ -590,7 +590,6 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer,
                        list_add_tail(&timer->cb_entry,
                                      &base->cpu_base->cb_pending);
                        timer->state = HRTIMER_STATE_PENDING;
-                       raise_softirq(HRTIMER_SOFTIRQ);
                        return 1;
                default:
                        BUG();
@@ -633,6 +632,11 @@ static int hrtimer_switch_to_hres(void)
        return 1;
 }
 
+static inline void hrtimer_raise_softirq(void)
+{
+       raise_softirq(HRTIMER_SOFTIRQ);
+}
+
 #else
 
 static inline int hrtimer_hres_active(void) { return 0; }
@@ -651,6 +655,7 @@ static inline int hrtimer_reprogram(struct hrtimer *timer,
 {
        return 0;
 }
+static inline void hrtimer_raise_softirq(void) { }
 
 #endif /* CONFIG_HIGH_RES_TIMERS */
 
@@ -850,7 +855,7 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
 {
        struct hrtimer_clock_base *base, *new_base;
        unsigned long flags;
-       int ret;
+       int ret, raise;
 
        base = lock_hrtimer_base(timer, &flags);
 
@@ -884,8 +889,18 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
        enqueue_hrtimer(timer, new_base,
                        new_base->cpu_base == &__get_cpu_var(hrtimer_bases));
 
+       /*
+        * The timer may be expired and moved to the cb_pending
+        * list. We can not raise the softirq with base lock held due
+        * to a possible deadlock with runqueue lock.
+        */
+       raise = timer->state == HRTIMER_STATE_PENDING;
+
        unlock_hrtimer_base(timer, &flags);
 
+       if (raise)
+               hrtimer_raise_softirq();
+
        return ret;
 }
 EXPORT_SYMBOL_GPL(hrtimer_start);
index c4ba85c..b17dca7 100644 (file)
@@ -29,6 +29,8 @@
 
 #include <asm/tlbflush.h>
 
+#include "internal.h"
+
 /* add this memory to iomem resource */
 static struct resource *register_memory_resource(u64 start, u64 size)
 {