mm/damon/core: allow esz to be set to zero
Subsystems (2)
SJ Park
maintainerPATCH 1/2 mm/damon/core: allow esz to be set to zero
From: Liew Rui Yan <[email protected]>
When the temporal quota goal tuner determines that the goal has been achieved (score >= 10000), it sets esz_bp to zero so that the esz becomes zero. However, damos_set_effective_quota() clamps the esz to min_region_sz when quota->ms is set.
This is a minor issue, the main problem is that it doesn't match the description in the documentation, which state that if the goal has already been [over-]achieved, the quota will be set to zero.
Fix this by set quota (esz) as minimum as possible.
--- mm/damon/core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
mm/damon/core.c +3 -2
@@ -2191,6 +2191,7 @@ static void damos_set_effective_quota(struct damos_quota *quota, {unsigned long throughput;unsigned long esz =ULONG_MAX ; +unsigned long esz_time;if (!quota->ms &&list_empty ("a->goals)) { quota->esz = quota->sz;
@@ -2212,8 +2213,8 @@ static void damos_set_effective_quota(struct damos_quota *quota, quota->total_charged_ns); else throughput =PAGE_SIZE *1024 ; - esz =min (throughput * quota->ms, esz); - esz =max (ctx->min_sz_region, esz); + esz_time =max (throughput * quota->ms, ctx->min_sz_region); + esz =min (esz_time, esz); }if (quota->sz && quota->sz < esz)
Signature · 1 line
2.47.3
SJ Park
maintainerPATCH 2/2 mm/damon/core: fix unconditionally skip last region
From: Liew Rui Yan <[email protected]>
Once quota set, the charge_{target,addr}_from unconditionally skips and resets at the last region of the tracked target, so the last region can be skipped even when it has not been processed.
Example:
1. Target has 2 regions: R1 (0-100 bytes) and R2 (100-200 bytes).
2. Quota is configured to process only 100 bytes per window.
3. Window 1: Processes R1 (0-100). Quota is full. charge_{target, addr}_from is saved at (Target, 100).
4. Window 2: The loop reaches R2. Because R2 is damon_last_region(t), the old code unconditionally returns true, skipping R2 entirely and resetting the charge_{target,addr}_from.
Result: R2 is permanently skipped even though it has never been processed.
However, it is important to note that this is a very minor issue. This is because it is triggered only when the previous window saved/kept charge_{target,addr}_from, and in the next window, all regions except the last region were skipped by damos_skip_charged_region().
Fix this by only resetting the charge_{target,addr}_from when last region is reached, only skipping when it is applied or cannot split.
--- mm/damon/core.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-)
mm/damon/core.c +14 -10
@@ -1746,37 +1746,41 @@ static bool damos_skip_charged_region(struct damon_target *t,struct damon_region *r = *rp;struct damos_quota *quota = &s->quota;unsigned long sz_to_skip; +bool skip = false;/* Skip previously charged regions */ if (quota->charge_target_from) {if (t != quota->charge_target_from)return true; -if (r ==damon_last_region (t)) { - quota->charge_target_from =NULL ; - quota->charge_addr_from =0 ; -return true; - }if (quota->charge_addr_from && - r->ar.end <= quota->charge_addr_from) -return true; + r->ar.end <= quota->charge_addr_from) { + skip = true; + goto out; + }if (quota->charge_addr_from && r->ar.start < quota->charge_addr_from) { sz_to_skip =ALIGN_DOWN (quota->charge_addr_from - r->ar.start, min_sz_region);if (!sz_to_skip) { -if (damon_sz_region (r) <= min_sz_region) -return true; +if (damon_sz_region (r) <= min_sz_region) { + skip = true; + goto out; + } sz_to_skip = min_sz_region; }damon_split_region_at (t, r, sz_to_skip); r =damon_next_region (r); *rp = r; + skip = false; } + } +out: +if (r ==damon_last_region (t)) { quota->charge_target_from =NULL ; quota->charge_addr_from =0 ; } -return false; +return skip; } static void damos_update_stat(struct damos *s,
Signature · 1 line
2.47.3
[email protected]
AI reviewRe: [PATCH 6.18.y 2/2] mm/damon/core: fix unconditionally skip last region
Sashiko has reviewed this patch and found no issues. It looks great!
Quoted 15 lines
From: Liew Rui Yan <[email protected]>
Once quota set, the charge_{target,addr}_from unconditionally skips and resets at the last region of the tracked target, so the last region can be skipped even when it has not been processed.
Example:
1. Target has 2 regions: R1 (0-100 bytes) and R2 (100-200 bytes).
2. Quota is configured to process only 100 bytes per window.
3. Window 1: Processes R1 (0-100). Quota is full. charge_{target, addr}_from is saved at (Target, 100).
4. Window 2: The loop reaches R2. Because R2 isdamon_last_region(t), the old code unconditionally returns true, skipping R2 entirely and resetting the charge_{target,addr}_from.
Quoted 6 lines
[ ... ]Signed-off-by SJ Park <[email protected]>Signed-off-by Andrew Morton <[email protected]>Cc <[email protected]> # v5.16.x(cherry picked from commit b3723b596b548c837a766aae3553c14a7b15af2b)Signed-off-by SJ Park <[email protected]>
Sashiko has reviewed this patch and found no issues. It looks great!
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
[email protected]
AI reviewThank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Medium] mm/damon: removing min_sz_region clamp on esz breaks quota accounting --
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] mm/damon: removing min_sz_region clamp on esz breaks quota accounting --
commit f7906e90ad53cf62853b7b051dfd11b8012181f1
Author: Liew Rui Yan <[email protected]>
Subject: mm/damon/core: allow esz to be set to zero
This patch modifies damos_set_effective_quota() to allow the effective size quota (esz) to be reduced as much as possible when temporal quota goals are achieved. It does this by removing the clamp against min_sz_region when calculating esz.
Quoted 4 lines
mm/damon/core.c +0
-0
[ ... ]
mm/damon/core.c static void damos_set_effective_quota(struct damos_quota *quota, · line 2218
Quoted 9 lines
mm/damon/core.c +2
-2@@ -2212,8 +2213,8 @@ static void damos_set_effective_quota(struct damos_quota *quota, quota->total_charged_ns); else throughput =PAGE_SIZE *1024 ; - esz =min (throughput * quota->ms, esz); - esz =max (ctx->min_sz_region, esz); + esz_time =max (throughput * quota->ms, ctx->min_sz_region); + esz =min (esz_time, esz); }
[Severity: Medium]
Will this break quota accounting when goals are over-achieved?
By removing the clamp against min_sz_region, esz can drop below the minimum region size, for example to 1.
If esz becomes 1, does ALIGN_DOWN() in damos_apply_scheme() evaluate to 0?
mm/damon/core.c:damos_apply_scheme() {
if (quota->esz && quota->charged_sz + sz > quota->esz) {
sz = ALIGN_DOWN(quota->esz - quota->charged_sz,
c->min_sz_region);
if (!sz)
goto update_stat;
damon_split_region_at(t, r, sz);
}
...
quota->charged_sz += sz;
}If sz evaluates to 0, it jumps to update_stat and bypasses incrementing quota->charged_sz.
Because quota->charged_sz gets frozen at 0, wouldn't this prevent the quota short-circuit from ever being taken in damon_do_apply_schemes()?
mm/damon/core.c:damon_do_apply_schemes() {
/* Check the quota */
if (quota->esz && quota->charged_sz >= quota->esz)
continue;
}Can this also corrupt the qt_exceeds statistic since the same check fails in damos_adjust_quota()?
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
SJ Park
maintainerHello stable team,
Please don't apply this patch.
Quoted 7 lines · On Tue, 29 Sep 2026 10:44:55 -0700 SJ Park <[email protected]> wrote:
From: Liew Rui Yan <[email protected]>
When the temporal quota goal tuner determines that the goal has been achieved (score >= 10000), it sets
esz_bpto zero so that the esz becomes zero. However,damos_set_effective_quota()clamps the esz tomin_region_szwhenquota->msis set.
Quoted 8 lines
This is a minor issue, the main problem is that it doesn't match the description in the documentation, which state that if the goal has already been [over-]achieved, the quota will be set to zero.
Fix this by set quota (esz) as minimum as possible.
Fixes 8bbde987c2b8 ("mm/damon/core: disallow time-quota setting zero esz")
The problem happens only when there is temporal tuner. Temporal tuner is a feature that introduced in 7.1. Hence <7.1 stable kernels don't have the temporal tuner, and this patch shouldn't be applied.
Thanks,
SJ
[...]
Quoted 18 lines · SJ Park
Hello stable team,
Please don't apply this patch.
Quoted 11 lines · On Tue, 29 Sep 2026 10:44:55 -0700 SJ Park <[email protected]> wrote:
From: Liew Rui Yan <[email protected]>
When the temporal quota goal tuner determines that the goal has been achieved (score >= 10000), it sets
esz_bpto zero so that the esz becomes zero. However,damos_set_effective_quota()clamps the esz tomin_region_szwhenquota->msis set.This is a minor issue, the main problem is that it doesn't match the description in the documentation, which state that if the goal has already been [over-]achieved, the quota will be set to zero.
Quoted 8 lines
Quoted 4 lines
Fix this by set quota (esz) as minimum as possible.
Fixes 8bbde987c2b8 ("mm/damon/core: disallow time-quota setting zero esz")The problem happens only when there is temporal tuner. Temporal tuner is a feature that introduced in 7.1. Hence <7.1 stable kernels don't have the temporal tuner, and this patch shouldn't be applied.
SHould we skip patch 2/2 here too?
SJ Park
maintainerQuoted 21 lines · On Wed, 30 Sep 2026 06:34:35 +0200 Greg KH <[email protected]> wrote:
Quoted 20 lines · SJ Park
Hello stable team,
Please don't apply this patch.
Quoted 13 lines · On Tue, 29 Sep 2026 10:44:55 -0700 SJ Park <[email protected]> wrote:
From: Liew Rui Yan <[email protected]>
When the temporal quota goal tuner determines that the goal has been achieved (score >= 10000), it sets
esz_bpto zero so that the esz becomes zero. However,damos_set_effective_quota()clamps the esz tomin_region_szwhenquota->msis set.This is a minor issue, the main problem is that it doesn't match the description in the documentation, which state that if the goal has already been [over-]achieved, the quota will be set to zero.
Fix this by set quota (esz) as minimum as possible.
Quoted 8 lines
Quoted 6 lines
Quoted 2 lines
Fixes 8bbde987c2b8 ("mm/damon/core: disallow time-quota setting zero esz")The problem happens only when there is temporal tuner. Temporal tuner is a feature that introduced in 7.1. Hence <7.1 stable kernels don't have the temporal tuner, and this patch shouldn't be applied.
SHould we skip patch 2/2 here too?
2/2 is good. Sorry for not clarifying it. Please let me know if there is anything I can help.
Thanks,
SJ
Quoted 26 lines · SJ Park
Quoted 24 lines · On Wed, 30 Sep 2026 06:34:35 +0200 Greg KH <[email protected]> wrote:
Quoted 23 lines · SJ Park
Hello stable team,
Please don't apply this patch.
Quoted 15 lines · On Tue, 29 Sep 2026 10:44:55 -0700 SJ Park <[email protected]> wrote:
From: Liew Rui Yan <[email protected]>
When the temporal quota goal tuner determines that the goal has been achieved (score >= 10000), it sets
esz_bpto zero so that the esz becomes zero. However,damos_set_effective_quota()clamps the esz tomin_region_szwhenquota->msis set.This is a minor issue, the main problem is that it doesn't match the description in the documentation, which state that if the goal has already been [over-]achieved, the quota will be set to zero.
Fix this by set quota (esz) as minimum as possible.
Fixes 8bbde987c2b8 ("mm/damon/core: disallow time-quota setting zero esz")
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
The problem happens only when there is temporal tuner. Temporal tuner is a feature that introduced in 7.1. Hence <7.1 stable kernels don't have the temporal tuner, and this patch shouldn't be applied.
SHould we skip patch 2/2 here too?
2/2 is good. Sorry for not clarifying it. Please let me know if there is anything I can help.
Great, I'll take that one now, thanks.
greg k-h