mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 13:41:51 +00:00
ACPI: acpi_idle: touch TS_POLLING only in the non-MWAIT case
commit d306ebc286
(ACPI: Be in TS_POLLING state during mwait based C-state entry)
fixed an important power & performance issue where ACPI c2 and c3 C-states
were clearing TS_POLLING even when using MWAIT (ACPI_STATE_FFH).
That bug had been causing us to receive redundant scheduling interrups
when we had already been woken up by MONITOR/MWAIT.
Following up on that...
In the MWAIT case, we don't have to subsequently
check need_resched(), as that c heck was there
for the TS_POLLING-clearing case.
Note that not only does the cpuidle calling function
already check need_resched() before calling us, the
low-level entry into monitor/mwait calls it twice --
guaranteeing that a write to the trigger address
can not go un-noticed.
Also, in this case, we don't have to set TS_POLLING
when we wake, because we never cleared it.
Signed-off-by: Len Brown <len.brown@intel.com>
Acked-by: Venkatesh Pallipadi <venki@google.com>
This commit is contained in:
parent
a7d27c3753
commit
02cf4f9808
@ -881,6 +881,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
|
||||
return(acpi_idle_enter_c1(dev, state));
|
||||
|
||||
local_irq_disable();
|
||||
|
||||
if (cx->entry_method != ACPI_CSTATE_FFH) {
|
||||
current_thread_info()->status &= ~TS_POLLING;
|
||||
/*
|
||||
@ -888,12 +889,12 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
|
||||
* NEED_RESCHED:
|
||||
*/
|
||||
smp_mb();
|
||||
}
|
||||
|
||||
if (unlikely(need_resched())) {
|
||||
current_thread_info()->status |= TS_POLLING;
|
||||
local_irq_enable();
|
||||
return 0;
|
||||
if (unlikely(need_resched())) {
|
||||
current_thread_info()->status |= TS_POLLING;
|
||||
local_irq_enable();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -918,7 +919,8 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
|
||||
sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
|
||||
|
||||
local_irq_enable();
|
||||
current_thread_info()->status |= TS_POLLING;
|
||||
if (cx->entry_method != ACPI_CSTATE_FFH)
|
||||
current_thread_info()->status |= TS_POLLING;
|
||||
|
||||
cx->usage++;
|
||||
|
||||
@ -968,6 +970,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
|
||||
}
|
||||
|
||||
local_irq_disable();
|
||||
|
||||
if (cx->entry_method != ACPI_CSTATE_FFH) {
|
||||
current_thread_info()->status &= ~TS_POLLING;
|
||||
/*
|
||||
@ -975,12 +978,12 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
|
||||
* NEED_RESCHED:
|
||||
*/
|
||||
smp_mb();
|
||||
}
|
||||
|
||||
if (unlikely(need_resched())) {
|
||||
current_thread_info()->status |= TS_POLLING;
|
||||
local_irq_enable();
|
||||
return 0;
|
||||
if (unlikely(need_resched())) {
|
||||
current_thread_info()->status |= TS_POLLING;
|
||||
local_irq_enable();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
acpi_unlazy_tlb(smp_processor_id());
|
||||
@ -1032,7 +1035,8 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
|
||||
sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
|
||||
|
||||
local_irq_enable();
|
||||
current_thread_info()->status |= TS_POLLING;
|
||||
if (cx->entry_method != ACPI_CSTATE_FFH)
|
||||
current_thread_info()->status |= TS_POLLING;
|
||||
|
||||
cx->usage++;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user