aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/core.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-02-19 17:53:26 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-02-20 11:18:07 +0100
commit36003d4cf57ca431fb3f94d317bcca426a2394d6 (patch)
tree78888be63e3a3ef454fb6a6054092d6f6ff21c20 /drivers/base/core.c
parentdrivers/component: kerneldoc polish (diff)
downloadlinux-dev-36003d4cf57ca431fb3f94d317bcca426a2394d6.tar.xz
linux-dev-36003d4cf57ca431fb3f94d317bcca426a2394d6.zip
driver core: Fix PM-runtime for links added during consumer probe
Commit 4c06c4e6cf63 ("driver core: Fix possible supplier PM-usage counter imbalance") introduced a regression that causes suppliers to be suspended prematurely for device links added during consumer driver probe if the initial PM-runtime status of the consumer is "suspended" and the consumer is resumed after adding the link and before pm_runtime_put_suppliers() is called. In that case, pm_runtime_put_suppliers() will drop the rpm_active refcount for the link by one and (since rpm_active is equal to two after the preceding consumer resume) the supplier's PM-runtime usage counter will be decremented, which may cause the supplier to suspend even though the consumer's PM-runtime status is "active". For this reason, partially revert commit 4c06c4e6cf63 as the problem it tried to fix needs to be addressed somewhat differently, and change pm_runtime_get_suppliers() and pm_runtime_put_suppliers() so that the latter only drops rpm_active references acquired by the former. [This requires adding a new field to struct device_link, but I coulnd't find a cleaner way to address the issue that would work in all cases.] This causes pm_runtime_put_suppliers() to effectively ignore device links added during consumer probe, so device_link_add() doesn't need to worry about ensuring that suppliers will remain active after pm_runtime_put_suppliers() for links created with DL_FLAG_RPM_ACTIVE set and it only needs to bump up rpm_active by one for those links, so pm_runtime_active_link() is not necessary any more. Fixes: 4c06c4e6cf63 ("driver core: Fix possible supplier PM-usage counter imbalance") Reported-by: Jon Hunter <jonathanh@nvidia.com> Tested-by: Jon Hunter <jonathanh@nvidia.com> Tested-by: Ulf Hansson <ulf.hansson@linaro.org> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Tested-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r--drivers/base/core.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 787190238753..4aeaa0c92bda 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -277,7 +277,7 @@ struct device_link *device_link_add(struct device *consumer,
link->flags |= DL_FLAG_PM_RUNTIME;
}
if (flags & DL_FLAG_RPM_ACTIVE)
- pm_runtime_active_link(link, supplier);
+ refcount_inc(&link->rpm_active);
}
if (flags & DL_FLAG_STATELESS) {
@@ -310,7 +310,7 @@ struct device_link *device_link_add(struct device *consumer,
if (flags & DL_FLAG_PM_RUNTIME) {
if (flags & DL_FLAG_RPM_ACTIVE)
- pm_runtime_active_link(link, supplier);
+ refcount_inc(&link->rpm_active);
pm_runtime_new_link(consumer);
}