• Thomas Gleixner's avatar
    tick: Prevent uncontrolled switch to oneshot mode · 1f73a980
    Thomas Gleixner authored
    When the system switches from periodic to oneshot mode, the broadcast
    logic causes a possibility that a CPU which has not yet switched to
    oneshot mode puts its own clock event device into oneshot mode without
    updating the state and the timer handler.
    
    CPU0				CPU1
    				per cpu tickdev is in periodic mode
    				and switched to broadcast
    
    Switch to oneshot mode
     tick_broadcast_switch_to_oneshot()
      cpumask_copy(tick_oneshot_broacast_mask,
    	       tick_broadcast_mask);
    
      broadcast device mode = oneshot
    
    				Timer interrupt
    						
    				irq_enter()
    				 tick_check_oneshot_broadcast()
    				  dev->set_mode(ONESHOT);
    
    				tick_handle_periodic()
    				 if (dev->mode == ONESHOT)
    				   dev->next_event += period;
    				   FAIL.
    
    We fail, because dev->next_event contains KTIME_MAX, if the device was
    in periodic mode before the uncontrolled switch to oneshot happened.
    
    We must copy the broadcast bits over to the oneshot mask, because
    otherwise a CPU which relies on the broadcast would not been woken up
    anymore after the broadcast device switched to oneshot mode.
    
    So we need to verify in tick_check_oneshot_broadcast() whether the CPU
    has already switched to oneshot mode. If not, leave the device
    untouched and let the CPU switch controlled into oneshot mode.
    
    This is a long standing bug, which was never noticed, because the main
    user of the broadcast x86 cannot run into that scenario, AFAICT. The
    nonarchitected timer mess of ARM creates a gazillion of differently
    broken abominations which trigger the shortcomings of that broadcast
    code, which better had never been necessary in the first place.
    Reported-and-tested-by: default avatarStehle Vincent-B46079 <B46079@freescale.com>
    Reviewed-by: default avatarStephen Boyd <sboyd@codeaurora.org>
    Cc: John Stultz <john.stultz@linaro.org>,
    Cc: Mark Rutland <mark.rutland@arm.com>
    Link: http://lkml.kernel.org/r/alpine.DEB.2.02.1307012153060.4013@ionos.tec.linutronix.de
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    1f73a980
tick-broadcast.c 21.3 KB