* [PATCH 0/2] mm/damon: fix zero quota for PSI goals under the temporal tuner
@ 2026-09-15 6:09 Karl Mehltretter
2026-09-15 6:09 ` [PATCH 1/2] mm/damon/core: score an unmeasured PSI goal as not achieved for " Karl Mehltretter
2026-09-15 6:09 ` [PATCH 2/2] mm/damon/tests/core-kunit: test PSI goal rounds under " Karl Mehltretter
0 siblings, 2 replies; 9+ messages in thread
From: Karl Mehltretter @ 2026-09-15 6:09 UTC (permalink / raw)
To: SJ Park
Cc: Karl Mehltretter, Andrew Morton, Lian Wang, Kunwu Chan, damon,
linux-mm, linux-kernel
A PSI quota goal without a previous sample is scored as achieved.
With the temporal tuner, this sets the quota to zero for the first
charge window and the window after each goal commit.
The series is based on next-20260911. It fixes commit a68878f83ae6
("mm/damon/core: handle uninitialized damos_quota_goal->last_psi_total"),
which is in mm-new and tagged for stable. Please carry this fix with
it.
Patch 1 keeps the temporal quota active until a PSI delta is
available. Patch 2 adds a regression test for the first round, the
next measured round, the round after a goal commit, a measured round
that reaches the target, and the consist tuner's unmeasured round.
Reproduced with damo 3.4.0 (b41965a) in a QEMU guest running
next-20260911 (x86_64, CONFIG_DAMON_SYSFS=y, CONFIG_PSI=y):
damo start --damos_action stat --damos_quota_interval 120000 \
--damos_quota_space 1048576 \
--damos_quota_goal some_mem_psi_us 100000000000 \
--damos_quota_goal_tuner temporal
then reading quotas/effective_bytes after update_schemes_effective_quotas
every 18 seconds. Without patch 1 the effective quota is 0 for the whole
first 120 second window and again for the window after "damo tune" with
the same parameters. With patch 1 it is 1048576 throughout.
The KUnit test in patch 2 fails without patch 1 and passes with it on
x86_64 and i386 (CONFIG_DAMON_KUNIT_TEST=y, built-in KUnit run at boot).
Karl Mehltretter (2):
mm/damon/core: score an unmeasured PSI goal as not achieved for the
temporal tuner
mm/damon/tests/core-kunit: test PSI goal rounds under the temporal
tuner
mm/damon/core.c | 14 +++++---
mm/damon/tests/core-kunit.h | 69 +++++++++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+), 4 deletions(-)
base-commit: 68142f986ff04b2b70b31db00f719bf690f64a9a
--
2.53.0
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 1/2] mm/damon/core: score an unmeasured PSI goal as not achieved for the temporal tuner 2026-09-15 6:09 [PATCH 0/2] mm/damon: fix zero quota for PSI goals under the temporal tuner Karl Mehltretter @ 2026-09-15 6:09 ` Karl Mehltretter 2026-09-15 14:50 ` SJ Park 2026-09-15 6:09 ` [PATCH 2/2] mm/damon/tests/core-kunit: test PSI goal rounds under " Karl Mehltretter 1 sibling, 1 reply; 9+ messages in thread From: Karl Mehltretter @ 2026-09-15 6:09 UTC (permalink / raw) To: SJ Park Cc: Karl Mehltretter, Andrew Morton, Lian Wang, Kunwu Chan, damon, linux-mm, linux-kernel A newly created or committed PSI quota goal has no previous sample. Commit a68878f83ae6 ("mm/damon/core: handle uninitialized damos_quota_goal->last_psi_total") scores the first tuning round as achieved to preserve the consist tuner's quota, since the feedback loop returns its input unchanged at that score. The temporal tuner sets the quota to zero for an achieved goal. This skips the first charge window and the window after each goal commit. Committing the PSI goal before every tuning round keeps the scheme idle indefinitely. Score an unmeasured PSI goal as not achieved for the temporal tuner, so a new scheme can run in its first window. Keep the consist tuner's behaviour unchanged. Fixes: a68878f83ae6 ("mm/damon/core: handle uninitialized damos_quota_goal->last_psi_total") Cc: <stable@vger.kernel.org> # 7.1.x Assisted-by: LLM Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com> --- mm/damon/core.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/mm/damon/core.c b/mm/damon/core.c index 06cf2ab7e97d..e6d87fd3992e 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -3161,12 +3161,18 @@ static void damos_set_quota_goal_current_value(struct damon_ctx *c, break; case DAMOS_QUOTA_SOME_MEM_PSI_US: now_psi_total = damos_get_some_mem_psi_total(); - /* uninitialized last_psi_total; make no effect this round */ - if (goal->last_psi_total == U64_MAX) - goal->current_value = goal->target_value; - else + if (goal->last_psi_total == U64_MAX) { + /* uninitialized last_psi_total; make no effect this round */ + if (s->quota.goal_tuner == + DAMOS_QUOTA_GOAL_TUNER_TEMPORAL) + /* an achieved score would zero the temporal quota */ + goal->current_value = 0; + else + goal->current_value = goal->target_value; + } else { goal->current_value = now_psi_total - goal->last_psi_total; + } goal->last_psi_total = now_psi_total; break; case DAMOS_QUOTA_NODE_MEM_USED_BP: -- 2.53.0 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] mm/damon/core: score an unmeasured PSI goal as not achieved for the temporal tuner 2026-09-15 6:09 ` [PATCH 1/2] mm/damon/core: score an unmeasured PSI goal as not achieved for " Karl Mehltretter @ 2026-09-15 14:50 ` SJ Park 2026-09-15 21:19 ` Karl Mehltretter 0 siblings, 1 reply; 9+ messages in thread From: SJ Park @ 2026-09-15 14:50 UTC (permalink / raw) To: Karl Mehltretter Cc: SJ Park, Andrew Morton, Lian Wang, Kunwu Chan, damon, linux-mm, linux-kernel Hello Karl, On Tue, 15 Sep 2026 08:09:36 +0200 Karl Mehltretter <kmehltretter@gmail.com> wrote: > A newly created or committed PSI quota goal has no previous sample. > Commit a68878f83ae6 ("mm/damon/core: handle uninitialized > damos_quota_goal->last_psi_total") scores the first tuning round as > achieved to preserve the consist tuner's quota, since the feedback > loop returns its input unchanged at that score. > > The temporal tuner sets the quota to zero for an achieved goal. This > skips the first charge window and the window after each goal commit. > Committing the PSI goal before every tuning round keeps the scheme > idle indefinitely. > > Score an unmeasured PSI goal as not achieved for the temporal tuner, > so a new scheme can run in its first window. Keep the consist tuner's > behaviour unchanged. Good catch, thank you. > > Fixes: a68878f83ae6 ("mm/damon/core: handle uninitialized damos_quota_goal->last_psi_total") > Cc: <stable@vger.kernel.org> # 7.1.x > Assisted-by: LLM > Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com> > --- > mm/damon/core.c | 14 ++++++++++---- > 1 file changed, 10 insertions(+), 4 deletions(-) > > diff --git a/mm/damon/core.c b/mm/damon/core.c > index 06cf2ab7e97d..e6d87fd3992e 100644 > --- a/mm/damon/core.c > +++ b/mm/damon/core.c > @@ -3161,12 +3161,18 @@ static void damos_set_quota_goal_current_value(struct damon_ctx *c, > break; > case DAMOS_QUOTA_SOME_MEM_PSI_US: > now_psi_total = damos_get_some_mem_psi_total(); > - /* uninitialized last_psi_total; make no effect this round */ > - if (goal->last_psi_total == U64_MAX) > - goal->current_value = goal->target_value; > - else > + if (goal->last_psi_total == U64_MAX) { > + /* uninitialized last_psi_total; make no effect this round */ > + if (s->quota.goal_tuner == > + DAMOS_QUOTA_GOAL_TUNER_TEMPORAL) > + /* an achieved score would zero the temporal quota */ > + goal->current_value = 0; > + else > + goal->current_value = goal->target_value; > + } else { The intention is to make no effect this round. Setting current_value to zero to temporal tuner means it will now have highest quota it could have. If the effective quota before this was zero, it gets an effect. Ideally, we should somehow remember what was the last esz and keep it. I have no good idea for doing that with minimum change. This is a corner case in my opinion (correct me if I'm wrong) so I want to keep the change as simple as possible. If there is not easy way to do that, I think just keeping the behavior but making it explicitly explained might be better. What do you think, Karl? Thanks, SJ [...] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] mm/damon/core: score an unmeasured PSI goal as not achieved for the temporal tuner 2026-09-15 14:50 ` SJ Park @ 2026-09-15 21:19 ` Karl Mehltretter 2026-09-16 0:13 ` SJ Park 0 siblings, 1 reply; 9+ messages in thread From: Karl Mehltretter @ 2026-09-15 21:19 UTC (permalink / raw) To: SJ Park Cc: Andrew Morton, Lian Wang, Kunwu Chan, damon, linux-mm, linux-kernel On Tue, Sep 15, 2026 at 07:50:54AM +0100, SJ Park wrote: > > The intention is to make no effect this round. Setting current_value to zero > to temporal tuner means it will now have highest quota it could have. If the > effective quota before this was zero, it gets an effect. > > Ideally, we should somehow remember what was the last esz and keep it. I have > no good idea for doing that with minimum change. This is a corner case in my > opinion (correct me if I'm wrong) so I want to keep the change as simple as > possible. > > If there is not easy way to do that, I think just keeping the behavior but > making it explicitly explained might be better. > Hello SJ, I believe I have a version that addresses your concern without adding too much complexity. In short, it leaves the tuners as they are and instead keeps last_psi_total across a commit of an existing PSI goal, as the code did before a68878f83ae6. The U64_MAX round then happens only once per new goal. That also covers anything that commits before every tuning round, like the user_input feedback path or "damo tune", which currently never gets a measured round on either tuner. I will test that and send it as v2. Thanks, Karl ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] mm/damon/core: score an unmeasured PSI goal as not achieved for the temporal tuner 2026-09-15 21:19 ` Karl Mehltretter @ 2026-09-16 0:13 ` SJ Park 0 siblings, 0 replies; 9+ messages in thread From: SJ Park @ 2026-09-16 0:13 UTC (permalink / raw) To: Karl Mehltretter Cc: SJ Park, Andrew Morton, Lian Wang, Kunwu Chan, damon, linux-mm, linux-kernel On Tue, 15 Sep 2026 23:19:27 +0200 Karl Mehltretter <kmehltretter@gmail.com> wrote: > On Tue, Sep 15, 2026 at 07:50:54AM +0100, SJ Park wrote: > > > > The intention is to make no effect this round. Setting current_value to zero > > to temporal tuner means it will now have highest quota it could have. If the > > effective quota before this was zero, it gets an effect. > > > > Ideally, we should somehow remember what was the last esz and keep it. I have > > no good idea for doing that with minimum change. This is a corner case in my > > opinion (correct me if I'm wrong) so I want to keep the change as simple as > > possible. > > > > If there is not easy way to do that, I think just keeping the behavior but > > making it explicitly explained might be better. > > > > Hello SJ, > > I believe I have a version that addresses your concern without adding > too much complexity. Thank you for keep pursuing on improving DAMON, Karl! > > In short, it leaves the tuners as they are and instead keeps > last_psi_total across a commit of an existing PSI goal, as the code > did before a68878f83ae6. The U64_MAX round then happens only once per > new goal. I actually considered this option when working on commit a68878f83ae6. I had two following concerns though. First, if the user commits multiple times before the next quota reset interval, the next tuning round will work with pressure times that cumulated for longer than the quota reset interval. This is a quite rare corner case, but I didn't feel that comfortable. Second, the behavior for new commit and update commit is different. So I'd still prefer to just making no effect this round. And my commit was failed at doing that, because it didn't aware of temporal tuner. Maybe we could show whether the goal was achieved or not, using esz and let the tuner show same achieveness? What about something like below? ''' --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -3187,6 +3187,25 @@ static inline u64 damos_get_some_mem_psi_total(void) #endif /* CONFIG_PSI */ +static void damos_set_psi_current_val(u64 now_psi_total, struct + damos_quota_goal *goal, struct damos *s) +{ + if (goal->last_psi_total != U64_MAX) { + goal->current_value = now_psi_total - goal->last_psi_total; + return; + } + /* Uninitialized last_psi_total; make no effect this round */ + if (s->quota.goal_tuner == DAMOS_QUOTA_GOAL_TUNER_CONSIST) { + goal->current_value = goal->target_value; + return; + } + /* Let temporal tuner show goal achieveness same to the last round */ + if (!s->quota.esz) + goal->current_value = goal->target_value; + else + goal->current_value = 0; +} + #ifdef CONFIG_NUMA static bool invalid_mem_node(int nid) { @@ -3439,12 +3458,7 @@ static void damos_set_quota_goal_current_value(struct damon_ctx *c, break; case DAMOS_QUOTA_SOME_MEM_PSI_US: now_psi_total = damos_get_some_mem_psi_total(); - /* uninitialized last_psi_total; make no effect this round */ - if (goal->last_psi_total == U64_MAX) - goal->current_value = goal->target_value; - else - goal->current_value = now_psi_total - - goal->last_psi_total; + damos_set_psi_current_val(now_psi_total, goal, s); goal->last_psi_total = now_psi_total; break; case DAMOS_QUOTA_NODE_MEM_USED_BP: ''' The code could further cleaned and optimized, but hopefully that will give you my rough idea. What do you think? Thanks, SJ [...] ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/2] mm/damon/tests/core-kunit: test PSI goal rounds under the temporal tuner 2026-09-15 6:09 [PATCH 0/2] mm/damon: fix zero quota for PSI goals under the temporal tuner Karl Mehltretter 2026-09-15 6:09 ` [PATCH 1/2] mm/damon/core: score an unmeasured PSI goal as not achieved for " Karl Mehltretter @ 2026-09-15 6:09 ` Karl Mehltretter 2026-09-15 7:04 ` KunWu Chan 2026-09-16 0:21 ` SJ Park 1 sibling, 2 replies; 9+ messages in thread From: Karl Mehltretter @ 2026-09-15 6:09 UTC (permalink / raw) To: SJ Park Cc: Karl Mehltretter, Andrew Morton, Lian Wang, Kunwu Chan, damon, linux-mm, linux-kernel Exercise a PSI quota goal under the temporal tuner on its first round, its next measured round, and after a goal commit. Use ULONG_MAX as the target so the goal is not reached during the test. Then check that a measured round which does reach the target sets the quota to zero, and that the consist tuner keeps its quota over an unmeasured round. Without the previous patch, the first and the post-commit checks see a zero quota. Assisted-by: LLM Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com> --- mm/damon/tests/core-kunit.h | 69 +++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/mm/damon/tests/core-kunit.h b/mm/damon/tests/core-kunit.h index c01e6a75cadc..2b9b24ce7dad 100644 --- a/mm/damon/tests/core-kunit.h +++ b/mm/damon/tests/core-kunit.h @@ -889,6 +889,74 @@ static void damos_test_commit_quota_goal(struct kunit *test) }); } +/* + * Unmeasured PSI goals must not disable the temporal quota. + * Keep sz * 10000 within a 32-bit unsigned long. + */ +static void damos_test_set_effective_quota_temporal_psi(struct kunit *test) +{ + struct damon_ctx *c = damon_new_ctx(); + struct damos_access_pattern pattern = {}; + struct damos_quota quota = { + .sz = SZ_64K, + .goal_tuner = DAMOS_QUOTA_GOAL_TUNER_TEMPORAL, + }; + struct damos_watermarks wmarks = {}; + struct damos_quota_goal src = { + .metric = DAMOS_QUOTA_SOME_MEM_PSI_US, + .target_value = ULONG_MAX, + }; + struct damos_quota_goal *goal; + struct damos *s; + + 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); + goal = damos_new_quota_goal(DAMOS_QUOTA_SOME_MEM_PSI_US, ULONG_MAX); + if (!goal) { + damon_destroy_ctx(c); + kunit_skip(test, "goal alloc fail"); + } + damos_add_quota_goal(&s->quota, goal); + + /* fresh goal, first tuning round */ + damos_set_effective_quota(c, s); + KUNIT_EXPECT_EQ(test, s->quota.esz, (unsigned long)SZ_64K); + + /* second round: last_psi_total is initialised now */ + damos_set_effective_quota(c, s); + KUNIT_EXPECT_EQ(test, s->quota.esz, (unsigned long)SZ_64K); + + /* commit a PSI goal onto the initialised PSI goal */ + damos_commit_quota_goal(goal, &src); + damos_set_effective_quota(c, s); + KUNIT_EXPECT_EQ(test, s->quota.esz, (unsigned long)SZ_64K); + + /* a measured round that reaches the target disables the quota */ + goal->target_value = 10; + goal->last_psi_total = damos_get_some_mem_psi_total() - 10; + /* U64_MAX marks an unmeasured goal, keep the sample away from it */ + if (goal->last_psi_total == U64_MAX) + goal->last_psi_total--; + damos_set_effective_quota(c, s); + KUNIT_EXPECT_EQ(test, s->quota.esz, 0ul); + + /* the consist tuner keeps its quota over an unmeasured round */ + s->quota.goal_tuner = DAMOS_QUOTA_GOAL_TUNER_CONSIST; + s->quota.esz_bp = SZ_32K * 10000; + damos_commit_quota_goal(goal, &src); + damos_set_effective_quota(c, s); + KUNIT_EXPECT_EQ(test, s->quota.esz, (unsigned long)SZ_32K); + + damon_destroy_ctx(c); +} + static void damos_test_commit_quota_goals_for(struct kunit *test, struct damos_quota_goal *dst_goals, int nr_dst_goals, struct damos_quota_goal *src_goals, int nr_src_goals) @@ -1887,6 +1955,7 @@ static struct kunit_case damon_test_cases[] = { KUNIT_CASE(damos_test_new_filter), KUNIT_CASE(damos_test_commit_quota_goal), KUNIT_CASE(damos_test_commit_quota_goals), + KUNIT_CASE(damos_test_set_effective_quota_temporal_psi), KUNIT_CASE(damos_test_commit_quota), KUNIT_CASE(damos_test_commit_dests), KUNIT_CASE(damos_test_commit_filter), -- 2.53.0 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] mm/damon/tests/core-kunit: test PSI goal rounds under the temporal tuner 2026-09-15 6:09 ` [PATCH 2/2] mm/damon/tests/core-kunit: test PSI goal rounds under " Karl Mehltretter @ 2026-09-15 7:04 ` KunWu Chan 2026-09-15 21:31 ` Karl Mehltretter 2026-09-16 0:21 ` SJ Park 1 sibling, 1 reply; 9+ messages in thread From: KunWu Chan @ 2026-09-15 7:04 UTC (permalink / raw) To: Karl Mehltretter Cc: SJ Park, Andrew Morton, Lian Wang, damon, linux-mm, linux-kernel On Tue, Sep 15, 2026 at 2:09 PM Karl Mehltretter <kmehltretter@gmail.com> wrote: > > Exercise a PSI quota goal under the temporal tuner on its first > round, its next measured round, and after a goal commit. Use > ULONG_MAX as the target so the goal is not reached during the test. > Then check that a measured round which does reach the target sets > the quota to zero, and that the consist tuner keeps its quota over > an unmeasured round. > > Without the previous patch, the first and the post-commit checks see > a zero quota. > > Assisted-by: LLM > Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com> > --- > mm/damon/tests/core-kunit.h | 69 +++++++++++++++++++++++++++++++++++++ > 1 file changed, 69 insertions(+) > > diff --git a/mm/damon/tests/core-kunit.h b/mm/damon/tests/core-kunit.h > index c01e6a75cadc..2b9b24ce7dad 100644 > --- a/mm/damon/tests/core-kunit.h > +++ b/mm/damon/tests/core-kunit.h > @@ -889,6 +889,74 @@ static void damos_test_commit_quota_goal(struct kunit *test) > }); > } > > +/* > + * Unmeasured PSI goals must not disable the temporal quota. > + * Keep sz * 10000 within a 32-bit unsigned long. > + */ > +static void damos_test_set_effective_quota_temporal_psi(struct kunit *test) > +{ > + struct damon_ctx *c = damon_new_ctx(); > + struct damos_access_pattern pattern = {}; > + struct damos_quota quota = { > + .sz = SZ_64K, > + .goal_tuner = DAMOS_QUOTA_GOAL_TUNER_TEMPORAL, > + }; > + struct damos_watermarks wmarks = {}; > + struct damos_quota_goal src = { > + .metric = DAMOS_QUOTA_SOME_MEM_PSI_US, > + .target_value = ULONG_MAX, > + }; > + struct damos_quota_goal *goal; > + struct damos *s; > + > + 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); > + goal = damos_new_quota_goal(DAMOS_QUOTA_SOME_MEM_PSI_US, ULONG_MAX); > + if (!goal) { > + damon_destroy_ctx(c); > + kunit_skip(test, "goal alloc fail"); > + } > + damos_add_quota_goal(&s->quota, goal); > + > + /* fresh goal, first tuning round */ > + damos_set_effective_quota(c, s); > + KUNIT_EXPECT_EQ(test, s->quota.esz, (unsigned long)SZ_64K); > + > + /* second round: last_psi_total is initialised now */ Could we also check goal->last_psi_total here? The first tuning round should consume the U64_MAX sentinel and establish the measured state. Testing this explicitly would lock in that state transition. Thanks, Kunwu > + damos_set_effective_quota(c, s); > + KUNIT_EXPECT_EQ(test, s->quota.esz, (unsigned long)SZ_64K); > + > + /* commit a PSI goal onto the initialised PSI goal */ > + damos_commit_quota_goal(goal, &src); > + damos_set_effective_quota(c, s); > + KUNIT_EXPECT_EQ(test, s->quota.esz, (unsigned long)SZ_64K); > + > + /* a measured round that reaches the target disables the quota */ > + goal->target_value = 10; > + goal->last_psi_total = damos_get_some_mem_psi_total() - 10; > + /* U64_MAX marks an unmeasured goal, keep the sample away from it */ > + if (goal->last_psi_total == U64_MAX) > + goal->last_psi_total--; > + damos_set_effective_quota(c, s); > + KUNIT_EXPECT_EQ(test, s->quota.esz, 0ul); > + > + /* the consist tuner keeps its quota over an unmeasured round */ > + s->quota.goal_tuner = DAMOS_QUOTA_GOAL_TUNER_CONSIST; > + s->quota.esz_bp = SZ_32K * 10000; > + damos_commit_quota_goal(goal, &src); > + damos_set_effective_quota(c, s); > + KUNIT_EXPECT_EQ(test, s->quota.esz, (unsigned long)SZ_32K); > + > + damon_destroy_ctx(c); > +} > + > static void damos_test_commit_quota_goals_for(struct kunit *test, > struct damos_quota_goal *dst_goals, int nr_dst_goals, > struct damos_quota_goal *src_goals, int nr_src_goals) > @@ -1887,6 +1955,7 @@ static struct kunit_case damon_test_cases[] = { > KUNIT_CASE(damos_test_new_filter), > KUNIT_CASE(damos_test_commit_quota_goal), > KUNIT_CASE(damos_test_commit_quota_goals), > + KUNIT_CASE(damos_test_set_effective_quota_temporal_psi), > KUNIT_CASE(damos_test_commit_quota), > KUNIT_CASE(damos_test_commit_dests), > KUNIT_CASE(damos_test_commit_filter), > -- > 2.53.0 > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] mm/damon/tests/core-kunit: test PSI goal rounds under the temporal tuner 2026-09-15 7:04 ` KunWu Chan @ 2026-09-15 21:31 ` Karl Mehltretter 0 siblings, 0 replies; 9+ messages in thread From: Karl Mehltretter @ 2026-09-15 21:31 UTC (permalink / raw) To: KunWu Chan Cc: SJ Park, Andrew Morton, Lian Wang, damon, linux-mm, linux-kernel On Tue, Sep 15, 2026 at 03:04:06PM +0100, KunWu Chan wrote: > Could we also check goal->last_psi_total here? > > The first tuning round should consume the U64_MAX sentinel > and establish the measured state. > > Testing this explicitly would lock in that state transition. > Thanks for the review, good idea! The test only inferred the state from the effective quota, a direct check of last_psi_total is clearer and stricter. It also fits the v2 fix. I plan to keep last_psi_total across a commit of an existing PSI goal instead of touching the tuners, so that value is what the test should assert. For the v2 test I plan to check last_psi_total at each transition: not U64_MAX after the first round, still the kept sample after a commit of the same metric, U64_MAX again after a commit that changes the metric and back. The quota checks stay to cover the tuners. Karl ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] mm/damon/tests/core-kunit: test PSI goal rounds under the temporal tuner 2026-09-15 6:09 ` [PATCH 2/2] mm/damon/tests/core-kunit: test PSI goal rounds under " Karl Mehltretter 2026-09-15 7:04 ` KunWu Chan @ 2026-09-16 0:21 ` SJ Park 1 sibling, 0 replies; 9+ messages in thread From: SJ Park @ 2026-09-16 0:21 UTC (permalink / raw) To: Karl Mehltretter Cc: SJ Park, Andrew Morton, Lian Wang, Kunwu Chan, damon, linux-mm, linux-kernel On Tue, 15 Sep 2026 08:09:37 +0200 Karl Mehltretter <kmehltretter@gmail.com> wrote: > Exercise a PSI quota goal under the temporal tuner on its first > round, its next measured round, and after a goal commit. Use > ULONG_MAX as the target so the goal is not reached during the test. > Then check that a measured round which does reach the target sets > the quota to zero, and that the consist tuner keeps its quota over > an unmeasured round. > > Without the previous patch, the first and the post-commit checks see > a zero quota. Thank you for adding this test. > > Assisted-by: LLM > Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com> > --- > mm/damon/tests/core-kunit.h | 69 +++++++++++++++++++++++++++++++++++++ > 1 file changed, 69 insertions(+) > > diff --git a/mm/damon/tests/core-kunit.h b/mm/damon/tests/core-kunit.h > index c01e6a75cadc..2b9b24ce7dad 100644 > --- a/mm/damon/tests/core-kunit.h > +++ b/mm/damon/tests/core-kunit.h > @@ -889,6 +889,74 @@ static void damos_test_commit_quota_goal(struct kunit *test) > }); > } > > +/* > + * Unmeasured PSI goals must not disable the temporal quota. > + * Keep sz * 10000 within a 32-bit unsigned long. > + */ > +static void damos_test_set_effective_quota_temporal_psi(struct kunit *test) > +{ [...] > + /* fresh goal, first tuning round */ > + damos_set_effective_quota(c, s); > + KUNIT_EXPECT_EQ(test, s->quota.esz, (unsigned long)SZ_64K); > + > + /* second round: last_psi_total is initialised now */ > + damos_set_effective_quota(c, s); > + KUNIT_EXPECT_EQ(test, s->quota.esz, (unsigned long)SZ_64K); So, this test depends on the memory pressure level of the testing system? I concern if that could make the test result not very reliable. Maybe we could split out the corner case handling logic to explicitly receive the current memory PSI total time. For example, like what I suggested in the reply to the first patch of this series. With it, we could build a kunit test for only the target logic, without depending on the test system's status. Thanks, SJ [...] ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-09-16 0:21 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-09-15 6:09 [PATCH 0/2] mm/damon: fix zero quota for PSI goals under the temporal tuner Karl Mehltretter 2026-09-15 6:09 ` [PATCH 1/2] mm/damon/core: score an unmeasured PSI goal as not achieved for " Karl Mehltretter 2026-09-15 14:50 ` SJ Park 2026-09-15 21:19 ` Karl Mehltretter 2026-09-16 0:13 ` SJ Park 2026-09-15 6:09 ` [PATCH 2/2] mm/damon/tests/core-kunit: test PSI goal rounds under " Karl Mehltretter 2026-09-15 7:04 ` KunWu Chan 2026-09-15 21:31 ` Karl Mehltretter 2026-09-16 0:21 ` SJ Park
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®