[PATCH] regmap: debugfs: fix race condition in dummy name allocation
From: Zxyan Zhu
Date: Wed Apr 08 2026 - 09:12:12 EST
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".
---
drivers/base/regmap/internal.h | 1 +
drivers/base/regmap/regmap-debugfs.c | 21 ++++++++++++++++-----
2 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 5bf993165438..e067890866c1 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 5a46ce5fee72..18f1c60749fe 100644
--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -12,6 +12,7 @@
#include <linux/uaccess.h>
#include <linux/device.h>
#include <linux/list.h>
+#include <linux/idr.h>
#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 {
--
2.34.1