• Tejun Heo's avatar
    timers: Use proper base migration in add_timer_on() · 861afec5
    Tejun Heo authored
    commit 22b886dd upstream.
    
    Regardless of the previous CPU a timer was on, add_timer_on()
    currently simply sets timer->flags to the new CPU.  As the caller must
    be seeing the timer as idle, this is locally fine, but the timer
    leaving the old base while unlocked can lead to race conditions as
    follows.
    
    Let's say timer was on cpu 0.
    
      cpu 0					cpu 1
      -----------------------------------------------------------------------------
      del_timer(timer) succeeds
    					del_timer(timer)
    					  lock_timer_base(timer) locks cpu_0_base
      add_timer_on(timer, 1)
        spin_lock(&cpu_1_base->lock)
        timer->flags set to cpu_1_base
        operates on @timer			  operates on @timer
    
    This triggered with mod_delayed_work_on() which contains
    "if (del_timer()) add_timer_on()" sequence eventually leading to the
    following oops.
    
      BUG: unable to handle kernel NULL pointer dereference at           (null)
      IP: [<ffffffff810ca6e9>] detach_if_pending+0x69/0x1a0
      ...
      Workqueue: wqthrash wqthrash_workfunc [wqthrash]
      task: ffff8800172ca680 ti: ffff8800172d0000 task.ti: ffff8800172d0000
      RIP: 0010:[<ffffffff810ca6e9>]  [<ffffffff810ca6e9>] detach_if_pending+0x69/0x1a0
      ...
      Call Trace:
       [<ffffffff810cb0b4>] del_timer+0x44/0x60
       [<ffffffff8106e836>] try_to_grab_pending+0xb6/0x160
       [<ffffffff8106e913>] mod_delayed_work_on+0x33/0x80
       [<ffffffffa0000081>] wqthrash_workfunc+0x61/0x90 [wqthrash]
       [<ffffffff8106dba8>] process_one_work+0x1e8/0x650
       [<ffffffff8106e05e>] worker_thread+0x4e/0x450
       [<ffffffff810746af>] kthread+0xef/0x110
       [<ffffffff8185980f>] ret_from_fork+0x3f/0x70
    
    Fix it by updating add_timer_on() to perform proper migration as
    __mod_timer() does.
    Reported-and-tested-by: default avatarJeff Layton <jlayton@poochiereds.net>
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Cc: Chris Worley <chris.worley@primarydata.com>
    Cc: bfields@fieldses.org
    Cc: Michael Skralivetsky <michael.skralivetsky@primarydata.com>
    Cc: Trond Myklebust <trond.myklebust@primarydata.com>
    Cc: Shaohua Li <shli@fb.com>
    Cc: Jeff Layton <jlayton@poochiereds.net>
    Cc: kernel-team@fb.com
    Link: http://lkml.kernel.org/r/20151029103113.2f893924@tlielax.poochiereds.net
    Link: http://lkml.kernel.org/r/20151104171533.GI5749@mtj.duckdns.orgSigned-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Signed-off-by: default avatarKamal Mostafa <kamal@canonical.com>
    861afec5
timer.c 46.4 KB