DAMOS_FILTER_TYPE_AGE_MS defines an inclusive range for age in milliseconds to filter for target regions. Aggregation interval can be changed by users or intervals auto-tuning features. Add a kunit test for each: - convert region age to milliseconds, correct behavior at boundaries for defined filter range - DAMOS_FILTER_TYPE_AGE_MS filter keeps correct behavior even when aggregation interval changes Signed-off-by: Jason Angelov --- 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 fb84d30a712d..6de7c2531702 100644 --- a/mm/damon/tests/core-kunit.h +++ b/mm/damon/tests/core-kunit.h @@ -1837,6 +1837,86 @@ static void damos_test_age_ms_filter_is_core(struct kunit *test) KUNIT_EXPECT_FALSE(test, damos_filter_for_ops(DAMOS_FILTER_TYPE_AGE_MS)); } +static void damos_test_age_ms_filter_interval_changes(struct kunit *test) +{ + /* Filter window: 200-400 ms. Start: 100 ms interval, age 0. */ + struct damos_filter filter = { + .type = DAMOS_FILTER_TYPE_AGE_MS, + .matching = true, + .range_min = 200, + .range_max = 400, + }; + struct damon_attrs attrs = { + .sample_interval = 5000, + .aggr_interval = 100000, + .min_nr_regions = 3, + .max_nr_regions = 3, + }; + struct damon_ctx *ctx; + struct damon_target *t; + struct damon_region *r; + int err; + + ctx = damon_new_ctx(); + if (!ctx) + kunit_skip(test, "ctx alloc fail"); + t = damon_new_target(); + if (!t) { + damon_destroy_ctx(ctx); + kunit_skip(test, "target alloc fail"); + } + damon_add_target(ctx, t); + r = damon_new_region(0, DAMON_MIN_REGION_SZ); + if (!r) { + damon_destroy_ctx(ctx); + kunit_skip(test, "region alloc fail"); + } + damon_add_region(r, t); + KUNIT_EXPECT_EQ(test, damon_set_attrs(ctx, &attrs), 0); + + /* below window: age 1 = 100 ms */ + r->age = 1; + KUNIT_EXPECT_FALSE(test, damos_filter_match(ctx, t, r, &filter, + ctx->min_region_sz, &err)); + + /* inside window: age 2 = 200 ms */ + r->age = 2; + KUNIT_EXPECT_TRUE(test, damos_filter_match(ctx, t, r, &filter, + ctx->min_region_sz, &err)); + + /* + * change aggregation interval 100 -> 200 ms: + * inside window: age rescaled 2 -> 1, still 200 ms + */ + attrs.aggr_interval = 200000; + KUNIT_EXPECT_EQ(test, damon_set_attrs(ctx, &attrs), 0); + KUNIT_EXPECT_EQ(test, r->age, 1u); + KUNIT_EXPECT_TRUE(test, damos_filter_match(ctx, t, r, &filter, + ctx->min_region_sz, &err)); + + /* inside window: age 2 = 400 ms. */ + r->age = 2; + KUNIT_EXPECT_TRUE(test, damos_filter_match(ctx, t, r, &filter, + ctx->min_region_sz, &err)); + + /* + * change aggregation interval 200 -> 50 ms: + * inside window: age rescaled 2 -> 8, still 400 ms. + */ + attrs.aggr_interval = 50000; + KUNIT_EXPECT_EQ(test, damon_set_attrs(ctx, &attrs), 0); + KUNIT_EXPECT_EQ(test, r->age, 8u); + KUNIT_EXPECT_TRUE(test, damos_filter_match(ctx, t, r, &filter, + ctx->min_region_sz, &err)); + + /* above window: age 9 = 450 ms. */ + r->age = 9; + KUNIT_EXPECT_FALSE(test, damos_filter_match(ctx, t, r, &filter, + ctx->min_region_sz, &err)); + + damon_destroy_ctx(ctx); +} + static void damos_test_filter_out(struct kunit *test) { struct damon_target *t; @@ -2599,6 +2679,7 @@ static struct kunit_case damon_test_cases[] = { KUNIT_CASE(damon_test_commit_ctx_keeps_quota), KUNIT_CASE(damon_test_valid_probe_params), KUNIT_CASE(damos_test_age_ms_filter_is_core), + KUNIT_CASE(damos_test_age_ms_filter_interval_changes), KUNIT_CASE(damos_test_filter_out), KUNIT_CASE(damos_test_apply_scheme_filtered_sz), KUNIT_CASE(damos_test_apply_scheme_filter_sz_unchanged), -- 2.53.0