• Eric Dumazet's avatar
    timer: Write timer->flags atomically · d0023a14
    Eric Dumazet authored
    lock_timer_base() cannot prevent the following :
    
    CPU1 ( in __mod_timer()
    timer->flags |= TIMER_MIGRATING;
    spin_unlock(&base->lock);
    base = new_base;
    spin_lock(&base->lock);
    // The next line clears TIMER_MIGRATING
    timer->flags &= ~TIMER_BASEMASK;
                                      CPU2 (in lock_timer_base())
                                      see timer base is cpu0 base
                                      spin_lock_irqsave(&base->lock, *flags);
                                      if (timer->flags == tf)
                                           return base; // oops, wrong base
    timer->flags |= base->cpu // too late
    
    We must write timer->flags in one go, otherwise we can fool other cpus.
    
    Fixes: bc7a34b8 ("timer: Reduce timer migration overhead if disabled")
    Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
    Cc: Jon Christopherson <jon@jons.org>
    Cc: David Miller <davem@davemloft.net>
    Cc: xen-devel@lists.xen.org
    Cc: david.vrabel@citrix.com
    Cc: Sander Eikelenboom <linux@eikelenboom.it>
    Link: http://lkml.kernel.org/r/1439831928.32680.11.camel@edumazet-glaptop2.roam.corp.google.comSigned-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    d0023a14
timer.c 46.1 KB