diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2019-02-19 11:53:26 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-02-20 05:18:07 -0500 |
commit | 36003d4cf57ca431fb3f94d317bcca426a2394d6 (patch) | |
tree | 78888be63e3a3ef454fb6a6054092d6f6ff21c20 /include/linux/device.h | |
parent | e4246b05507fc6102008bac0aee848f207bd96de (diff) |
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 'include/linux/device.h')
-rw-r--r-- | include/linux/device.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/device.h b/include/linux/device.h index 292b720c4bc2..a7967a48cdc9 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -861,6 +861,7 @@ struct device_link { | |||
861 | #ifdef CONFIG_SRCU | 861 | #ifdef CONFIG_SRCU |
862 | struct rcu_head rcu_head; | 862 | struct rcu_head rcu_head; |
863 | #endif | 863 | #endif |
864 | bool supplier_preactivated; /* Owned by consumer probe. */ | ||
864 | }; | 865 | }; |
865 | 866 | ||
866 | /** | 867 | /** |