mm-damon-tests-core-kunit-test-the-size-charged-for-a-filter-trimmed-region.patch removed from -mm tree
The quilt patch titled
Subject: mm/damon/tests/core-kunit: test the size charged for a filter-trimmed region
has been removed from the -mm tree. Its filename was
mm-damon-tests-core-kunit-test-the-size-charged-for-a-filter-trimmed-region.patch
This patch was dropped because it was merged into the mm-stable branch of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
------------------------------------------------------
From: Donggeun Yoo <[email protected]>
Subject: mm/damon/tests/core-kunit: test the size charged for a filter-trimmed region
Date: Mon, 21 Sep 2026 08:24:42 -0700
damos_test_filter_out() checks that an address range filter splits a region at the filter boundary, and stops there. Nothing checks what damos_apply_scheme() then charges to the quota and reports as tried.
damos_test_apply_scheme_filtered_sz() covers the two ways such a filter trims a region: one that starts before the filter's range, and one that starts inside it.
damos_test_apply_scheme_filter_sz_unchanged() and damos_test_apply_scheme_quota_sz() cover the cases whose accounting must not change: a region wholly inside a reject range, one wholly inside an allow range, two filters trimming in a single call, a filter type that never splits, no filter at all, a region the quota trims, and a quota remainder too small for one region.
---
mm/damon/tests/core-kunit.h | 316 ++++++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+)
mm/damon/tests/core-kunit.h renamed from mm/damon/tests/core-kunit.h~mm-damon-tests-core-kunit-test-the-size-charged-for-a-filter-trimmed-region +316 -0
@@ -1706,6 +1706,319 @@ out:damos_free_filter (f); } +static unsigned long damos_test_apply_scheme_stub (struct damon_ctx *c, +struct damon_target *t,struct damon_region *r, +struct damos *s,unsigned long *sz_filter_passed) +{ +return 0 ; +} + +static void damos_test_apply_scheme_filtered_sz (struct kunit *test) +{ +struct damos_access_pattern pattern = { + .min_sz_region =0 , + .max_sz_region =ULONG_MAX , + .min_nr_accesses =0 , + .max_nr_accesses =UINT_MAX , + .min_age_region =0 , + .max_age_region =UINT_MAX , + }; +unsigned long min_sz =DAMON_MIN_REGION_SZ ; +struct damos_watermarks wmarks = {}; +struct damos_quota quota = {}; +struct damon_ctx *c; +struct damon_target *t; +struct damon_region *r; +struct damos_filter *f; +struct damos *s; + + c =damon_new_ctx (); +if (!c) +kunit_skip (test,"ctx alloc fail" ); + c->ops.apply_scheme = damos_test_apply_scheme_stub; + + s =damon_new_scheme (&pattern,DAMOS_STAT ,0 , "a, &wmarks, +NUMA_NO_NODE ); +if (!s) { +damon_destroy_ctx (c); +kunit_skip (test,"scheme alloc fail" ); + } +damon_add_scheme (c, s); + + t =damon_new_target (); +if (!t) { +damon_destroy_ctx (c); +kunit_skip (test,"target alloc fail" ); + } +damon_add_target (c, t); + + f =damos_new_filter (DAMOS_FILTER_TYPE_ADDR , true, false); +if (!f) { +damon_destroy_ctx (c); +kunit_skip (test,"filter alloc fail" ); + } + f->addr_range = (struct damon_addr_range ){ + .start =2 * min_sz, + .end =8 * min_sz + }; +damos_add_filter (s, f); +damos_set_filters_default_reject (s); + +/* reject filter, region starting before the range */ + r =damon_new_region (0 ,4 * min_sz); +if (!r) { +damon_destroy_ctx (c); +kunit_skip (test,"region alloc fail" ); + } +damon_add_region (r, t); + +damos_apply_scheme (c, t, r, s); +KUNIT_EXPECT_EQ (test,damon_nr_regions (t),2 ); +KUNIT_EXPECT_EQ (test, r->ar.end,2 * min_sz); +KUNIT_EXPECT_EQ (test, s->stat.sz_tried,2 * min_sz); + +if (damon_nr_regions (t) !=2 ) + goto out; +damon_destroy_region (damon_next_region (r), t); +damon_destroy_region (r, t); + s->stat = (struct damos_stat ){}; + +/* allow filter, region starting inside the range */ + f->allow = true; +damos_set_filters_default_reject (s); + r =damon_new_region (2 * min_sz,10 * min_sz); +if (!r) { +damon_destroy_ctx (c); +kunit_skip (test,"region alloc fail" ); + } +damon_add_region (r, t); + +damos_apply_scheme (c, t, r, s); +KUNIT_EXPECT_EQ (test,damon_nr_regions (t),2 ); +KUNIT_EXPECT_EQ (test, r->ar.end,8 * min_sz); +KUNIT_EXPECT_EQ (test, s->stat.sz_tried,6 * min_sz); + +out: +damon_destroy_ctx (c); +} + +static void damos_test_apply_scheme_filter_sz_unchanged (struct kunit *test) +{ +struct damos_access_pattern pattern = { + .min_sz_region =0 , + .max_sz_region =ULONG_MAX , + .min_nr_accesses =0 , + .max_nr_accesses =UINT_MAX , + .min_age_region =0 , + .max_age_region =UINT_MAX , + }; +unsigned long min_sz =DAMON_MIN_REGION_SZ ; +struct damos_watermarks wmarks = {}; +struct damos_quota quota = {}; +struct damos_filter *f, *f2; +struct damon_ctx *c; +struct damon_target *t; +struct damon_region *r; +struct damos *s; + + c =damon_new_ctx (); +if (!c) +kunit_skip (test,"ctx alloc fail" ); + c->ops.apply_scheme = damos_test_apply_scheme_stub; + + s =damon_new_scheme (&pattern,DAMOS_STAT ,0 , "a, &wmarks, +NUMA_NO_NODE ); +if (!s) { +damon_destroy_ctx (c); +kunit_skip (test,"scheme alloc fail" ); + } +damon_add_scheme (c, s); + + t =damon_new_target (); +if (!t) { +damon_destroy_ctx (c); +kunit_skip (test,"target alloc fail" ); + } +damon_add_target (c, t); + + f =damos_new_filter (DAMOS_FILTER_TYPE_ADDR , true, false); +if (!f) { +damon_destroy_ctx (c); +kunit_skip (test,"filter alloc fail" ); + } + f->addr_range = (struct damon_addr_range ){ + .start =2 * min_sz, .end =8 * min_sz}; +damos_add_filter (s, f); +damos_set_filters_default_reject (s); + +/* wholly inside a reject range: not counted at all */ + r =damon_new_region (4 * min_sz,6 * min_sz); +if (!r) { +damon_destroy_ctx (c); +kunit_skip (test,"region alloc fail" ); + } +damon_add_region (r, t); + +damos_apply_scheme (c, t, r, s); +KUNIT_EXPECT_EQ (test, s->stat.nr_tried,0 ); +KUNIT_EXPECT_EQ (test, s->stat.sz_tried,0 ); +KUNIT_EXPECT_EQ (test,damon_nr_regions (t),1 ); + +/* wholly inside an allow range: counted whole, not split */ + f->allow = true; +damos_set_filters_default_reject (s); + +damos_apply_scheme (c, t, r, s); +KUNIT_EXPECT_EQ (test, s->stat.sz_tried,2 * min_sz); +KUNIT_EXPECT_EQ (test,damon_nr_regions (t),1 ); + +/* two filters, each trimming: the size left after both is counted */ +damon_destroy_region (r, t); + s->stat = (struct damos_stat ){}; + f->allow = false; + f->addr_range = (struct damon_addr_range ){ + .start =4 * min_sz, .end =12 * min_sz}; + f2 =damos_new_filter (DAMOS_FILTER_TYPE_ADDR , true, false); +if (!f2) { +damon_destroy_ctx (c); +kunit_skip (test,"filter alloc fail" ); + } + f2->addr_range = (struct damon_addr_range ){ + .start =2 * min_sz, .end =3 * min_sz}; +damos_add_filter (s, f2); +damos_set_filters_default_reject (s); + + r =damon_new_region (0 ,8 * min_sz); +if (!r) { +damon_destroy_ctx (c); +kunit_skip (test,"region alloc fail" ); + } +damon_add_region (r, t); + +damos_apply_scheme (c, t, r, s); +KUNIT_EXPECT_EQ (test,damon_nr_regions (t),3 ); +KUNIT_EXPECT_EQ (test, r->ar.end,2 * min_sz); +KUNIT_EXPECT_EQ (test, s->stat.sz_tried,2 * min_sz); + +/* a core filter that never splits: counted whole */ +damos_destroy_filter (f2); +damos_destroy_filter (f); + f =damos_new_filter (DAMOS_FILTER_TYPE_TARGET , true, true); +if (!f) { +damon_destroy_ctx (c); +kunit_skip (test,"filter alloc fail" ); + } + f->target_idx =0 ; +damos_add_filter (s, f); +damos_set_filters_default_reject (s); + s->stat = (struct damos_stat ){}; + +damos_apply_scheme (c, t, r, s); +KUNIT_EXPECT_EQ (test,damon_nr_regions (t),3 ); +KUNIT_EXPECT_EQ (test, r->ar.end,2 * min_sz); +KUNIT_EXPECT_EQ (test, s->stat.sz_tried,2 * min_sz); + +damon_destroy_ctx (c); +} + +static void damos_test_apply_scheme_quota_sz (struct kunit *test) +{ +struct damos_access_pattern pattern = { + .min_sz_region =0 , + .max_sz_region =ULONG_MAX , + .min_nr_accesses =0 , + .max_nr_accesses =UINT_MAX , + .min_age_region =0 , + .max_age_region =UINT_MAX , + }; +unsigned long min_sz =DAMON_MIN_REGION_SZ ; +struct damos_watermarks wmarks = {}; +struct damos_quota quota = {}; +struct damon_region *r, *next; +struct damon_ctx *c; +struct damon_target *t; +struct damos *s; + + c =damon_new_ctx (); +if (!c) +kunit_skip (test,"ctx alloc fail" ); + + s =damon_new_scheme (&pattern,DAMOS_STAT ,0 , "a, &wmarks, +NUMA_NO_NODE ); +if (!s) { +damon_destroy_ctx (c); +kunit_skip (test,"scheme alloc fail" ); + } +damon_add_scheme (c, s); +damos_set_filters_default_reject (s); + + t =damon_new_target (); +if (!t) { +damon_destroy_ctx (c); +kunit_skip (test,"target alloc fail" ); + } +damon_add_target (c, t); + +/* no apply_scheme operation: the whole region is counted */ + r =damon_new_region (0 ,4 * min_sz); +if (!r) { +damon_destroy_ctx (c); +kunit_skip (test,"region alloc fail" ); + } +damon_add_region (r, t); + +damos_apply_scheme (c, t, r, s); +KUNIT_EXPECT_EQ (test, s->stat.sz_tried,4 * min_sz); +KUNIT_EXPECT_EQ (test,damon_nr_regions (t),1 ); + +/* no filter and no quota: the whole region is counted */ + c->ops.apply_scheme = damos_test_apply_scheme_stub; + s->stat = (struct damos_stat ){}; + +damos_apply_scheme (c, t, r, s); +KUNIT_EXPECT_EQ (test, s->stat.sz_tried,4 * min_sz); +KUNIT_EXPECT_EQ (test,damon_nr_regions (t),1 ); + +/* the quota trims the region: the trimmed size is counted */ +damon_for_each_region_safe (r, next, t) +damon_destroy_region (r, t); + s->stat = (struct damos_stat ){}; + s->quota.esz =2 * min_sz; + s->quota.charged_sz =0 ; + + r =damon_new_region (0 ,8 * min_sz); +if (!r) { +damon_destroy_ctx (c); +kunit_skip (test,"region alloc fail" ); + } +damon_add_region (r, t); + +damos_apply_scheme (c, t, r, s); +KUNIT_EXPECT_EQ (test, r->ar.end,2 * min_sz); +KUNIT_EXPECT_EQ (test, s->stat.sz_tried,2 * min_sz); + +/* quota remainder below one region: tried, but nothing counted */ +damon_for_each_region_safe (r, next, t) +damon_destroy_region (r, t); + s->stat = (struct damos_stat ){}; + s->quota.esz =1 ; + s->quota.charged_sz =0 ; + + r =damon_new_region (0 ,4 * min_sz); +if (!r) { +damon_destroy_ctx (c); +kunit_skip (test,"region alloc fail" ); + } +damon_add_region (r, t); + +damos_apply_scheme (c, t, r, s); +KUNIT_EXPECT_EQ (test, s->stat.nr_tried,1 ); +KUNIT_EXPECT_EQ (test, s->stat.sz_tried,0 ); +KUNIT_EXPECT_EQ (test, r->ar.end,4 * min_sz); + +damon_destroy_ctx (c); +} +static void damon_test_feed_loop_next_input (struct kunit *test) {unsigned long last_input =900000 , current_score =200 ;
@@ -1959,6 +2272,9 @@ static struct kunit_case damon_test_caseKUNIT_CASE (damon_test_commit_ctx),KUNIT_CASE (damon_test_valid_probe_params),KUNIT_CASE (damos_test_filter_out), +KUNIT_CASE (damos_test_apply_scheme_filtered_sz), +KUNIT_CASE (damos_test_apply_scheme_filter_sz_unchanged), +KUNIT_CASE (damos_test_apply_scheme_quota_sz),KUNIT_CASE (damon_test_feed_loop_next_input),KUNIT_CASE (damon_test_set_filters_default_reject), KUNIT_CASE(damon_test_apply_min_nr_regions),
_
Patches currently in -mm which might be from [email protected] are
userfaultfd-clear-the-inherited-uffd-bit-in-move_swap_pte.patch mm-damon-core-prevent-size-quota-overflow-in-the-temporal-goal-tuner.patch mm-damon-tests-core-kunit-test-the-temporal-tuners-size-quota-conversion.patch