[RFC PATCH 0/6] mm/damon: add kunit and selftests for probes and probe weights

1 view
Skip to first unread message

SJ Park

unread,
Jul 29, 2026, 10:47:45 AMJul 29
to SJ Park, Andrew Morton, Brendan Higgins, David Gow, Shuah Khan, da...@lists.linux.dev, kuni...@googlegroups.com, linux-...@vger.kernel.org, linux-k...@vger.kernel.org, linu...@kvack.org
DAMON recently introduced probes and probe weights. Add kunit and
selftests for ensuring the parameters for features can be set using the
core API and the sysfs ABI, respectively.

SJ Park (6):
mm/damon/tests/core-kunit: test damon_commit_filter()
mm/damon/tests/core-kunit: add damon_commit_probes() test
selftests/damon/_damon_sysfs: implement DamonProbes
selftests/damon/drgn_dump_damon_status: dump probes
selftests/damon/sysfs.py: extend commit assertion function for probes
selftests/damon/sysfs.py: test damon probes

mm/damon/tests/core-kunit.h | 121 +++++++++++++++++
tools/testing/selftests/damon/_damon_sysfs.py | 123 +++++++++++++++++-
.../selftests/damon/drgn_dump_damon_status.py | 32 +++++
tools/testing/selftests/damon/sysfs.py | 35 ++++-
4 files changed, 309 insertions(+), 2 deletions(-)


base-commit: 2f558ff382eed84b9ffde4dbd630a1fc4c57fab4
--
2.47.3

SJ Park

unread,
Jul 29, 2026, 10:47:46 AMJul 29
to SJ Park, Andrew Morton, Brendan Higgins, David Gow, da...@lists.linux.dev, kuni...@googlegroups.com, linux-...@vger.kernel.org, linux-k...@vger.kernel.org, linu...@kvack.org
Add kunit test to ensure damon_commit_probes() updates destination DAMON
context with source probes as expected.

Signed-off-by: SJ Park <s...@kernel.org>
---
mm/damon/tests/core-kunit.h | 81 +++++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)

diff --git a/mm/damon/tests/core-kunit.h b/mm/damon/tests/core-kunit.h
index ff864402e9c75..d1e8c612fea03 100644
--- a/mm/damon/tests/core-kunit.h
+++ b/mm/damon/tests/core-kunit.h
@@ -1393,6 +1393,86 @@ static void damon_test_commit_filter(struct kunit *test)
});
}

