From: Wang Xiaolei damon_sysfs_test_add_targets() creates its monitoring context with damon_new_ctx(), which leaves ctx->ops zero-initialized. Since DAMON_OPS_VADDR is zero, damon_target_has_pid() returns true for the context, and damon_sysfs_add_targets() therefore calls damon_set_target_pid() for each target it adds. That function grabs a reference to the target's struct pid via find_get_pid(). The test then tears the context down with damon_destroy_ctx(), which releases such a reference from ctx->ops.cleanup_target(). For the vaddr operations set that callback is damon_va_cleanup_target(), and it is the only place where the reference is put. The test never selects an operations set, though, so cleanup_target is NULL and both references -- one for each of the two damon_sysfs_add_targets() calls -- are leaked on every run of the test. Running the test with CONFIG_DEBUG_KMEMLEAK enabled reports the leaked struct pid objects as unreferenced. Fix this by selecting the vaddr operations set for the context before adding the targets, mirroring what the sysfs interface does. damon_select_ops() fails if the vaddr operations set is not registered, in which case the test cannot exercise the pid handling and skips itself. Fixes: b8ee5575f763 ("mm/damon/sysfs-test: add a unit test for damon_sysfs_set_targets()") Cc: Liam R. Howlett Cc: Michal Hocko Cc: Mike Rapoport Cc: Suren Baghdasaryan Cc: Vlastimil Babka Signed-off-by: Wang Xiaolei --- Changes in v2: - Fix ctx leak in the vaddr-not-registered error path (reported by Sashiko AI review) - Link to v1: https://patchwork.kernel.org/project/linux-mm/patch/20261029015725.17378-1-xiaoleiwangxiaolei@gmail.com/ mm/damon/tests/sysfs-kunit.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mm/damon/tests/sysfs-kunit.h b/mm/damon/tests/sysfs-kunit.h index 138a4b8d14e7..16373ba751db 100644 --- a/mm/damon/tests/sysfs-kunit.h +++ b/mm/damon/tests/sysfs-kunit.h @@ -79,6 +79,15 @@ static void damon_sysfs_test_add_targets(struct kunit *test) kunit_skip(test, "ctx alloc fail"); } + if (damon_select_ops(ctx, DAMON_OPS_VADDR)) { + damon_destroy_ctx(ctx); + kfree(sysfs_targets->targets_arr); + kfree(sysfs_targets); + kfree(sysfs_target->regions); + kfree(sysfs_target); + kunit_skip(test, "vaddr ops not registered"); + } + damon_sysfs_add_targets(ctx, sysfs_targets); KUNIT_EXPECT_EQ(test, 1u, nr_damon_targets(ctx)); -- 2.53.0