• Salman Qazi's avatar
    hrtimer: Preserve timer state in remove_hrtimer() · f13d4f97
    Salman Qazi authored
    The race is described as follows:
    
    CPU X                                 CPU Y
    remove_hrtimer
    // state & QUEUED == 0
    timer->state = CALLBACK
    unlock timer base
    timer->f(n) //very long
                                      hrtimer_start
                                        lock timer base
                                        remove_hrtimer // no effect
                                        hrtimer_enqueue
                                        timer->state = CALLBACK |
                                                       QUEUED
                                        unlock timer base
                                      hrtimer_start
                                        lock timer base
                                        remove_hrtimer
                                            mode = INACTIVE
                                            // CALLBACK bit lost!
                                        switch_hrtimer_base
                                                CALLBACK bit not set:
                                                        timer->base
                                                        changes to a
                                                        different CPU.
    lock this CPU's timer base
    
    The bug was introduced with commit ca109491 (hrtimer: removing all ur
    callback modes) in 2.6.29
    
    [ tglx: Feed new state via local variable and add a comment. ]
    Signed-off-by: default avatarSalman Qazi <sqazi@google.com>
    Cc: akpm@linux-foundation.org
    Cc: Peter Zijlstra <peterz@infradead.org>
    LKML-Reference: <20101012142351.8485.21823.stgit@dungbeetle.mtv.corp.google.com>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Cc: stable@kernel.org
    f13d4f97
hrtimer.c 46 KB