+static struct damon_ctx *damon_test_help_setup_probes(unsigned int weights[],
+ int nr_weights)
+{
+ struct damon_ctx *ctx;
+ struct damon_probe *probe;
+ int i;
+
+ ctx = damon_new_ctx();
+ if (!ctx)
+ return NULL;
+ for (i = 0; i < nr_weights; i++) {
+ probe = damon_new_probe();
+ if (!probe) {
+ damon_destroy_ctx(ctx);
+ return NULL;
+ }
+ probe->weight = weights[i];
+ damon_add_probe(ctx, probe);
+ }
+ return ctx;
+}
+
+static void damon_test_commit_probes_for(struct kunit *test,
+ unsigned int dst_weights[], int nr_dst_probes,
+ unsigned int src_weights[], int nr_src_probes)
+{
+ struct damon_ctx *dst, *src;
+ int err;
+ struct damon_probe *dst_probe, *src_probe;
+
+ dst = damon_test_help_setup_probes(dst_weights, nr_dst_probes);
+ if (!dst)
+ kunit_skip(test, "dst alloc fail");
+ src = damon_test_help_setup_probes(src_weights, nr_src_probes);
+ if (!src) {
+ damon_destroy_ctx(dst);
+ kunit_skip(test, "src alloc fail");
+ }
+
+ err = damon_commit_probes(dst, src);
+ KUNIT_EXPECT_EQ(test, err, 0);
+ if (err)
+ return;
+ nr_dst_probes = 0;
+ damon_for_each_probe(dst_probe, dst)
+ nr_dst_probes++;
+ nr_src_probes = 0;
+ damon_for_each_probe(src_probe, src)
+ nr_src_probes++;
+ KUNIT_EXPECT_EQ(test, nr_dst_probes, nr_src_probes);
+ nr_dst_probes = 0;
+ damon_for_each_probe(dst_probe, dst) {
+ src_probe = damon_nth_probe(nr_dst_probes, src);
+ KUNIT_EXPECT_EQ(test, src_probe->weight, dst_probe->weight);
+ nr_dst_probes++;
+ }
+ damon_destroy_ctx(dst);
+ damon_destroy_ctx(src);
+}
+
+static void damon_test_commit_probes(struct kunit *test)
+{
+ damon_test_commit_probes_for(test,
+ (unsigned int[]){}, 0, (unsigned int[]){}, 0);
+ damon_test_commit_probes_for(test,
+ (unsigned int[]){}, 0, (unsigned int[]){1}, 1);
+ damon_test_commit_probes_for(test,
+ (unsigned int[]){}, 0, (unsigned int[]){1, 2}, 2);
+ damon_test_commit_probes_for(test,
+ (unsigned int[]){1}, 1, (unsigned int[]){2}, 1);
+ damon_test_commit_probes_for(test,
+ (unsigned int[]){1}, 1, (unsigned int[]){2, 3}, 2);
+ damon_test_commit_probes_for(test,
+ (unsigned int[]){2, 3}, 2, (unsigned int[]){1}, 1);
+ damon_test_commit_probes_for(test,
+ (unsigned int[]){2, 3}, 2, (unsigned int[]){}, 0);
+ damon_test_commit_probes_for(test,
+ (unsigned int[]){2}, 1, (unsigned int[]){}, 0);
+}
+
static void damon_test_commit_ctx(struct kunit *test)
{
struct damon_ctx *src, *dst;
@@ -1745,6 +1825,7 @@ static struct kunit_case damon_test_cases[] = {
KUNIT_CASE(damos_test_commit_migrate_hot),
KUNIT_CASE(damon_test_commit_target_regions),
KUNIT_CASE(damon_test_commit_filter),
+ KUNIT_CASE(damon_test_commit_probes),
KUNIT_CASE(damon_test_commit_ctx),
KUNIT_CASE(damos_test_filter_out),
KUNIT_CASE(damon_test_feed_loop_next_input),
--
2.47.3

SJ Park

unread,
Jul 30, 2026, 12:39:55 AMJul 30
to SJ Park, Andrew Morton, Brendan Higgins, David Gow, Shuah Khan, da...@lists.linux.dev, kuni...@googlegroups.com, linux-...@vger.kernel.org, linux-k...@vger.kernel.org, linu...@kvack.org
DAMON recently introduced probes and probe weights. Add kunit and
selftests for ensuring the parameters for features can be set using the
core API and the sysfs ABI, respectively.

Changes from RFC v1
- RFC v1: https://lore.kernel.org/202607291447...@kernel.org
- Fix a typo, memory leak and NULL dereference in kunit test.
- Fix ignored error in selftest.

SJ Park (6):
mm/damon/tests/core-kunit: test damon_commit_filter()
mm/damon/tests/core-kunit: add damon_commit_probes() test
selftests/damon/_damon_sysfs: implement DamonProbes
selftests/damon/drgn_dump_damon_status: dump probes
selftests/damon/sysfs.py: extend commit assertion function for probes
selftests/damon/sysfs.py: test damon probes

mm/damon/tests/core-kunit.h | 124 +++++++++++++++++
tools/testing/selftests/damon/_damon_sysfs.py | 125 +++++++++++++++++-
.../selftests/damon/drgn_dump_damon_status.py | 32 +++++
tools/testing/selftests/damon/sysfs.py | 35 ++++-
4 files changed, 314 insertions(+), 2 deletions(-)


base-commit: 1e413a0c40e2aca4a55f9ba664b2b7ac2a03c9da
--
2.47.3

SJ Park

unread,
Jul 30, 2026, 12:39:56 AMJul 30
to SJ Park, Andrew Morton, Brendan Higgins, David Gow, da...@lists.linux.dev, kuni...@googlegroups.com, linux-...@vger.kernel.org, linux-k...@vger.kernel.org, linu...@kvack.org
Add kunit test to ensure damon_commit_filter() updates destination
filter as expected for valid inputs.

Signed-off-by: SJ Park <s...@kernel.org>
---
mm/damon/tests/core-kunit.h | 40 +++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)

diff --git a/mm/damon/tests/core-kunit.h b/mm/damon/tests/core-kunit.h
index c7bda8aadef3f..9cd2be03aeb9b 100644
--- a/mm/damon/tests/core-kunit.h
+++ b/mm/damon/tests/core-kunit.h
@@ -1354,6 +1354,45 @@ static void damon_test_commit_target_regions(struct kunit *test)
(unsigned long[][2]) {{3, 8}, {8, 10}}, 2);
}

