[PATCH 1/4] test-ww_mutex: Fix module cleanup

From: Håkon Bugge

Date: Wed Jun 17 2026 - 08:18:58 EST


When test-ww_mutex is compiled as a module, there are two bugs. One is
related to the case where the module fails to load. In that case, some
or all of the allocated objects are not released. Also, if loaded OK
and thereafter unloaded, the sysfs file is not removed.

The latter bug gives the following splat (trimmed for better brevity):

sysfs: cannot create duplicate filename '/kernel/test_ww_mutex'
dump_stack_lvl+0x5d/0x90
sysfs_warn_dup.cold+0x17/0x23
sysfs_create_dir_ns+0xe2/0x100
kobject_add_internal+0xba/0x270
kobject_add+0x95/0xd0
kobject_create_and_add+0xa3/0xd0
test_ww_mutex_init+0x90/0xff0 [test_ww_mutex]
do_one_initcall+0x5c/0x330
do_init_module+0x90/0x290
__do_sys_init_module+0x195/0x1d0
do_syscall_64+0xe8/0x550
entry_SYSCALL_64_after_hwframe+0x76/0x7e

Fixes: 2a0c11282881 ("locking/ww_mutex: Add kselftests for ww_mutex stress")
Fixes: de2c5a1523fd ("test-ww_mutex: Allow test to be run (and re-run) from userland")
Signed-off-by: Håkon Bugge <haakon.bugge@xxxxxxxxxx>
---
kernel/locking/test-ww_mutex.c | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/kernel/locking/test-ww_mutex.c b/kernel/locking/test-ww_mutex.c
index 838d631544ed2..6f56a29ed6d77 100644
--- a/kernel/locking/test-ww_mutex.c
+++ b/kernel/locking/test-ww_mutex.c
@@ -734,7 +734,7 @@ static struct kobject *test_ww_mutex_kobj;

static int __init test_ww_mutex_init(void)
{
- int ret;
+ int ret = -ENOMEM;

prandom_seed_state(&rng, get_random_u64());

@@ -743,28 +743,35 @@ static int __init test_ww_mutex_init(void)
return -ENOMEM;

test_ww_mutex_kobj = kobject_create_and_add("test_ww_mutex", kernel_kobj);
- if (!test_ww_mutex_kobj) {
- destroy_workqueue(wq);
- return -ENOMEM;
- }
+ if (!test_ww_mutex_kobj)
+ goto kobj_err;

/* Create the files associated with this kobject */
ret = sysfs_create_group(test_ww_mutex_kobj, &attr_group);
- if (ret) {
- kobject_put(test_ww_mutex_kobj);
- destroy_workqueue(wq);
- return ret;
- }
+ if (ret)
+ goto sysfs_err;

mutex_lock(&run_lock);
ret = run_test_classes();
mutex_unlock(&run_lock);

+ if (!ret)
+ return 0;
+
+ sysfs_remove_group(test_ww_mutex_kobj, &attr_group);
+
+sysfs_err:
+ kobject_put(test_ww_mutex_kobj);
+
+kobj_err:
+ destroy_workqueue(wq);
+
return ret;
}

static void __exit test_ww_mutex_exit(void)
{
+ sysfs_remove_group(test_ww_mutex_kobj, &attr_group);
kobject_put(test_ww_mutex_kobj);
destroy_workqueue(wq);
}
--
2.43.5