Commit:     f8953856eb8dd62232aee6cacb46993dc2ac4869
Parent:     d1d67174b42a02c7d106894df0ed155d595871f7
Author:     Thomas Gleixner <[EMAIL PROTECTED]>
AuthorDate: Tue Mar 6 01:42:08 2007 -0800
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Tue Mar 6 09:30:25 2007 -0800

    [PATCH] highres: do not run the TIMER_SOFTIRQ after switching to highres 
    The TIMER_SOFTIRQ runs the hrtimers during bootup until a usable
    clocksource and clock event sources are registered.  The switch to high
    resolution mode happens inside of the TIMER_SOFTIRQ, but runs the softirq
    afterwards.  That way the tick emulation timer, which was set up in the
    switch to highres might be executed in the softirq context, which is a BUG.
     The rbtree has not to be touched by the softirq after the highres switch.
    This BUG was observed by Andres Salomon, who provided the information to
    debug it.
    Return early from the softirq, when the switch was sucessful.
    [EMAIL PROTECTED]: add debug warning]
    [EMAIL PROTECTED]: make debug warning compile]
    Signed-off-by: Thomas Gleixner <[EMAIL PROTECTED]>
    Cc: Andres Salomon <[EMAIL PROTECTED]>
    Acked-by: Ingo Molnar <[EMAIL PROTECTED]>
    Signed-off-by: Andres Salomon <[EMAIL PROTECTED]>
    Acked-by: Thomas Gleixner <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
 kernel/hrtimer.c |   15 ++++++++++-----
 1 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index de93a81..ec4cb9f 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -540,19 +540,19 @@ static inline int hrtimer_enqueue_reprogram(struct 
hrtimer *timer,
  * Switch to high resolution mode
-static void hrtimer_switch_to_hres(void)
+static int hrtimer_switch_to_hres(void)
        struct hrtimer_cpu_base *base = &__get_cpu_var(hrtimer_bases);
        unsigned long flags;
        if (base->hres_active)
-               return;
+               return 1;
        if (tick_init_highres()) {
-               return;
+               return 0;
        base->hres_active = 1;
        base->clock_base[CLOCK_REALTIME].resolution = KTIME_HIGH_RES;
@@ -565,13 +565,14 @@ static void hrtimer_switch_to_hres(void)
        printk(KERN_INFO "Switched to high resolution mode on CPU %d\n",
+       return 1;
 static inline int hrtimer_hres_active(void) { return 0; }
 static inline int hrtimer_is_hres_enabled(void) { return 0; }
-static inline void hrtimer_switch_to_hres(void) { }
+static inline int hrtimer_switch_to_hres(void) { return 0; }
 static inline void hrtimer_force_reprogram(struct hrtimer_cpu_base *base) { }
 static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer,
                                            struct hrtimer_clock_base *base)
@@ -1130,6 +1131,9 @@ static inline void run_hrtimer_queue(struct 
hrtimer_cpu_base *cpu_base,
                if (base->softirq_time.tv64 <= timer->expires.tv64)
+               WARN_ON_ONCE(timer->cb_mode == HRTIMER_CB_IRQSAFE_NO_SOFTIRQ);
                fn = timer->function;
@@ -1173,7 +1177,8 @@ void hrtimer_run_queues(void)
         * deadlock vs. xtime_lock.
        if (tick_check_oneshot_change(!hrtimer_is_hres_enabled()))
-               hrtimer_switch_to_hres();
+               if (hrtimer_switch_to_hres())
+                       return;
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at

Reply via email to