* [PATCH v2 0/2] mm/damon: preserve temporal quota state for unmeasured PSI goals
@ 2026-09-21 2:00 Karl Mehltretter
2026-09-21 2:00 ` [PATCH v2 1/2] mm/damon/core: keep the temporal tuner quota over an unmeasured PSI round Karl Mehltretter
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Karl Mehltretter @ 2026-09-21 2:00 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. This
leaves the consist tuner's input unchanged but sets the temporal quota
to zero. Preserve the temporal tuner's previous goal-achievement state
using its effective quota, as SJ suggested [1], and test the helper with
explicit PSI totals.
All 42 DAMON KUnit tests pass on x86-64 and i386. With the original
scoring retained in the extracted helper, the new test fails on both.
In a live damo test, a goals-only update changes a running 64 KiB quota
to zero for an unmeasured round without the fix. With the fix, the
effective quota stays at 64 KiB. A full damo tune also needs the separate
quota-reset fix [3], so the context update preserves the running quota
used for this decision.
DAMON selftests show no new failures (QEMU TCG guest; the wss_estimation
test misses its accuracy bounds with and without the fix).
Changes since v1 [2]:
- Use the previous effective quota for the temporal decision, including
when it is zero. Keep resetting last_psi_total for new and updated
goals.
- Move the current-value calculation and last_psi_total update into a
helper. Test both tuners with explicit samples and check
last_psi_total after each call.
The series is based on mm-new as of September 20.
[1] https://lore.kernel.org/damon/20260916001311.101024-1-sj@kernel.org/
[2] https://lore.kernel.org/20260915060937.3423-1-kmehltretter@gmail.com/
[3] https://lore.kernel.org/20260921003047.12041-1-kmehltretter@gmail.com/
Karl Mehltretter (2):
mm/damon/core: keep the temporal tuner quota over an unmeasured PSI
round
mm/damon/tests/core-kunit: test PSI goal values with explicit samples
mm/damon/core.c | 30 ++++++++++++++++++++------
mm/damon/tests/core-kunit.h | 43 +++++++++++++++++++++++++++++++++++++
2 files changed, 66 insertions(+), 7 deletions(-)
base-commit: 185111f116aabf202d12ce440c0f6e9bae073514
--
2.53.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 1/2] mm/damon/core: keep the temporal tuner quota over an unmeasured PSI round
2026-09-21 2:00 [PATCH v2 0/2] mm/damon: preserve temporal quota state for unmeasured PSI goals Karl Mehltretter
@ 2026-09-21 2:00 ` Karl Mehltretter
2026-09-21 16:36 ` SJ Park
2026-09-21 2:00 ` [PATCH v2 2/2] mm/damon/tests/core-kunit: test PSI goal values with explicit samples Karl Mehltretter
2026-09-21 16:47 ` [PATCH v2 0/2] mm/damon: preserve temporal quota state for unmeasured PSI goals SJ Park
2 siblings, 1 reply; 7+ messages in thread
From: Karl Mehltretter @ 2026-09-21 2:00 UTC (permalink / raw)
To: SJ Park
Cc: Karl Mehltretter, Andrew Morton, Lian Wang, Kunwu Chan, damon,
linux-mm, linux-kernel
Commit b73198a47ffe ("mm/damon/core: handle uninitialized
damos_quota_goal->last_psi_total") scores a PSI quota goal without a
previous sample as achieved. This leaves the consist tuner's input
unchanged, but the temporal tuner sets its quota to zero for an achieved
goal. A running scheme with a nonzero temporal quota therefore loses a
charge window after a quota-goal commit.
Use the effective quota to preserve the temporal tuner's previous
goal-achievement state during an unmeasured round, as SJ suggested [1].
Score the goal as achieved when the effective quota is zero and as not
achieved otherwise. A new scheme's initially zero quota stays zero, and
the consist tuner's behavior is unchanged.
Move the PSI current-value calculation and last_psi_total update into a
helper that takes the current PSI total. This lets a unit test cover the
unmeasured and measured rounds without depending on system memory
pressure.
Fixes: b73198a47ffe ("mm/damon/core: handle uninitialized damos_quota_goal->last_psi_total")
Cc: <stable@vger.kernel.org> # 7.1.x
Suggested-by: SJ Park <sj@kernel.org>
Link: https://lore.kernel.org/damon/20260916001311.101024-1-sj@kernel.org/ [1]
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
The commit being fixed is still in mm-unstable, so its hash may change.
mm/damon/core.c | 30 +++++++++++++++++++++++-------
1 file changed, 23 insertions(+), 7 deletions(-)
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 2258b72da7a78..add1b7afb957a 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -2955,6 +2955,28 @@ 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)
+{
+ u64 last_psi_total = goal->last_psi_total;
+
+ goal->last_psi_total = now_psi_total;
+ if (last_psi_total != U64_MAX) {
+ goal->current_value = now_psi_total - 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 the same achievement as in 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)
{
@@ -3207,13 +3229,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;
- goal->last_psi_total = now_psi_total;
+ damos_set_psi_current_val(now_psi_total, goal, s);
break;
case DAMOS_QUOTA_NODE_MEM_USED_BP:
case DAMOS_QUOTA_NODE_MEM_FREE_BP:
--
2.53.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 2/2] mm/damon/tests/core-kunit: test PSI goal values with explicit samples
2026-09-21 2:00 [PATCH v2 0/2] mm/damon: preserve temporal quota state for unmeasured PSI goals Karl Mehltretter
2026-09-21 2:00 ` [PATCH v2 1/2] mm/damon/core: keep the temporal tuner quota over an unmeasured PSI round Karl Mehltretter
@ 2026-09-21 2:00 ` Karl Mehltretter
2026-09-21 16:40 ` SJ Park
2026-09-21 16:47 ` [PATCH v2 0/2] mm/damon: preserve temporal quota state for unmeasured PSI goals SJ Park
2 siblings, 1 reply; 7+ messages in thread
From: Karl Mehltretter @ 2026-09-21 2:00 UTC (permalink / raw)
To: SJ Park
Cc: Karl Mehltretter, Andrew Morton, Lian Wang, Kunwu Chan, damon,
linux-mm, linux-kernel
Test the PSI current-value helper with explicit totals so the result does
not depend on the test system's memory pressure. Cover an unmeasured
consist goal, unmeasured temporal goals with zero and nonzero effective
quotas, and measured rounds for both tuners. Check last_psi_total after
each call.
With the old unmeasured-round behavior retained in the helper, the
temporal check with a nonzero effective quota fails.
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
mm/damon/tests/core-kunit.h | 43 +++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/mm/damon/tests/core-kunit.h b/mm/damon/tests/core-kunit.h
index 5ff0436c58441..a30040826874e 100644
--- a/mm/damon/tests/core-kunit.h
+++ b/mm/damon/tests/core-kunit.h
@@ -910,6 +910,48 @@ static void damos_test_commit_quota_goal(struct kunit *test)
});
}
+static void damos_test_set_psi_current_val(struct kunit *test)
+{
+ struct damos s = {
+ .quota.goal_tuner = DAMOS_QUOTA_GOAL_TUNER_CONSIST,
+ };
+ struct damos_quota_goal goal = {
+ .metric = DAMOS_QUOTA_SOME_MEM_PSI_US,
+ .target_value = 100,
+ .last_psi_total = U64_MAX,
+ };
+
+ /* uninitialized last_psi_total keeps the consist tuner quota */
+ damos_set_psi_current_val(1000, &goal, &s);
+ KUNIT_EXPECT_EQ(test, goal.current_value, 100ul);
+ KUNIT_EXPECT_EQ(test, goal.last_psi_total, 1000ull);
+
+ /* initialized last_psi_total gives the delta */
+ damos_set_psi_current_val(1030, &goal, &s);
+ KUNIT_EXPECT_EQ(test, goal.current_value, 30ul);
+ KUNIT_EXPECT_EQ(test, goal.last_psi_total, 1030ull);
+
+ /* temporal tuner keeps a zero quota */
+ s.quota.goal_tuner = DAMOS_QUOTA_GOAL_TUNER_TEMPORAL;
+ s.quota.esz = 0;
+ goal.last_psi_total = U64_MAX;
+ damos_set_psi_current_val(2000, &goal, &s);
+ KUNIT_EXPECT_EQ(test, goal.current_value, 100ul);
+ KUNIT_EXPECT_EQ(test, goal.last_psi_total, 2000ull);
+
+ /* temporal tuner keeps a non-zero quota */
+ s.quota.esz = SZ_64K;
+ goal.last_psi_total = U64_MAX;
+ damos_set_psi_current_val(3000, &goal, &s);
+ KUNIT_EXPECT_EQ(test, goal.current_value, 0ul);
+ KUNIT_EXPECT_EQ(test, goal.last_psi_total, 3000ull);
+
+ /* temporal tuner uses the measured PSI delta */
+ damos_set_psi_current_val(3250, &goal, &s);
+ KUNIT_EXPECT_EQ(test, goal.current_value, 250ul);
+ KUNIT_EXPECT_EQ(test, goal.last_psi_total, 3250ull);
+}
+
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)
@@ -1947,6 +1989,7 @@ static struct kunit_case damon_test_cases[] = {
KUNIT_CASE(damon_test_nr_accesses_mvsum),
KUNIT_CASE(damos_test_new_filter),
KUNIT_CASE(damos_test_commit_quota_goal),
+ KUNIT_CASE(damos_test_set_psi_current_val),
KUNIT_CASE(damos_test_commit_quota_goals),
KUNIT_CASE(damos_test_commit_quota),
KUNIT_CASE(damos_test_commit_dests),
--
2.53.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/2] mm/damon/core: keep the temporal tuner quota over an unmeasured PSI round
2026-09-21 2:00 ` [PATCH v2 1/2] mm/damon/core: keep the temporal tuner quota over an unmeasured PSI round Karl Mehltretter
@ 2026-09-21 16:36 ` SJ Park
0 siblings, 0 replies; 7+ messages in thread
From: SJ Park @ 2026-09-21 16:36 UTC (permalink / raw)
To: Karl Mehltretter
Cc: SJ Park, Andrew Morton, Lian Wang, Kunwu Chan, damon, linux-mm,
linux-kernel
On Mon, 21 Sep 2026 04:00:12 +0200 Karl Mehltretter <kmehltretter@gmail.com> wrote:
> Commit b73198a47ffe ("mm/damon/core: handle uninitialized
> damos_quota_goal->last_psi_total") scores a PSI quota goal without a
> previous sample as achieved. This leaves the consist tuner's input
> unchanged, but the temporal tuner sets its quota to zero for an achieved
> goal. A running scheme with a nonzero temporal quota therefore loses a
> charge window after a quota-goal commit.
>
> Use the effective quota to preserve the temporal tuner's previous
> goal-achievement state during an unmeasured round, as SJ suggested [1].
> Score the goal as achieved when the effective quota is zero and as not
> achieved otherwise. A new scheme's initially zero quota stays zero, and
> the consist tuner's behavior is unchanged.
>
> Move the PSI current-value calculation and last_psi_total update into a
> helper that takes the current PSI total. This lets a unit test cover the
> unmeasured and measured rounds without depending on system memory
> pressure.
Looks good to me.
>
> Fixes: b73198a47ffe ("mm/damon/core: handle uninitialized damos_quota_goal->last_psi_total")
> Cc: <stable@vger.kernel.org> # 7.1.x
The broken commit (b73198a47ffe) is not in the mainline but mm-unstable. We
should squash this to the broken commit before it is merged into the mainline.
Or, maybe pointing the original broken fix (2dbb60f789cb) as 'Fixes:' is
another option.
Do you have a preferrence?
> Suggested-by: SJ Park <sj@kernel.org>
> Link: https://lore.kernel.org/damon/20260916001311.101024-1-sj@kernel.org/ [1]
> Assisted-by: LLM
> Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Other than the above,
Reviewed-by: SJ Park <sj@kernel.org>
Thanks,
SJ
[...]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 2/2] mm/damon/tests/core-kunit: test PSI goal values with explicit samples
2026-09-21 2:00 ` [PATCH v2 2/2] mm/damon/tests/core-kunit: test PSI goal values with explicit samples Karl Mehltretter
@ 2026-09-21 16:40 ` SJ Park
0 siblings, 0 replies; 7+ messages in thread
From: SJ Park @ 2026-09-21 16:40 UTC (permalink / raw)
To: Karl Mehltretter
Cc: SJ Park, Andrew Morton, Lian Wang, Kunwu Chan, damon, linux-mm,
linux-kernel
On Mon, 21 Sep 2026 04:00:13 +0200 Karl Mehltretter <kmehltretter@gmail.com> wrote:
> Test the PSI current-value helper with explicit totals so the result does
> not depend on the test system's memory pressure. Cover an unmeasured
> consist goal, unmeasured temporal goals with zero and nonzero effective
> quotas, and measured rounds for both tuners. Check last_psi_total after
> each call.
>
> With the old unmeasured-round behavior retained in the helper, the
> temporal check with a nonzero effective quota fails.
Thank you for contributing test!
>
> Assisted-by: LLM
> Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: SJ Park <sj@kernel.org>
Thanks,
SJ
[...]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 0/2] mm/damon: preserve temporal quota state for unmeasured PSI goals
2026-09-21 2:00 [PATCH v2 0/2] mm/damon: preserve temporal quota state for unmeasured PSI goals Karl Mehltretter
2026-09-21 2:00 ` [PATCH v2 1/2] mm/damon/core: keep the temporal tuner quota over an unmeasured PSI round Karl Mehltretter
2026-09-21 2:00 ` [PATCH v2 2/2] mm/damon/tests/core-kunit: test PSI goal values with explicit samples Karl Mehltretter
@ 2026-09-21 16:47 ` SJ Park
2026-09-21 18:39 ` Karl Mehltretter
2 siblings, 1 reply; 7+ messages in thread
From: SJ Park @ 2026-09-21 16:47 UTC (permalink / raw)
To: Karl Mehltretter
Cc: SJ Park, Andrew Morton, Lian Wang, Kunwu Chan, damon, linux-mm,
linux-kernel
On Mon, 21 Sep 2026 04:00:11 +0200 Karl Mehltretter <kmehltretter@gmail.com> wrote:
> A PSI quota goal without a previous sample is scored as achieved. This
> leaves the consist tuner's input unchanged but sets the temporal quota
> to zero. Preserve the temporal tuner's previous goal-achievement state
> using its effective quota, as SJ suggested [1], and test the helper with
> explicit PSI totals.
>
> All 42 DAMON KUnit tests pass on x86-64 and i386. With the original
> scoring retained in the extracted helper, the new test fails on both.
> In a live damo test, a goals-only update changes a running 64 KiB quota
> to zero for an unmeasured round without the fix. With the fix, the
> effective quota stays at 64 KiB. A full damo tune also needs the separate
> quota-reset fix [3], so the context update preserves the running quota
> used for this decision.
>
> DAMON selftests show no new failures (QEMU TCG guest; the wss_estimation
> test misses its accuracy bounds with and without the fix).
>
> Changes since v1 [2]:
> - Use the previous effective quota for the temporal decision, including
> when it is zero. Keep resetting last_psi_total for new and updated
> goals.
> - Move the current-value calculation and last_psi_total update into a
> helper. Test both tuners with explicit samples and check
> last_psi_total after each call.
>
> The series is based on mm-new as of September 20.
>
> [1] https://lore.kernel.org/damon/20260916001311.101024-1-sj@kernel.org/
> [2] https://lore.kernel.org/20260915060937.3423-1-kmehltretter@gmail.com/
> [3] https://lore.kernel.org/20260921003047.12041-1-kmehltretter@gmail.com/
The patch 1 has wrong Fixes: tag, as I replied to it with two options to path
forward. Speculatively assuming your preferrence is option 2 (adding this
series with fixed 'Fixes:' tag), I applied this series to damon/next [1] tree
with the suggested Fixes: tag modification. Let me know if you want the
options 1 (squash it into the incomplete fix [2] before it is merged into the
mainline).
Unless you want option 1, and if this series is not added to mm.git in short
term (~1 week?) with option 1 update, I will ask mm.git maintainer (Andrew
Morton) to pick this. So, no action from your side is needed for now unless
you want option 1. If it seems I forgot doing that or you cannot wait for my
action, please feel free to ping me or Andrew.
[1] https://origin.kernel.org/doc/html/latest/mm/damon/maintainer-profile.html#scm-trees
[2] commit b73198a47ffe ("mm/damon/core: handle uninitialized damos_quota_goal->last_psi_total")
Thanks,
SJ
[...]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 0/2] mm/damon: preserve temporal quota state for unmeasured PSI goals
2026-09-21 16:47 ` [PATCH v2 0/2] mm/damon: preserve temporal quota state for unmeasured PSI goals SJ Park
@ 2026-09-21 18:39 ` Karl Mehltretter
0 siblings, 0 replies; 7+ messages in thread
From: Karl Mehltretter @ 2026-09-21 18:39 UTC (permalink / raw)
To: SJ Park
Cc: Andrew Morton, Lian Wang, Kunwu Chan, damon, linux-mm, linux-kernel
On Mon, Sep 21, 2026 at 09:47:48AM +0100, SJ Park wrote:
> The patch 1 has wrong Fixes: tag, as I replied to it with two options to path
> forward. Speculatively assuming your preferrence is option 2 (adding this
> series with fixed 'Fixes:' tag), I applied this series to damon/next [1] tree
> with the suggested Fixes: tag modification. Let me know if you want the
> options 1 (squash it into the incomplete fix [2] before it is merged into the
> mainline).
>
> Unless you want option 1, and if this series is not added to mm.git in short
> term (~1 week?) with option 1 update, I will ask mm.git maintainer (Andrew
> Morton) to pick this. So, no action from your side is needed for now unless
> you want option 1. If it seems I forgot doing that or you cannot wait for my
> action, please feel free to ping me or Andrew.
>
Hello SJ,
Thanks for reviewing both patches!
I used b73198a47ffe in Fixes because that commit introduced the problem
with the temporal tuner.
I thought a Fixes tag could also point to a commit that is still in a
maintainer tree. The tip handbook describes that for tip [1], though mm
may handle it differently.
The hash can still change in mm-unstable, so the tag may need updating.
I also found this reply from Andrew [2]. He says he tracks these fixes
by filename and folds them into the original patch before moving it to
non-rebasing git.
Maybe squashing is indeed simpler here, also for backports.
So either option is fine with me. I'll leave that to you and Andrew.
[1] https://docs.kernel.org/process/maintainer-tip.html#ordering-of-commit-tags
[2] https://lore.kernel.org/r/20260313091738.354244f6fb500bef3bad1fa1@linux-foundation.org/
Thanks,
Karl
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-09-21 18:39 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-21 2:00 [PATCH v2 0/2] mm/damon: preserve temporal quota state for unmeasured PSI goals Karl Mehltretter
2026-09-21 2:00 ` [PATCH v2 1/2] mm/damon/core: keep the temporal tuner quota over an unmeasured PSI round Karl Mehltretter
2026-09-21 16:36 ` SJ Park
2026-09-21 2:00 ` [PATCH v2 2/2] mm/damon/tests/core-kunit: test PSI goal values with explicit samples Karl Mehltretter
2026-09-21 16:40 ` SJ Park
2026-09-21 16:47 ` [PATCH v2 0/2] mm/damon: preserve temporal quota state for unmeasured PSI goals SJ Park
2026-09-21 18:39 ` Karl Mehltretter
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®