cpuidle: Run tick_broadcast_exit() with disabled interrupts
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 29 Apr 2015 13:19:21 +0000 (15:19 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 29 Apr 2015 13:19:21 +0000 (15:19 +0200)
commitdf8d9eeadd0f7a216f2476351d5aee43c6550bf0
tree5290522027dd4acd6912c69446ad181c2aff4324
parentb787f68c36d49bb1d9236f403813641efa74a031
cpuidle: Run tick_broadcast_exit() with disabled interrupts

Commit 335f49196fd6 (sched/idle: Use explicit broadcast oneshot
control function) replaced clockevents_notify() invocations in
cpuidle_idle_call() with direct calls to tick_broadcast_enter()
and tick_broadcast_exit(), but it overlooked the fact that
interrupts were already enabled before calling the latter which
led to functional breakage on systems using idle states with the
CPUIDLE_FLAG_TIMER_STOP flag set.

Fix that by moving the invocations of tick_broadcast_enter()
and tick_broadcast_exit() down into cpuidle_enter_state() where
interrupts are still disabled when tick_broadcast_exit() is
called.  Also ensure that interrupts will be disabled before
running tick_broadcast_exit() even if they have been enabled by
the idle state's ->enter callback.  Trigger a WARN_ON_ONCE() in
that case, as we generally don't want that to happen for states
with CPUIDLE_FLAG_TIMER_STOP set.

Fixes: 335f49196fd6 (sched/idle: Use explicit broadcast oneshot control function)
Reported-and-tested-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Reported-and-tested-by: Sudeep Holla <sudeep.holla@arm.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/cpuidle/cpuidle.c
kernel/sched/idle.c