Skip to content

Commit 7d69621

Browse files
zxyan0222broonie
authored andcommitted
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 <zxyan0222@gmail.com> Link: https://patch.msgid.link/20260409035015.950764-1-zxyan0222@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 1ef3e1c commit 7d69621

2 files changed

Lines changed: 17 additions & 5 deletions

File tree

drivers/base/regmap/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ struct regmap {
8484
bool debugfs_disable;
8585
struct dentry *debugfs;
8686
const char *debugfs_name;
87+
int debugfs_dummy_id;
8788

8889
unsigned int debugfs_reg_len;
8990
unsigned int debugfs_val_len;

drivers/base/regmap/regmap-debugfs.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/uaccess.h>
1313
#include <linux/device.h>
1414
#include <linux/list.h>
15+
#include <linux/idr.h>
1516

1617
#include "internal.h"
1718

@@ -20,7 +21,7 @@ struct regmap_debugfs_node {
2021
struct list_head link;
2122
};
2223

23-
static unsigned int dummy_index;
24+
static DEFINE_IDA(dummy_ida);
2425
static struct dentry *regmap_debugfs_root;
2526
static LIST_HEAD(regmap_debugfs_early_list);
2627
static DEFINE_MUTEX(regmap_debugfs_early_lock);
@@ -539,6 +540,7 @@ void regmap_debugfs_init(struct regmap *map)
539540
struct regmap_range_node *range_node;
540541
const char *devname = "dummy";
541542
const char *name = map->name;
543+
int id;
542544

543545
/*
544546
* Userspace can initiate reads from the hardware over debugfs.
@@ -567,6 +569,7 @@ void regmap_debugfs_init(struct regmap *map)
567569

568570
INIT_LIST_HEAD(&map->debugfs_off_cache);
569571
mutex_init(&map->cache_lock);
572+
map->debugfs_dummy_id = -1;
570573

571574
if (map->dev)
572575
devname = dev_name(map->dev);
@@ -585,12 +588,16 @@ void regmap_debugfs_init(struct regmap *map)
585588

586589
if (!strcmp(name, "dummy")) {
587590
kfree(map->debugfs_name);
588-
map->debugfs_name = kasprintf(GFP_KERNEL, "dummy%d",
589-
dummy_index);
590-
if (!map->debugfs_name)
591+
id = ida_alloc(&dummy_ida, GFP_KERNEL);
592+
if (id < 0)
591593
return;
594+
map->debugfs_name = kasprintf(GFP_KERNEL, "dummy%d", id);
595+
if (!map->debugfs_name) {
596+
ida_free(&dummy_ida, id);
597+
return;
598+
}
599+
map->debugfs_dummy_id = id;
592600
name = map->debugfs_name;
593-
dummy_index++;
594601
}
595602

596603
map->debugfs = debugfs_create_dir(name, regmap_debugfs_root);
@@ -660,6 +667,10 @@ void regmap_debugfs_exit(struct regmap *map)
660667
mutex_lock(&map->cache_lock);
661668
regmap_debugfs_free_dump_cache(map);
662669
mutex_unlock(&map->cache_lock);
670+
if (map->debugfs_dummy_id >= 0) {
671+
ida_free(&dummy_ida, map->debugfs_dummy_id);
672+
map->debugfs_dummy_id = -1;
673+
}
663674
kfree(map->debugfs_name);
664675
map->debugfs_name = NULL;
665676
} else {

0 commit comments

Comments
 (0)