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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.