From: "Rafael J. Wysocki" <rjw@rjwysocki.net>
To: Linux PM <linux-pm@vger.kernel.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
Viresh Kumar <viresh.kumar@linaro.org>,
Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>,
Mario Limonciello <mario.limonciello@amd.com>,
Sudeep Holla <sudeep.holla@arm.com>
Subject: [PATCH v1 04/10] cpufreq: Add and use cpufreq policy locking guards
Date: Fri, 28 Mar 2025 21:42:48 +0100 [thread overview]
Message-ID: <8518682.T7Z3S40VBb@rjwysocki.net> (raw)
In-Reply-To: <4651448.LvFx2qVVIh@rjwysocki.net>
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Introduce "read" and "write" locking guards for cpufreq policies and use
them where applicable in the cpufreq core.
No intentional functional impact.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
drivers/cpufreq/cpufreq.c | 121 ++++++++++++++++++++--------------------------
include/linux/cpufreq.h | 6 ++
2 files changed, 60 insertions(+), 67 deletions(-)
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -987,17 +987,16 @@
{
struct cpufreq_policy *policy = to_policy(kobj);
struct freq_attr *fattr = to_attr(attr);
- ssize_t ret = -EBUSY;
if (!fattr->show)
return -EIO;
- down_read(&policy->rwsem);
+ guard(cpufreq_policy_read)(policy);
+
if (likely(!policy_is_inactive(policy)))
- ret = fattr->show(policy, buf);
- up_read(&policy->rwsem);
+ return fattr->show(policy, buf);
- return ret;
+ return -EBUSY;
}
static ssize_t store(struct kobject *kobj, struct attribute *attr,
@@ -1005,17 +1004,16 @@
{
struct cpufreq_policy *policy = to_policy(kobj);
struct freq_attr *fattr = to_attr(attr);
- ssize_t ret = -EBUSY;
if (!fattr->store)
return -EIO;
- down_write(&policy->rwsem);
+ guard(cpufreq_policy_write)(policy);
+
if (likely(!policy_is_inactive(policy)))
- ret = fattr->store(policy, buf, count);
- up_write(&policy->rwsem);
+ return fattr->store(policy, buf, count);
- return ret;
+ return -EBUSY;
}
static void cpufreq_sysfs_release(struct kobject *kobj)
@@ -1167,7 +1165,8 @@
if (cpumask_test_cpu(cpu, policy->cpus))
return 0;
- down_write(&policy->rwsem);
+ guard(cpufreq_policy_write)(policy);
+
if (has_target())
cpufreq_stop_governor(policy);
@@ -1178,7 +1177,7 @@
if (ret)
pr_err("%s: Failed to start governor\n", __func__);
}
- up_write(&policy->rwsem);
+
return ret;
}
@@ -1198,9 +1197,10 @@
container_of(work, struct cpufreq_policy, update);
pr_debug("handle_update for cpu %u called\n", policy->cpu);
- down_write(&policy->rwsem);
+
+ guard(cpufreq_policy_write)(policy);
+
refresh_frequency_limits(policy);
- up_write(&policy->rwsem);
}
static int cpufreq_notifier_min(struct notifier_block *nb, unsigned long freq,
@@ -1226,11 +1226,11 @@
struct kobject *kobj;
struct completion *cmp;
- down_write(&policy->rwsem);
- cpufreq_stats_free_table(policy);
- kobj = &policy->kobj;
- cmp = &policy->kobj_unregister;
- up_write(&policy->rwsem);
+ scoped_guard(cpufreq_policy_write, policy) {
+ cpufreq_stats_free_table(policy);
+ kobj = &policy->kobj;
+ cmp = &policy->kobj_unregister;
+ }
kobject_put(kobj);
/*
@@ -1381,7 +1381,7 @@
unsigned int j;
int ret;
- down_write(&policy->rwsem);
+ guard(cpufreq_policy_write)(policy);
policy->cpu = cpu;
policy->governor = NULL;
@@ -1558,10 +1558,7 @@
goto out_destroy_policy;
}
-out_unlock:
- up_write(&policy->rwsem);
-
- return ret;
+ return 0;
out_destroy_policy:
for_each_cpu(j, policy->real_cpus)
@@ -1578,7 +1575,7 @@
out_clear_policy:
cpumask_clear(policy->cpus);
- goto out_unlock;
+ return ret;
}
static int cpufreq_online(unsigned int cpu)
@@ -1726,11 +1723,10 @@
return 0;
}
- down_write(&policy->rwsem);
+ guard(cpufreq_policy_write)(policy);
__cpufreq_offline(cpu, policy);
- up_write(&policy->rwsem);
return 0;
}
@@ -1747,33 +1743,29 @@
if (!policy)
return;
- down_write(&policy->rwsem);
+ scoped_guard(cpufreq_policy_write, policy) {
+ if (cpu_online(cpu))
+ __cpufreq_offline(cpu, policy);
- if (cpu_online(cpu))
- __cpufreq_offline(cpu, policy);
+ remove_cpu_dev_symlink(policy, cpu, dev);
- remove_cpu_dev_symlink(policy, cpu, dev);
+ if (!cpumask_empty(policy->real_cpus))
+ return;
- if (!cpumask_empty(policy->real_cpus)) {
- up_write(&policy->rwsem);
- return;
- }
+ /*
+ * Unregister cpufreq cooling once all the CPUs of the policy
+ * are removed.
+ */
+ if (cpufreq_thermal_control_enabled(cpufreq_driver)) {
+ cpufreq_cooling_unregister(policy->cdev);
+ policy->cdev = NULL;
+ }
- /*
- * Unregister cpufreq cooling once all the CPUs of the policy are
- * removed.
- */
- if (cpufreq_thermal_control_enabled(cpufreq_driver)) {
- cpufreq_cooling_unregister(policy->cdev);
- policy->cdev = NULL;
+ /* We did light-weight exit earlier, do full tear down now */
+ if (cpufreq_driver->offline && cpufreq_driver->exit)
+ cpufreq_driver->exit(policy);
}
- /* We did light-weight exit earlier, do full tear down now */
- if (cpufreq_driver->offline && cpufreq_driver->exit)
- cpufreq_driver->exit(policy);
-
- up_write(&policy->rwsem);
-
cpufreq_policy_free(policy);
}
@@ -1926,15 +1918,16 @@
struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
unsigned int ret_freq = 0;
- if (policy) {
- down_read(&policy->rwsem);
+ if (!policy)
+ return 0;
+
+ scoped_guard(cpufreq_policy_read, policy) {
if (cpufreq_driver->get)
ret_freq = __cpufreq_get(policy);
- up_read(&policy->rwsem);
-
- cpufreq_cpu_put(policy);
}
+ cpufreq_cpu_put(policy);
+
return ret_freq;
}
EXPORT_SYMBOL(cpufreq_get);
@@ -1994,9 +1987,9 @@
for_each_active_policy(policy) {
if (has_target()) {
- down_write(&policy->rwsem);
- cpufreq_stop_governor(policy);
- up_write(&policy->rwsem);
+ scoped_guard(cpufreq_policy_write, policy) {
+ cpufreq_stop_governor(policy);
+ }
}
if (cpufreq_driver->suspend && cpufreq_driver->suspend(policy))
@@ -2037,9 +2030,9 @@
pr_err("%s: Failed to resume driver: %s\n", __func__,
cpufreq_driver->name);
} else if (has_target()) {
- down_write(&policy->rwsem);
- ret = cpufreq_start_governor(policy);
- up_write(&policy->rwsem);
+ scoped_guard(cpufreq_policy_write, policy) {
+ ret = cpufreq_start_governor(policy);
+ }
if (ret)
pr_err("%s: Failed to start governor for CPU%u's policy\n",
@@ -2406,15 +2399,9 @@
unsigned int target_freq,
unsigned int relation)
{
- int ret;
+ guard(cpufreq_policy_write)(policy);
- down_write(&policy->rwsem);
-
- ret = __cpufreq_driver_target(policy, target_freq, relation);
-
- up_write(&policy->rwsem);
-
- return ret;
+ return __cpufreq_driver_target(policy, target_freq, relation);
}
EXPORT_SYMBOL_GPL(cpufreq_driver_target);
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -170,6 +170,12 @@
struct notifier_block nb_max;
};
+DEFINE_GUARD(cpufreq_policy_write, struct cpufreq_policy *,
+ down_write(&_T->rwsem), up_write(&_T->rwsem))
+
+DEFINE_GUARD(cpufreq_policy_read, struct cpufreq_policy *,
+ down_read(&_T->rwsem), up_read(&_T->rwsem))
+
/*
* Used for passing new cpufreq policy data to the cpufreq driver's ->verify()
* callback for sanitization. That callback is only expected to modify the min
next prev parent reply other threads:[~2025-03-28 21:06 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-28 20:36 [PATCH v1 00/10] cpufreq: cpufreq_update_limits() fix and some cleanups Rafael J. Wysocki
2025-03-28 20:39 ` [PATCH v1 01/10] cpufreq: Reference count policy in cpufreq_update_limits() Rafael J. Wysocki
2025-03-29 2:02 ` Marek Marczykowski-Górecki
2025-03-29 11:48 ` Rafael J. Wysocki
2025-04-01 8:30 ` Viresh Kumar
2025-04-01 16:47 ` Rafael J. Wysocki
2025-04-15 13:08 ` Marek Marczykowski-Górecki
2025-04-15 13:12 ` Rafael J. Wysocki
2025-03-28 20:40 ` [PATCH v1 02/10] cpufreq: Consolidate some code in cpufreq_online() Rafael J. Wysocki
2025-04-01 8:32 ` Viresh Kumar
2025-03-28 20:41 ` [PATCH v1 03/10] cpufreq: Split cpufreq_online() Rafael J. Wysocki
2025-04-01 8:38 ` Viresh Kumar
2025-04-01 8:43 ` Viresh Kumar
2025-03-28 20:42 ` Rafael J. Wysocki [this message]
2025-04-01 8:43 ` [PATCH v1 04/10] cpufreq: Add and use cpufreq policy locking guards Viresh Kumar
2025-03-28 20:43 ` [PATCH v1 05/10] cpufreq: intel_pstate: Rearrange max frequency updates handling code Rafael J. Wysocki
2025-04-07 18:46 ` Rafael J. Wysocki
2025-03-28 20:44 ` [PATCH v1 06/10] cpufreq: Use locking guard and __free() in cpufreq_update_policy() Rafael J. Wysocki
2025-04-01 8:46 ` Viresh Kumar
2025-03-28 20:45 ` [PATCH v1 07/10] cpufreq: Drop cpufreq_cpu_acquire() and cpufreq_cpu_release() Rafael J. Wysocki
2025-04-01 8:46 ` Viresh Kumar
2025-03-28 20:46 ` [PATCH v1 08/10] cpufreq: Use __free() for policy reference counting cleanup Rafael J. Wysocki
2025-04-01 8:48 ` Viresh Kumar
2025-03-28 20:47 ` [PATCH v1 09/10] cpufreq: Introduce cpufreq_policy_refresh() Rafael J. Wysocki
2025-04-01 8:51 ` Viresh Kumar
2025-03-28 20:48 ` [PATCH v1 10/10] cpufreq: Pass policy pointer to ->update_limits() Rafael J. Wysocki
2025-04-01 8:51 ` Viresh Kumar
2025-04-07 18:48 ` Rafael J. Wysocki
2025-04-07 22:27 ` srinivas pandruvada
2025-04-07 23:49 ` Doug Smythies
2025-04-08 14:18 ` srinivas pandruvada
2025-04-08 11:41 ` Rafael J. Wysocki
2025-04-08 13:37 ` Rafael J. Wysocki
2025-04-08 17:47 ` srinivas pandruvada
2025-04-08 18:34 ` Rafael J. Wysocki
2025-04-08 18:48 ` srinivas pandruvada
2025-04-01 16:57 ` [PATCH v1 00/10] cpufreq: cpufreq_update_limits() fix and some cleanups Mario Limonciello
2025-04-09 19:16 ` Sudeep Holla
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8518682.T7Z3S40VBb@rjwysocki.net \
--to=rjw@rjwysocki.net \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=mario.limonciello@amd.com \
--cc=srinivas.pandruvada@linux.intel.com \
--cc=sudeep.holla@arm.com \
--cc=viresh.kumar@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox