[PATCH v1 08/10] devfreq: Allow find_devfreq_governor() to get module refcount
Jie Zhan
zhanjie9 at hisilicon.com
Thu Mar 26 05:34:26 PDT 2026
Add a 'get' parameter for find_devfreq_governor() to optionally get a
refcount of the governor module.
Getting refcount in try_then_request_governor() prevents the governor
module from being removed during the governor setting phase.
However, in devfreq_add/remove_governor(), it doesn't need to get a
refcount of the governor module because it just checks whether a
governor registered with the same name exists or not.
Signed-off-by: Jie Zhan <zhanjie9 at hisilicon.com>
---
drivers/devfreq/devfreq.c | 28 +++++++++++++++++++++-------
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index ba09948915ba..c6b670b8fd22 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -254,11 +254,13 @@ EXPORT_SYMBOL(devfreq_update_status);
/**
* find_devfreq_governor() - find devfreq governor from name
* @name: name of the governor
+ * @get: whether to get a refcount of the governor module
*
* Search the list of devfreq governors and return the matched
* governor's pointer.
*/
-static struct devfreq_governor *find_devfreq_governor(const char *name)
+static struct devfreq_governor *find_devfreq_governor(const char *name,
+ bool get)
{
struct devfreq_governor *tmp_governor;
@@ -269,8 +271,13 @@ static struct devfreq_governor *find_devfreq_governor(const char *name)
guard(mutex)(&devfreq_gov_lock);
list_for_each_entry(tmp_governor, &devfreq_governor_list, node) {
- if (!strncmp(tmp_governor->name, name, DEVFREQ_NAME_LEN))
- return tmp_governor;
+ if (strncmp(tmp_governor->name, name, DEVFREQ_NAME_LEN))
+ continue;
+
+ if (get && !try_module_get(tmp_governor->owner))
+ return ERR_PTR(-EBUSY);
+
+ return tmp_governor;
}
return ERR_PTR(-ENODEV);
@@ -285,6 +292,9 @@ static struct devfreq_governor *find_devfreq_governor(const char *name)
* if is not found. This can happen when both drivers (the governor driver
* and the driver that call devfreq_add_device) are built as modules.
* Returns the matched governor's pointer or an error pointer.
+ * On success, this holds a refcount of the governor module to prevent the
+ * module from being unloaded during usage, so the caller should put a module
+ * refcount after using it.
*/
static struct devfreq_governor *try_then_request_governor(const char *name)
{
@@ -296,7 +306,7 @@ static struct devfreq_governor *try_then_request_governor(const char *name)
return ERR_PTR(-EINVAL);
}
- governor = find_devfreq_governor(name);
+ governor = find_devfreq_governor(name, true);
if (IS_ERR(governor)) {
if (!strncmp(name, DEVFREQ_GOV_SIMPLE_ONDEMAND,
DEVFREQ_NAME_LEN))
@@ -307,7 +317,7 @@ static struct devfreq_governor *try_then_request_governor(const char *name)
if (err)
return (err < 0) ? ERR_PTR(err) : ERR_PTR(-EINVAL);
- governor = find_devfreq_governor(name);
+ governor = find_devfreq_governor(name, true);
}
return governor;
@@ -1007,6 +1017,8 @@ struct devfreq *devfreq_add_device(struct device *dev,
if (err)
goto err_devfreq;
+ module_put(governor->owner);
+
list_add(&devfreq->node, &devfreq_list);
mutex_unlock(&devfreq_list_lock);
@@ -1312,7 +1324,7 @@ int __devfreq_add_governor(struct devfreq_governor *governor,
return -EINVAL;
}
- g = find_devfreq_governor(governor->name);
+ g = find_devfreq_governor(governor->name, false);
if (!IS_ERR(g)) {
pr_err("%s: governor %s already registered\n", __func__,
g->name);
@@ -1361,7 +1373,7 @@ int devfreq_remove_governor(struct devfreq_governor *governor)
return -EINVAL;
}
- g = find_devfreq_governor(governor->name);
+ g = find_devfreq_governor(governor->name, false);
if (IS_ERR(g)) {
pr_err("%s: governor %s not registered\n", __func__,
governor->name);
@@ -1436,6 +1448,8 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
ret = devfreq_set_governor(df, governor);
+ module_put(governor->owner);
+
return ret ? ret : count;
}
static DEVICE_ATTR_RW(governor);
--
2.43.0
More information about the linux-arm-kernel
mailing list