More power management updates for 4.19-rc1
- Make the idle loop handle stopped scheduler tick correctly (Rafael Wysocki). - Prevent the menu cpuidle governor from letting CPUs spend too much time in shallow idle states when it is invoked with scheduler tick stopped and clean it up somewhat (Rafael Wysocki). - Avoid invoking the platform firmware to make the platform enter the ACPI S3 sleep state with suspended PCIe root ports which may confuse the firmware and cause it to crash (Rafael Wysocki). - Fix sysfs-related race in the ondemand and conservative cpufreq governors which may cause the system to crash if the governor module is removed during an update of CPU frequency limits (Henry Willard). - Select SRCU when building the system wakeup framework to avoid a build issue in it (zhangyi). - Make the descriptions of ACPI C-states vendor-neutral to avoid confusion (Prarit Bhargava). -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJbfSnVAAoJEILEb/54YlRxBn4QAKQ8PqkSYkBby+1hb90ET4dk VaLkbCYXuzLK5rIDvnbYOALhVKo4B29Ex5GdCLN7cWkZMkrVKe7oX8QQTnp3/7lF URjTKgTNec5uJG652PrE3ESAa3X/kYggj6aeQOxDR4iYKzcpJEQ92ekFW+SoJTNp Jc2kZh3qkC2On64GB3ibsZaKnmHfPvLg0t4agwzuYq/Gff8NRJFk7kMwAPzqGzZo b2UVRcYFWIRkJjgmU9iInoeHIY8mBdT3IiKwTemZP1dOhb5T1AHOXwGTk6/cS+RH A9qx4eg7I3R00KmnYvO8WytYJeOu2qb83GIUx4fIJGOqfvevm5xkxB9F+nfE+ouj ROBqO4+X4XfQGPw8slayg0rJjI9JSkXLnLdl0Qw2WRlbc4/fVWntra1C57EeKFBR EG9UAF9+7nUUx0bOCLsfFF3+r9R3SDUjk7b4thyhYncyQRsYC+FL7ztlxnMzVtzW M5SF2sPrpcQzqmcszdUdbESI10n5X8m/crJW4rsbTxBpAM+coO+uLcvHWOY4MpkW BgBsR6bMDAlG/VlTFgeeP/tkCRd5zNlJi7yBFItXuOoVKXpnHCJuxq2WkZ1Rb74M Gk1d3TduekHJm8VsLEdCJR/tEk1cMc0zVUD/a1yzI4Z21QxvXUCqMDdws4/Ey184 qmKgNR9R94vSC5xIPRhM =9GrU -----END PGP SIGNATURE----- Merge tag 'pm-4.19-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull more power management updates from Rafael Wysocki: "These fix the main idle loop and the menu cpuidle governor, clean up the latter, fix a mistake in the PCI bus type's support for system suspend and resume, fix the ondemand and conservative cpufreq governors, address a build issue in the system wakeup framework and make the ACPI C-states desciptions less confusing. Specifics: - Make the idle loop handle stopped scheduler tick correctly (Rafael Wysocki). - Prevent the menu cpuidle governor from letting CPUs spend too much time in shallow idle states when it is invoked with scheduler tick stopped and clean it up somewhat (Rafael Wysocki). - Avoid invoking the platform firmware to make the platform enter the ACPI S3 sleep state with suspended PCIe root ports which may confuse the firmware and cause it to crash (Rafael Wysocki). - Fix sysfs-related race in the ondemand and conservative cpufreq governors which may cause the system to crash if the governor module is removed during an update of CPU frequency limits (Henry Willard). - Select SRCU when building the system wakeup framework to avoid a build issue in it (zhangyi). - Make the descriptions of ACPI C-states vendor-neutral to avoid confusion (Prarit Bhargava)" * tag 'pm-4.19-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: cpuidle: menu: Handle stopped tick more aggressively sched: idle: Avoid retaining the tick when it has been stopped PCI / ACPI / PM: Resume all bridges on suspend-to-RAM cpuidle: menu: Update stale polling override comment cpufreq: governor: Avoid accessing invalid governor_data x86/ACPI/cstate: Make APCI C1 FFH MWAIT C-state description vendor-neutral cpuidle: menu: Fix white space PM / sleep: wakeup: Fix build error caused by missing SRCU support
This commit is contained in:
commit
dfec4a8478
6 changed files with 43 additions and 25 deletions
|
@ -108,7 +108,7 @@ static long acpi_processor_ffh_cstate_probe_cpu(void *_cx)
|
|||
cx->type);
|
||||
}
|
||||
snprintf(cx->desc,
|
||||
ACPI_CX_DESC_LEN, "ACPI FFH INTEL MWAIT 0x%x",
|
||||
ACPI_CX_DESC_LEN, "ACPI FFH MWAIT 0x%x",
|
||||
cx->address);
|
||||
out:
|
||||
return retval;
|
||||
|
|
|
@ -555,12 +555,20 @@ EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_stop);
|
|||
|
||||
void cpufreq_dbs_governor_limits(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct policy_dbs_info *policy_dbs = policy->governor_data;
|
||||
struct policy_dbs_info *policy_dbs;
|
||||
|
||||
/* Protect gov->gdbs_data against cpufreq_dbs_governor_exit() */
|
||||
mutex_lock(&gov_dbs_data_mutex);
|
||||
policy_dbs = policy->governor_data;
|
||||
if (!policy_dbs)
|
||||
goto out;
|
||||
|
||||
mutex_lock(&policy_dbs->update_mutex);
|
||||
cpufreq_policy_apply_limits(policy);
|
||||
gov_update_sample_delay(policy_dbs, 0);
|
||||
|
||||
mutex_unlock(&policy_dbs->update_mutex);
|
||||
|
||||
out:
|
||||
mutex_unlock(&gov_dbs_data_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_limits);
|
||||
|
|
|
@ -328,9 +328,8 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
|
|||
unsigned int polling_threshold;
|
||||
|
||||
/*
|
||||
* We want to default to C1 (hlt), not to busy polling
|
||||
* unless the timer is happening really really soon, or
|
||||
* C1's exit latency exceeds the user configured limit.
|
||||
* Default to a physical idle state, not to busy polling, unless
|
||||
* a timer is going to trigger really really soon.
|
||||
*/
|
||||
polling_threshold = max_t(unsigned int, 20, s->target_residency);
|
||||
if (data->next_timer_us > polling_threshold &&
|
||||
|
@ -349,14 +348,12 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
|
|||
* If the tick is already stopped, the cost of possible short
|
||||
* idle duration misprediction is much higher, because the CPU
|
||||
* may be stuck in a shallow idle state for a long time as a
|
||||
* result of it. In that case say we might mispredict and try
|
||||
* to force the CPU into a state for which we would have stopped
|
||||
* the tick, unless a timer is going to expire really soon
|
||||
* anyway.
|
||||
* result of it. In that case say we might mispredict and use
|
||||
* the known time till the closest timer event for the idle
|
||||
* state selection.
|
||||
*/
|
||||
if (data->predicted_us < TICK_USEC)
|
||||
data->predicted_us = min_t(unsigned int, TICK_USEC,
|
||||
ktime_to_us(delta_next));
|
||||
data->predicted_us = ktime_to_us(delta_next);
|
||||
} else {
|
||||
/*
|
||||
* Use the performance multiplier and the user-configurable
|
||||
|
@ -381,8 +378,22 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
|
|||
continue;
|
||||
if (idx == -1)
|
||||
idx = i; /* first enabled state */
|
||||
if (s->target_residency > data->predicted_us)
|
||||
break;
|
||||
if (s->target_residency > data->predicted_us) {
|
||||
if (!tick_nohz_tick_stopped())
|
||||
break;
|
||||
|
||||
/*
|
||||
* If the state selected so far is shallow and this
|
||||
* state's target residency matches the time till the
|
||||
* closest timer event, select this one to avoid getting
|
||||
* stuck in the shallow one for too long.
|
||||
*/
|
||||
if (drv->states[idx].target_residency < TICK_USEC &&
|
||||
s->target_residency <= ktime_to_us(delta_next))
|
||||
idx = i;
|
||||
|
||||
goto out;
|
||||
}
|
||||
if (s->exit_latency > latency_req) {
|
||||
/*
|
||||
* If we break out of the loop for latency reasons, use
|
||||
|
@ -403,14 +414,13 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
|
|||
* Don't stop the tick if the selected state is a polling one or if the
|
||||
* expected idle duration is shorter than the tick period length.
|
||||
*/
|
||||
if ((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) ||
|
||||
expected_interval < TICK_USEC) {
|
||||
if (((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) ||
|
||||
expected_interval < TICK_USEC) && !tick_nohz_tick_stopped()) {
|
||||
unsigned int delta_next_us = ktime_to_us(delta_next);
|
||||
|
||||
*stop_tick = false;
|
||||
|
||||
if (!tick_nohz_tick_stopped() && idx > 0 &&
|
||||
drv->states[idx].target_residency > delta_next_us) {
|
||||
if (idx > 0 && drv->states[idx].target_residency > delta_next_us) {
|
||||
/*
|
||||
* The tick is not going to be stopped and the target
|
||||
* residency of the state to be returned is not within
|
||||
|
@ -418,8 +428,8 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
|
|||
* tick, so try to correct that.
|
||||
*/
|
||||
for (i = idx - 1; i >= 0; i--) {
|
||||
if (drv->states[i].disabled ||
|
||||
dev->states_usage[i].disable)
|
||||
if (drv->states[i].disabled ||
|
||||
dev->states_usage[i].disable)
|
||||
continue;
|
||||
|
||||
idx = i;
|
||||
|
@ -429,6 +439,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
|
|||
}
|
||||
}
|
||||
|
||||
out:
|
||||
data->last_state_idx = idx;
|
||||
|
||||
return data->last_state_idx;
|
||||
|
|
|
@ -615,13 +615,11 @@ static bool acpi_pci_need_resume(struct pci_dev *dev)
|
|||
/*
|
||||
* In some cases (eg. Samsung 305V4A) leaving a bridge in suspend over
|
||||
* system-wide suspend/resume confuses the platform firmware, so avoid
|
||||
* doing that, unless the bridge has a driver that should take care of
|
||||
* the PM handling. According to Section 16.1.6 of ACPI 6.2, endpoint
|
||||
* doing that. According to Section 16.1.6 of ACPI 6.2, endpoint
|
||||
* devices are expected to be in D3 before invoking the S3 entry path
|
||||
* from the firmware, so they should not be affected by this issue.
|
||||
*/
|
||||
if (pci_is_bridge(dev) && !dev->driver &&
|
||||
acpi_target_system_state() != ACPI_STATE_S0)
|
||||
if (pci_is_bridge(dev) && acpi_target_system_state() != ACPI_STATE_S0)
|
||||
return true;
|
||||
|
||||
if (!adev || !acpi_device_power_manageable(adev))
|
||||
|
|
|
@ -105,6 +105,7 @@ config PM_SLEEP
|
|||
def_bool y
|
||||
depends on SUSPEND || HIBERNATE_CALLBACKS
|
||||
select PM
|
||||
select SRCU
|
||||
|
||||
config PM_SLEEP_SMP
|
||||
def_bool y
|
||||
|
|
|
@ -190,7 +190,7 @@ static void cpuidle_idle_call(void)
|
|||
*/
|
||||
next_state = cpuidle_select(drv, dev, &stop_tick);
|
||||
|
||||
if (stop_tick)
|
||||
if (stop_tick || tick_nohz_tick_stopped())
|
||||
tick_nohz_idle_stop_tick();
|
||||
else
|
||||
tick_nohz_idle_retain_tick();
|
||||
|
|
Loading…
Reference in a new issue