Merge tag 'pm-5.6-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull more power manadement updates from Rafael Wysocki:
 "Prevent cpufreq from creating excessively large stack frames and fix
  the handling of devices deleted during system-wide resume in the PM
  core (Rafael Wysocki), revert a problematic commit affecting the
  cpupower utility and correct its man page (Thomas Renninger,
  Brahadambal Srinivasan), and improve the intel_pstate_tracer utility
  (Doug Smythies)"

* tag 'pm-5.6-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  tools/power/x86/intel_pstate_tracer: change several graphs to autoscale y-axis
  tools/power/x86/intel_pstate_tracer: changes for python 3 compatibility
  Correction to manpage of cpupower
  cpufreq: Avoid creating excessively large stack frames
  PM: core: Fix handling of devices deleted during system-wide resume
  cpupower: Revert library ABI changes from commit ae2917093f
This commit is contained in:
Linus Torvalds
2020-01-31 14:36:35 -08:00
17 changed files with 266 additions and 173 deletions

View File

@@ -273,10 +273,38 @@ static void dpm_wait_for_suppliers(struct device *dev, bool async)
device_links_read_unlock(idx);
}
static void dpm_wait_for_superior(struct device *dev, bool async)
static bool dpm_wait_for_superior(struct device *dev, bool async)
{
dpm_wait(dev->parent, async);
struct device *parent;
/*
* If the device is resumed asynchronously and the parent's callback
* deletes both the device and the parent itself, the parent object may
* be freed while this function is running, so avoid that by reference
* counting the parent once more unless the device has been deleted
* already (in which case return right away).
*/
mutex_lock(&dpm_list_mtx);
if (!device_pm_initialized(dev)) {
mutex_unlock(&dpm_list_mtx);
return false;
}
parent = get_device(dev->parent);
mutex_unlock(&dpm_list_mtx);
dpm_wait(parent, async);
put_device(parent);
dpm_wait_for_suppliers(dev, async);
/*
* If the parent's callback has deleted the device, attempting to resume
* it would be invalid, so avoid doing that then.
*/
return device_pm_initialized(dev);
}
static void dpm_wait_for_consumers(struct device *dev, bool async)
@@ -621,7 +649,8 @@ static int device_resume_noirq(struct device *dev, pm_message_t state, bool asyn
if (!dev->power.is_noirq_suspended)
goto Out;
dpm_wait_for_superior(dev, async);
if (!dpm_wait_for_superior(dev, async))
goto Out;
skip_resume = dev_pm_may_skip_resume(dev);
@@ -829,7 +858,8 @@ static int device_resume_early(struct device *dev, pm_message_t state, bool asyn
if (!dev->power.is_late_suspended)
goto Out;
dpm_wait_for_superior(dev, async);
if (!dpm_wait_for_superior(dev, async))
goto Out;
callback = dpm_subsys_resume_early_cb(dev, state, &info);
@@ -944,7 +974,9 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
goto Complete;
}
dpm_wait_for_superior(dev, async);
if (!dpm_wait_for_superior(dev, async))
goto Complete;
dpm_watchdog_set(&wd, dev);
device_lock(dev);