• H
    nohz: Fix get_next_timer_interrupt() vs cpu hotplug · dbd87b5a
    Heiko Carstens 提交于
    This fixes a bug as seen on 2.6.32 based kernels where timers got
    enqueued on offline cpus.
    
    If a cpu goes offline it might still have pending timers. These will
    be migrated during CPU_DEAD handling after the cpu is offline.
    However while the cpu is going offline it will schedule the idle task
    which will then call tick_nohz_stop_sched_tick().
    
    That function in turn will call get_next_timer_intterupt() to figure
    out if the tick of the cpu can be stopped or not. If it turns out that
    the next tick is just one jiffy off (delta_jiffies == 1)
    tick_nohz_stop_sched_tick() incorrectly assumes that the tick should
    not stop and takes an early exit and thus it won't update the load
    balancer cpu.
    
    Just afterwards the cpu will be killed and the load balancer cpu could
    be the offline cpu.
    
    On 2.6.32 based kernel get_nohz_load_balancer() gets called to decide
    on which cpu a timer should be enqueued (see __mod_timer()). Which
    leads to the possibility that timers get enqueued on an offline cpu.
    These will never expire and can cause a system hang.
    
    This has been observed 2.6.32 kernels. On current kernels
    __mod_timer() uses get_nohz_timer_target() which doesn't have that
    problem. However there might be other problems because of the too
    early exit tick_nohz_stop_sched_tick() in case a cpu goes offline.
    
    The easiest and probably safest fix seems to be to let
    get_next_timer_interrupt() just lie and let it say there isn't any
    pending timer if the current cpu is offline.
    
    I also thought of moving migrate_[hr]timers() from CPU_DEAD to
    CPU_DYING, but seeing that there already have been fixes at least in
    the hrtimer code in this area I'm afraid that this could add new
    subtle bugs.
    Signed-off-by: NHeiko Carstens <heiko.carstens@de.ibm.com>
    Signed-off-by: NPeter Zijlstra <a.p.zijlstra@chello.nl>
    LKML-Reference: <20101201091109.GA8984@osiris.boeblingen.de.ibm.com>
    Cc: stable@kernel.org
    Signed-off-by: NIngo Molnar <mingo@elte.hu>
    dbd87b5a
timer.c 47.7 KB