linux-stable/drivers/base/power
Adrian Hunter 9dfacc54a8 PM: runtime: Fix race getting/putting suppliers at probe
pm_runtime_put_suppliers() must not decrement rpm_active unless the
consumer is suspended. That is because, otherwise, it could suspend
suppliers for an active consumer.

That can happen as follows:

 static int driver_probe_device(struct device_driver *drv, struct device *dev)
 {
	int ret = 0;

	if (!device_is_registered(dev))
		return -ENODEV;

	dev->can_match = true;
	pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
		 drv->bus->name, __func__, dev_name(dev), drv->name);

	pm_runtime_get_suppliers(dev);
	if (dev->parent)
		pm_runtime_get_sync(dev->parent);

 At this point, dev can runtime suspend so rpm_put_suppliers() can run,
 rpm_active becomes 1 (the lowest value).

	pm_runtime_barrier(dev);
	if (initcall_debug)
		ret = really_probe_debug(dev, drv);
	else
		ret = really_probe(dev, drv);

 Probe callback can have runtime resumed dev, and then runtime put
 so dev is awaiting autosuspend, but rpm_active is 2.

	pm_request_idle(dev);

	if (dev->parent)
		pm_runtime_put(dev->parent);

	pm_runtime_put_suppliers(dev);

 Now pm_runtime_put_suppliers() will put the supplier
 i.e. rpm_active 2 -> 1, but consumer can still be active.

	return ret;
 }

Fix by checking the runtime status. For any status other than
RPM_SUSPENDED, rpm_active can be considered to be "owned" by
rpm_[get/put]_suppliers() and pm_runtime_put_suppliers() need do nothing.

Reported-by: Asutosh Das <asutoshd@codeaurora.org>
Fixes: 4c06c4e6cf ("driver core: Fix possible supplier PM-usage counter imbalance")
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: 5.1+ <stable@vger.kernel.org> # 5.1+
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-03-29 19:27:09 +02:00
..
clock_ops.c PM: clk: make PM clock layer compatible with clocks that must sleep 2021-01-27 19:29:32 +01:00
common.c PM / Domains: Introduce dev_pm_domain_start() 2019-11-13 11:41:50 +01:00
domain.c Driver core / debugfs update for 5.12-rc1 2021-02-24 10:13:55 -08:00
domain_governor.c PM: domains: use device's next wakeup to determine domain idle state 2021-01-22 17:08:28 +01:00
generic_ops.c drivers: base: power: add proper SPDX identifiers on files that did not have them. 2019-04-04 20:03:40 +02:00
main.c PM: sleep: Use dev_printk() when possible 2021-01-27 19:21:17 +01:00
Makefile PM / QoS: Initial kunit test 2019-11-29 12:04:49 +01:00
power.h drivers/base/power: add dpm_sysfs_change_owner() 2020-02-26 20:07:25 -08:00
qos-test.c kunit: allow kunit tests to be loaded as a module 2020-01-09 16:42:29 -07:00
qos.c PM / QoS: Restore DEV_PM_QOS_MIN/MAX_FREQUENCY 2019-11-29 12:04:50 +01:00
runtime.c PM: runtime: Fix race getting/putting suppliers at probe 2021-03-29 19:27:09 +02:00
sysfs.c drivers core: Miscellaneous changes for sysfs_emit 2020-10-02 13:12:07 +02:00
trace.c PM: sleep: core: mark 2 functions as __init to save some memory 2020-06-23 17:35:33 +02:00
wakeirq.c PM / wakeirq: remove unnecessary parentheses 2019-11-13 11:31:08 +01:00
wakeup.c PM: sleep: wakeup: Skip wakeup_source_sysfs_remove() if device is not there 2020-03-25 11:15:55 +01:00
wakeup_stats.c drivers core: Miscellaneous changes for sysfs_emit 2020-10-02 13:12:07 +02:00