+static void damon_test_commit_filter_for(struct kunit *test,
+ struct damon_filter *dst, struct damon_filter *src)
+{
+ damon_commit_filter(dst, src);
+ KUNIT_EXPECT_EQ(test, dst->type, src->type);
+ KUNIT_EXPECT_EQ(test, dst->matching, src->matching);
+ KUNIT_EXPECT_EQ(test, dst->allow, src->allow);
+ switch (src->type) {
+ case DAMON_FILTER_TYPE_MEMCG:
+ KUNIT_EXPECT_EQ(test, dst->memcg_id, src->memcg_id);
+ break;
+ default:
+ break;
+ }
+}
+
+static void damon_test_commit_filter(struct kunit *test)
+{
+ struct damon_filter dst = {
+ .type = DAMON_FILTER_TYPE_ANON,
+ .matching = false,
+ .allow = false,
+ };
+
+ damon_test_commit_filter_for(test, &dst,
+ &(struct damon_filter){
+ .type = DAMON_FILTER_TYPE_ANON,
+ .matching = true,
+ .allow = true,
+ });
+ damon_test_commit_filter_for(test, &dst,
+ &(struct damon_filter){
+ .type = DAMON_FILTER_TYPE_MEMCG,
+ .matching = false,
+ .allow = false,
+ .memcg_id = 123,
+ });
+}
+
static void damon_test_commit_ctx(struct kunit *test)
{
struct damon_ctx *src, *dst;
@@ -1705,6 +1744,7 @@ static struct kunit_case damon_test_cases[] = {
KUNIT_CASE(damos_test_commit_pageout),
KUNIT_CASE(damos_test_commit_migrate_hot),
KUNIT_CASE(damon_test_commit_target_regions),
+ KUNIT_CASE(damon_test_commit_filter),

SJ Park

unread,
Jul 30, 2026, 12:39:58 AMJul 30
to SJ Park, Andrew Morton, Brendan Higgins, David Gow, da...@lists.linux.dev, kuni...@googlegroups.com, linux-...@vger.kernel.org, linux-k...@vger.kernel.org, linu...@kvack.org
Add kunit test to ensure damon_commit_probes() updates destination DAMON
context with source probes as expected.

Signed-off-by: SJ Park <s...@kernel.org>
---
mm/damon/tests/core-kunit.h | 84 +++++++++++++++++++++++++++++++++++++
1 file changed, 84 insertions(+)

diff --git a/mm/damon/tests/core-kunit.h b/mm/damon/tests/core-kunit.h
index 9cd2be03aeb9b..2ef0609b8d0e5 100644
--- a/mm/damon/tests/core-kunit.h
+++ b/mm/damon/tests/core-kunit.h
@@ -1393,6 +1393,89 @@ static void damon_test_commit_filter(struct kunit *test)
+ goto out;
+ nr_dst_probes = 0;
+ damon_for_each_probe(dst_probe, dst)
+ nr_dst_probes++;
+ nr_src_probes = 0;
+ damon_for_each_probe(src_probe, src)
+ nr_src_probes++;
+ KUNIT_EXPECT_EQ(test, nr_dst_probes, nr_src_probes);
+ if (nr_dst_probes != nr_src_probes)
+ goto out;
+ nr_dst_probes = 0;
+ damon_for_each_probe(dst_probe, dst) {
+ src_probe = damon_nth_probe(nr_dst_probes, src);
+ KUNIT_EXPECT_EQ(test, src_probe->weight, dst_probe->weight);
+ nr_dst_probes++;
+ }
+out:
+ damon_destroy_ctx(dst);
+ damon_destroy_ctx(src);
+}
+
+static void damon_test_commit_probes(struct kunit *test)
+{
+ damon_test_commit_probes_for(test,
+ (unsigned int[]){}, 0, (unsigned int[]){}, 0);
+ damon_test_commit_probes_for(test,
+ (unsigned int[]){}, 0, (unsigned int[]){1}, 1);
+ damon_test_commit_probes_for(test,
+ (unsigned int[]){}, 0, (unsigned int[]){1, 2}, 2);
+ damon_test_commit_probes_for(test,
+ (unsigned int[]){1}, 1, (unsigned int[]){2}, 1);
+ damon_test_commit_probes_for(test,
+ (unsigned int[]){1}, 1, (unsigned int[]){2, 3}, 2);
+ damon_test_commit_probes_for(test,
+ (unsigned int[]){2, 3}, 2, (unsigned int[]){1}, 1);
+ damon_test_commit_probes_for(test,
+ (unsigned int[]){2, 3}, 2, (unsigned int[]){}, 0);
+ damon_test_commit_probes_for(test,
+ (unsigned int[]){2}, 1, (unsigned int[]){}, 0);
+}
+
static void damon_test_commit_ctx(struct kunit *test)
{
struct damon_ctx *src, *dst;
@@ -1745,6 +1828,7 @@ static struct kunit_case damon_test_cases[] = {
KUNIT_CASE(damos_test_commit_migrate_hot),
KUNIT_CASE(damon_test_commit_target_regions),
KUNIT_CASE(damon_test_commit_filter),
+ KUNIT_CASE(damon_test_commit_probes),
Reply all
Reply to author
Forward
0 new messages