diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-02-26 18:39:21 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-02-28 17:46:24 -0500 |
commit | 01e04f466e12e883907937eb04a9010533363f55 (patch) | |
tree | 3c10e3c6c051d508bdf655d5e06162b328ffe7cf /drivers/cpuidle/cpuidle.c | |
parent | c517d838eb7d07bbe9507871fab3931deccff539 (diff) |
idle / sleep: Avoid excessive disabling and enabling interrupts
Disabling interrupts at the end of cpuidle_enter_freeze() is not
useful, because its caller, cpuidle_idle_call(), re-enables them
right away after invoking it.
To avoid that unnecessary back and forth dance with interrupts,
make cpuidle_enter_freeze() enable interrupts after calling
enter_freeze_proper() and drop the local_irq_disable() at its
end, so that all of the code paths in it end up with interrupts
enabled. Then, cpuidle_idle_call() will not need to re-enable
interrupts after calling cpuidle_enter_freeze() any more, because
the latter will return with interrupts enabled, in analogy with
cpuidle_enter().
Reported-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Diffstat (limited to 'drivers/cpuidle/cpuidle.c')
-rw-r--r-- | drivers/cpuidle/cpuidle.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 4d534582514e..b573f584b15a 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
@@ -117,6 +117,8 @@ static void enter_freeze_proper(struct cpuidle_driver *drv, | |||
117 | * If there are states with the ->enter_freeze callback, find the deepest of | 117 | * If there are states with the ->enter_freeze callback, find the deepest of |
118 | * them and enter it with frozen tick. Otherwise, find the deepest state | 118 | * them and enter it with frozen tick. Otherwise, find the deepest state |
119 | * available and enter it normally. | 119 | * available and enter it normally. |
120 | * | ||
121 | * Returns with enabled interrupts. | ||
120 | */ | 122 | */ |
121 | void cpuidle_enter_freeze(void) | 123 | void cpuidle_enter_freeze(void) |
122 | { | 124 | { |
@@ -132,6 +134,7 @@ void cpuidle_enter_freeze(void) | |||
132 | index = cpuidle_find_deepest_state(drv, dev, true); | 134 | index = cpuidle_find_deepest_state(drv, dev, true); |
133 | if (index >= 0) { | 135 | if (index >= 0) { |
134 | enter_freeze_proper(drv, dev, index); | 136 | enter_freeze_proper(drv, dev, index); |
137 | local_irq_enable(); | ||
135 | return; | 138 | return; |
136 | } | 139 | } |
137 | 140 | ||
@@ -144,9 +147,6 @@ void cpuidle_enter_freeze(void) | |||
144 | cpuidle_enter(drv, dev, index); | 147 | cpuidle_enter(drv, dev, index); |
145 | else | 148 | else |
146 | arch_cpu_idle(); | 149 | arch_cpu_idle(); |
147 | |||
148 | /* Interrupts are enabled again here. */ | ||
149 | local_irq_disable(); | ||
150 | } | 150 | } |
151 | 151 | ||
152 | /** | 152 | /** |