From: Zxyan Zhu Date: Thu, 9 Apr 2026 03:50:15 +0000 (+0800) Subject: regmap: debugfs: fix race condition in dummy name allocation X-Git-Tag: v7.1-rc1~155^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7d696210cf36ed31c7c37f6eff17cb7147e83367;p=thirdparty%2Fkernel%2Flinux.git regmap: debugfs: fix race condition in dummy name allocation Use IDA instead of a simple counter for generating unique dummy names. The previous implementation used dummy_index++ which is not atomic, leading to potential duplicate names when multiple threads call regmap_debugfs_init() concurrently with name="dummy". Signed-off-by: Zxyan Zhu Link: https://patch.msgid.link/20260409035015.950764-1-zxyan0222@gmail.com Signed-off-by: Mark Brown --- diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index c77f3a49a89e2..55273a6178f8d 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -84,6 +84,7 @@ struct regmap { bool debugfs_disable; struct dentry *debugfs; const char *debugfs_name; + int debugfs_dummy_id; unsigned int debugfs_reg_len; unsigned int debugfs_val_len; diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index 5a46ce5fee72a..18f1c60749fed 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "internal.h" @@ -20,7 +21,7 @@ struct regmap_debugfs_node { struct list_head link; }; -static unsigned int dummy_index; +static DEFINE_IDA(dummy_ida); static struct dentry *regmap_debugfs_root; static LIST_HEAD(regmap_debugfs_early_list); static DEFINE_MUTEX(regmap_debugfs_early_lock); @@ -539,6 +540,7 @@ void regmap_debugfs_init(struct regmap *map) struct regmap_range_node *range_node; const char *devname = "dummy"; const char *name = map->name; + int id; /* * Userspace can initiate reads from the hardware over debugfs. @@ -567,6 +569,7 @@ void regmap_debugfs_init(struct regmap *map) INIT_LIST_HEAD(&map->debugfs_off_cache); mutex_init(&map->cache_lock); + map->debugfs_dummy_id = -1; if (map->dev) devname = dev_name(map->dev); @@ -585,12 +588,16 @@ void regmap_debugfs_init(struct regmap *map) if (!strcmp(name, "dummy")) { kfree(map->debugfs_name); - map->debugfs_name = kasprintf(GFP_KERNEL, "dummy%d", - dummy_index); - if (!map->debugfs_name) + id = ida_alloc(&dummy_ida, GFP_KERNEL); + if (id < 0) return; + map->debugfs_name = kasprintf(GFP_KERNEL, "dummy%d", id); + if (!map->debugfs_name) { + ida_free(&dummy_ida, id); + return; + } + map->debugfs_dummy_id = id; name = map->debugfs_name; - dummy_index++; } map->debugfs = debugfs_create_dir(name, regmap_debugfs_root); @@ -660,6 +667,10 @@ void regmap_debugfs_exit(struct regmap *map) mutex_lock(&map->cache_lock); regmap_debugfs_free_dump_cache(map); mutex_unlock(&map->cache_lock); + if (map->debugfs_dummy_id >= 0) { + ida_free(&dummy_ida, map->debugfs_dummy_id); + map->debugfs_dummy_id = -1; + } kfree(map->debugfs_name); map->debugfs_name = NULL; } else {