* [PATCH AUTOSEL 5.10 074/116] PM: runtime: Add safety net to supplier device release
[not found] <20220118024007.1950576-1-sashal@kernel.org>
@ 2022-01-18 2:39 ` Sasha Levin
2022-01-18 2:39 ` [PATCH AUTOSEL 5.10 075/116] cpufreq: Fix initialization of min and max frequency QoS requests Sasha Levin
2022-01-18 2:39 ` [PATCH AUTOSEL 5.10 079/116] PM: AVS: qcom-cpr: Use div64_ul instead of do_div Sasha Levin
2 siblings, 0 replies; 3+ messages in thread
From: Sasha Levin @ 2022-01-18 2:39 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Rafael J. Wysocki, Peter Zijlstra, Greg Kroah-Hartman,
Sasha Levin, rafael, pavel, len.brown, linux-pm
From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
[ Upstream commit d1579e61192e0e686faa4208500ef4c3b529b16c ]
Because refcount_dec_not_one() returns true if the target refcount
becomes saturated, it is generally unsafe to use its return value as
a loop termination condition, but that is what happens when a device
link's supplier device is released during runtime PM suspend
operations and on device link removal.
To address this, introduce pm_runtime_release_supplier() to be used
in the above cases which will check the supplier device's runtime
PM usage counter in addition to the refcount_dec_not_one() return
value, so the loop can be terminated in case the rpm_active refcount
value becomes invalid, and update the code in question to use it as
appropriate.
This change is not expected to have any visible functional impact.
Reported-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/base/core.c | 3 +--
drivers/base/power/runtime.c | 41 ++++++++++++++++++++++++++----------
include/linux/pm_runtime.h | 3 +++
3 files changed, 34 insertions(+), 13 deletions(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 389d13616d1df..c0566aff53551 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -348,8 +348,7 @@ static void device_link_release_fn(struct work_struct *work)
/* Ensure that all references to the link object have been dropped. */
device_link_synchronize_removal();
- while (refcount_dec_not_one(&link->rpm_active))
- pm_runtime_put(link->supplier);
+ pm_runtime_release_supplier(link, true);
put_device(link->consumer);
put_device(link->supplier);
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index bc649da4899a0..1573319404888 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -305,19 +305,40 @@ static int rpm_get_suppliers(struct device *dev)
return 0;
}
+/**
+ * pm_runtime_release_supplier - Drop references to device link's supplier.
+ * @link: Target device link.
+ * @check_idle: Whether or not to check if the supplier device is idle.
+ *
+ * Drop all runtime PM references associated with @link to its supplier device
+ * and if @check_idle is set, check if that device is idle (and so it can be
+ * suspended).
+ */
+void pm_runtime_release_supplier(struct device_link *link, bool check_idle)
+{
+ struct device *supplier = link->supplier;
+
+ /*
+ * The additional power.usage_count check is a safety net in case
+ * the rpm_active refcount becomes saturated, in which case
+ * refcount_dec_not_one() would return true forever, but it is not
+ * strictly necessary.
+ */
+ while (refcount_dec_not_one(&link->rpm_active) &&
+ atomic_read(&supplier->power.usage_count) > 0)
+ pm_runtime_put_noidle(supplier);
+
+ if (check_idle)
+ pm_request_idle(supplier);
+}
+
static void __rpm_put_suppliers(struct device *dev, bool try_to_suspend)
{
struct device_link *link;
list_for_each_entry_rcu(link, &dev->links.suppliers, c_node,
- device_links_read_lock_held()) {
-
- while (refcount_dec_not_one(&link->rpm_active))
- pm_runtime_put_noidle(link->supplier);
-
- if (try_to_suspend)
- pm_request_idle(link->supplier);
- }
+ device_links_read_lock_held())
+ pm_runtime_release_supplier(link, try_to_suspend);
}
static void rpm_put_suppliers(struct device *dev)
@@ -1755,9 +1776,7 @@ void pm_runtime_drop_link(struct device_link *link)
return;
pm_runtime_drop_link_count(link->consumer);
-
- while (refcount_dec_not_one(&link->rpm_active))
- pm_runtime_put(link->supplier);
+ pm_runtime_release_supplier(link, true);
}
static bool pm_runtime_need_not_resume(struct device *dev)
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
index 161acd4ede448..30091ab5de287 100644
--- a/include/linux/pm_runtime.h
+++ b/include/linux/pm_runtime.h
@@ -58,6 +58,7 @@ extern void pm_runtime_get_suppliers(struct device *dev);
extern void pm_runtime_put_suppliers(struct device *dev);
extern void pm_runtime_new_link(struct device *dev);
extern void pm_runtime_drop_link(struct device_link *link);
+extern void pm_runtime_release_supplier(struct device_link *link, bool check_idle);
/**
* pm_runtime_get_if_in_use - Conditionally bump up runtime PM usage counter.
@@ -279,6 +280,8 @@ static inline void pm_runtime_get_suppliers(struct device *dev) {}
static inline void pm_runtime_put_suppliers(struct device *dev) {}
static inline void pm_runtime_new_link(struct device *dev) {}
static inline void pm_runtime_drop_link(struct device_link *link) {}
+static inline void pm_runtime_release_supplier(struct device_link *link,
+ bool check_idle) {}
#endif /* !CONFIG_PM */
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH AUTOSEL 5.10 075/116] cpufreq: Fix initialization of min and max frequency QoS requests
[not found] <20220118024007.1950576-1-sashal@kernel.org>
2022-01-18 2:39 ` [PATCH AUTOSEL 5.10 074/116] PM: runtime: Add safety net to supplier device release Sasha Levin
@ 2022-01-18 2:39 ` Sasha Levin
2022-01-18 2:39 ` [PATCH AUTOSEL 5.10 079/116] PM: AVS: qcom-cpr: Use div64_ul instead of do_div Sasha Levin
2 siblings, 0 replies; 3+ messages in thread
From: Sasha Levin @ 2022-01-18 2:39 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Rafael J. Wysocki, Srinivas Pandruvada, Sasha Levin, rafael,
linux-pm
From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
[ Upstream commit 521223d8b3ec078f670c7c35a1a04b1b2af07966 ]
The min and max frequency QoS requests in the cpufreq core are
initialized to whatever the current min and max frequency values are
at the init time, but if any of these values change later (for
example, cpuinfo.max_freq is updated by the driver), these initial
request values will be limiting the CPU frequency unnecessarily
unless they are changed by user space via sysfs.
To address this, initialize min_freq_req and max_freq_req to
FREQ_QOS_MIN_DEFAULT_VALUE and FREQ_QOS_MAX_DEFAULT_VALUE,
respectively, so they don't really limit anything until user
space updates them.
Reported-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Tested-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/cpufreq/cpufreq.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 8e159fb6af9cd..30dafe8fc5054 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1400,7 +1400,7 @@ static int cpufreq_online(unsigned int cpu)
ret = freq_qos_add_request(&policy->constraints,
policy->min_freq_req, FREQ_QOS_MIN,
- policy->min);
+ FREQ_QOS_MIN_DEFAULT_VALUE);
if (ret < 0) {
/*
* So we don't call freq_qos_remove_request() for an
@@ -1420,7 +1420,7 @@ static int cpufreq_online(unsigned int cpu)
ret = freq_qos_add_request(&policy->constraints,
policy->max_freq_req, FREQ_QOS_MAX,
- policy->max);
+ FREQ_QOS_MAX_DEFAULT_VALUE);
if (ret < 0) {
policy->max_freq_req = NULL;
goto out_destroy_policy;
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH AUTOSEL 5.10 079/116] PM: AVS: qcom-cpr: Use div64_ul instead of do_div
[not found] <20220118024007.1950576-1-sashal@kernel.org>
2022-01-18 2:39 ` [PATCH AUTOSEL 5.10 074/116] PM: runtime: Add safety net to supplier device release Sasha Levin
2022-01-18 2:39 ` [PATCH AUTOSEL 5.10 075/116] cpufreq: Fix initialization of min and max frequency QoS requests Sasha Levin
@ 2022-01-18 2:39 ` Sasha Levin
2 siblings, 0 replies; 3+ messages in thread
From: Sasha Levin @ 2022-01-18 2:39 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Changcheng Deng, Zeal Robot, Bjorn Andersson, Sasha Levin, nks,
agross, linux-pm, linux-arm-msm
From: Changcheng Deng <deng.changcheng@zte.com.cn>
[ Upstream commit 92c550f9ffd2884bb5def52b5c0485a35e452784 ]
do_div() does a 64-by-32 division. Here the divisor is an unsigned long
which on some platforms is 64 bit wide. So use div64_ul instead of do_div
to avoid a possible truncation.
Reported-by: Zeal Robot <zealci@zte.com.cn>
Signed-off-by: Changcheng Deng <deng.changcheng@zte.com.cn>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Link: https://lore.kernel.org/r/20211125014311.45942-1-deng.changcheng@zte.com.cn
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/soc/qcom/cpr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/soc/qcom/cpr.c b/drivers/soc/qcom/cpr.c
index b24cc77d1889f..6298561bc29c9 100644
--- a/drivers/soc/qcom/cpr.c
+++ b/drivers/soc/qcom/cpr.c
@@ -1043,7 +1043,7 @@ static int cpr_interpolate(const struct corner *corner, int step_volt,
return corner->uV;
temp = f_diff * (uV_high - uV_low);
- do_div(temp, f_high - f_low);
+ temp = div64_ul(temp, f_high - f_low);
/*
* max_volt_scale has units of uV/MHz while freq values
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2022-01-18 2:59 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20220118024007.1950576-1-sashal@kernel.org>
2022-01-18 2:39 ` [PATCH AUTOSEL 5.10 074/116] PM: runtime: Add safety net to supplier device release Sasha Levin
2022-01-18 2:39 ` [PATCH AUTOSEL 5.10 075/116] cpufreq: Fix initialization of min and max frequency QoS requests Sasha Levin
2022-01-18 2:39 ` [PATCH AUTOSEL 5.10 079/116] PM: AVS: qcom-cpr: Use div64_ul instead of do_div Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).