mm/damon/sysfs-test: add a unit test for damon_sysfs_set_targets()
authorSeongJae Park <sj@kernel.org>
Sun, 22 Oct 2023 21:07:34 +0000 (21:07 +0000)
committerAndrew Morton <akpm@linux-foundation.org>
Wed, 25 Oct 2023 23:47:15 +0000 (16:47 -0700)
damon_sysfs_set_targets() had a bug that can result in unexpected memory
usage and monitoring overhead increase.  The bug has fixed by a previous
commit.  Add a unit test for avoiding a similar bug of future.

Link: https://lkml.kernel.org/r/20231022210735.46409-3-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: Brendan Higgins <brendanhiggins@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/damon/Kconfig
mm/damon/sysfs-test.h [new file with mode: 0644]
mm/damon/sysfs.c

index 436c6b4cb5ec57fb7e47d093569ec093d7ec7401..29f43fbc2eff13db0c7cc84ea1bbf0ca3700edad 100644 (file)
@@ -59,6 +59,18 @@ config DAMON_SYSFS
          This builds the sysfs interface for DAMON.  The user space can use
          the interface for arbitrary data access monitoring.
 
+config DAMON_SYSFS_KUNIT_TEST
+       bool "Test for damon debugfs interface" if !KUNIT_ALL_TESTS
+       depends on DAMON_SYSFS && KUNIT=y
+       default KUNIT_ALL_TESTS
+       help
+         This builds the DAMON sysfs interface Kunit test suite.
+
+         For more information on KUnit and unit tests in general, please refer
+         to the KUnit documentation.
+
+         If unsure, say N.
+
 config DAMON_DBGFS
        bool "DAMON debugfs interface (DEPRECATED!)"
        depends on DAMON_VADDR && DAMON_PADDR && DEBUG_FS
diff --git a/mm/damon/sysfs-test.h b/mm/damon/sysfs-test.h
new file mode 100644 (file)
index 0000000..73bdce2
--- /dev/null
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Data Access Monitor Unit Tests
+ *
+ * Author: SeongJae Park <sj@kernel.org>
+ */
+
+#ifdef CONFIG_DAMON_SYSFS_KUNIT_TEST
+
+#ifndef _DAMON_SYSFS_TEST_H
+#define _DAMON_SYSFS_TEST_H
+
+#include <kunit/test.h>
+
+static unsigned int nr_damon_targets(struct damon_ctx *ctx)
+{
+       struct damon_target *t;
+       unsigned int nr_targets = 0;
+
+       damon_for_each_target(t, ctx)
+               nr_targets++;
+
+       return nr_targets;
+}
+
+static int __damon_sysfs_test_get_any_pid(int min, int max)
+{
+       struct pid *pid;
+       int i;
+
+       for (i = min; i <= max; i++) {
+               pid = find_get_pid(i);
+               if (pid) {
+                       put_pid(pid);
+                       return i;
+               }
+       }
+       return -1;
+}
+
+static void damon_sysfs_test_set_targets(struct kunit *test)
+{
+       struct damon_sysfs_targets *sysfs_targets;
+       struct damon_sysfs_target *sysfs_target;
+       struct damon_ctx *ctx;
+
+       sysfs_targets = damon_sysfs_targets_alloc();
+       sysfs_targets->nr = 1;
+       sysfs_targets->targets_arr = kmalloc_array(1,
+                       sizeof(*sysfs_targets->targets_arr), GFP_KERNEL);
+
+       sysfs_target = damon_sysfs_target_alloc();
+       sysfs_target->pid = __damon_sysfs_test_get_any_pid(12, 100);
+       sysfs_target->regions = damon_sysfs_regions_alloc();
+       sysfs_targets->targets_arr[0] = sysfs_target;
+
+       ctx = damon_new_ctx();
+
+       damon_sysfs_set_targets(ctx, sysfs_targets);
+       KUNIT_EXPECT_EQ(test, 1u, nr_damon_targets(ctx));
+
+       sysfs_target->pid = __damon_sysfs_test_get_any_pid(
+                       sysfs_target->pid + 1, 200);
+       damon_sysfs_set_targets(ctx, sysfs_targets);
+       KUNIT_EXPECT_EQ(test, 1u, nr_damon_targets(ctx));
+
+       damon_destroy_ctx(ctx);
+       kfree(sysfs_targets->targets_arr);
+       kfree(sysfs_targets);
+       kfree(sysfs_target);
+}
+
+static struct kunit_case damon_sysfs_test_cases[] = {
+       KUNIT_CASE(damon_sysfs_test_set_targets),
+       {},
+};
+
+static struct kunit_suite damon_sysfs_test_suite = {
+       .name = "damon-sysfs",
+       .test_cases = damon_sysfs_test_cases,
+};
+kunit_test_suite(damon_sysfs_test_suite);
+
+#endif /* _DAMON_SYSFS_TEST_H */
+
+#endif /* CONFIG_DAMON_SYSFS_KUNIT_TEST */
index f73dc88d2d19366c133682eca9a237a5cfcbcd9a..5846970cedcefb90a111c78bccdd96e3f7a7badb 100644 (file)
@@ -1836,3 +1836,5 @@ out:
        return err;
 }
 subsys_initcall(damon_sysfs_init);
+
+#include "sysfs-test.h"