DAMON development mailing list
 help / color / mirror / Atom feed
* [PATCH 6.18.y 1/2] mm/damon/core: allow esz to be set to zero
@ 2026-09-29 17:44 SJ Park
  2026-09-29 17:44 ` [PATCH 6.18.y 2/2] mm/damon/core: fix unconditionally skip last region SJ Park
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: SJ Park @ 2026-09-29 17:44 UTC (permalink / raw)
  To: stable; +Cc: damon, Liew Rui Yan, SJ Park, Andrew Morton

From: Liew Rui Yan <aethernet65535@gmail.com>

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.

Link: https://lore.kernel.org/20260908135413.97570-1-sj@kernel.org
Fixes: 8bbde987c2b8 ("mm/damon/core: disallow time-quota setting zero esz")
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Liew Rui Yan <aethernet65535@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: SJ Park <sj@kernel.org>
Cc: <stable@vger.kernel.org> # v7.1.x
(cherry picked from commit 90179da203ba8b708c84a12a07cd44be0f346334)
Signed-off-by: SJ Park <sj@kernel.org>
---
 mm/damon/core.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/mm/damon/core.c b/mm/damon/core.c
index 6fa02025d2af1..facb1fa1f695f 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -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(&quota->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)
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 6.18.y 2/2] mm/damon/core: fix unconditionally skip last region
  2026-09-29 17:44 [PATCH 6.18.y 1/2] mm/damon/core: allow esz to be set to zero SJ Park
@ 2026-09-29 17:44 ` SJ Park
  2026-09-29 17:55   ` sashiko-bot
  2026-09-29 17:59 ` [PATCH 6.18.y 1/2] mm/damon/core: allow esz to be set to zero sashiko-bot
  2026-09-29 19:13 ` SJ Park
  2 siblings, 1 reply; 8+ messages in thread
From: SJ Park @ 2026-09-29 17:44 UTC (permalink / raw)
  To: stable; +Cc: damon, Liew Rui Yan, SJ Park, Andrew Morton

From: Liew Rui Yan <aethernet65535@gmail.com>

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.

Link: https://lore.kernel.org/20260908134739.96919-1-sj@kernel.org
Fixes: 50585192bc2e ("mm/damon/schemes: skip already charged targets and regions")
Signed-off-by: Liew Rui Yan <aethernet65535@gmail.com>
Reviewed-by: SJ Park <sj@kernel.org>
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: <stable@vger.kernel.org> # v5.16.x
(cherry picked from commit b3723b596b548c837a766aae3553c14a7b15af2b)
Signed-off-by: SJ Park <sj@kernel.org>
---
 mm/damon/core.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/mm/damon/core.c b/mm/damon/core.c
index facb1fa1f695f..5bb69a4d2ffdf 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -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,
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 6.18.y 2/2] mm/damon/core: fix unconditionally skip last region
  2026-09-29 17:44 ` [PATCH 6.18.y 2/2] mm/damon/core: fix unconditionally skip last region SJ Park
@ 2026-09-29 17:55   ` sashiko-bot
  0 siblings, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-09-29 17:55 UTC (permalink / raw)
  To: SJ Park; +Cc: damon

> From: Liew Rui Yan <aethernet65535@gmail.com>
> 
> 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.
> [ ... ]
> Signed-off-by: SJ Park <sj@kernel.org>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Cc: <stable@vger.kernel.org> # v5.16.x
> (cherry picked from commit b3723b596b548c837a766aae3553c14a7b15af2b)
> Signed-off-by: SJ Park <sj@kernel.org>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260929174456.9251-1-sj@kernel.org?part=2


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 6.18.y 1/2] mm/damon/core: allow esz to be set to zero
  2026-09-29 17:44 [PATCH 6.18.y 1/2] mm/damon/core: allow esz to be set to zero SJ Park
  2026-09-29 17:44 ` [PATCH 6.18.y 2/2] mm/damon/core: fix unconditionally skip last region SJ Park
@ 2026-09-29 17:59 ` sashiko-bot
  2026-09-29 19:13 ` SJ Park
  2 siblings, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-09-29 17:59 UTC (permalink / raw)
  To: SJ Park; +Cc: damon

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 <aethernet65535@gmail.com>
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.

Link: https://lore.kernel.org/20260908135413.97570-1-sj@kernel.org

> diff --git a/mm/damon/core.c b/mm/damon/core.c
> index 6fa02025d2af1..facb1fa1f695f 100644
> --- a/mm/damon/core.c
> +++ b/mm/damon/core.c

[ ... ]

> @@ -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()?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260929174456.9251-1-sj@kernel.org?part=1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 6.18.y 1/2] mm/damon/core: allow esz to be set to zero
  2026-09-29 17:44 [PATCH 6.18.y 1/2] mm/damon/core: allow esz to be set to zero SJ Park
  2026-09-29 17:44 ` [PATCH 6.18.y 2/2] mm/damon/core: fix unconditionally skip last region SJ Park
  2026-09-29 17:59 ` [PATCH 6.18.y 1/2] mm/damon/core: allow esz to be set to zero sashiko-bot
@ 2026-09-29 19:13 ` SJ Park
  2026-09-30  4:34   ` Greg KH
  2 siblings, 1 reply; 8+ messages in thread
From: SJ Park @ 2026-09-29 19:13 UTC (permalink / raw)
  To: SJ Park; +Cc: stable, damon, Liew Rui Yan, Andrew Morton

Hello stable team,


Please don't apply this patch.

On Tue, 29 Sep 2026 10:44:55 -0700 SJ Park <sj@kernel.org> wrote:

> From: Liew Rui Yan <aethernet65535@gmail.com>
> 
> 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.
> 
> Link: https://lore.kernel.org/20260908135413.97570-1-sj@kernel.org
> 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

[...]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 6.18.y 1/2] mm/damon/core: allow esz to be set to zero
  2026-09-29 19:13 ` SJ Park
@ 2026-09-30  4:34   ` Greg KH
  2026-09-30  8:09     ` SJ Park
  0 siblings, 1 reply; 8+ messages in thread
From: Greg KH @ 2026-09-30  4:34 UTC (permalink / raw)
  To: SJ Park; +Cc: stable, damon, Liew Rui Yan, Andrew Morton

On Tue, Sep 29, 2026 at 12:13:19PM -0700, SJ Park wrote:
> Hello stable team,
> 
> 
> Please don't apply this patch.
> 
> On Tue, 29 Sep 2026 10:44:55 -0700 SJ Park <sj@kernel.org> wrote:
> 
> > From: Liew Rui Yan <aethernet65535@gmail.com>
> > 
> > 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.
> > 
> > Link: https://lore.kernel.org/20260908135413.97570-1-sj@kernel.org
> > 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?

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 6.18.y 1/2] mm/damon/core: allow esz to be set to zero
  2026-09-30  4:34   ` Greg KH
@ 2026-09-30  8:09     ` SJ Park
  2026-09-30 12:29       ` Greg KH
  0 siblings, 1 reply; 8+ messages in thread
From: SJ Park @ 2026-09-30  8:09 UTC (permalink / raw)
  To: Greg KH; +Cc: SJ Park, stable, damon, Liew Rui Yan, Andrew Morton

On Wed, 30 Sep 2026 06:34:35 +0200 Greg KH <greg@kroah.com> wrote:

> On Tue, Sep 29, 2026 at 12:13:19PM -0700, SJ Park wrote:
> > Hello stable team,
> > 
> > 
> > Please don't apply this patch.
> > 
> > On Tue, 29 Sep 2026 10:44:55 -0700 SJ Park <sj@kernel.org> wrote:
> > 
> > > From: Liew Rui Yan <aethernet65535@gmail.com>
> > > 
> > > 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.
> > > 
> > > Link: https://lore.kernel.org/20260908135413.97570-1-sj@kernel.org
> > > 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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 6.18.y 1/2] mm/damon/core: allow esz to be set to zero
  2026-09-30  8:09     ` SJ Park
@ 2026-09-30 12:29       ` Greg KH
  0 siblings, 0 replies; 8+ messages in thread
From: Greg KH @ 2026-09-30 12:29 UTC (permalink / raw)
  To: SJ Park; +Cc: stable, damon, Liew Rui Yan, Andrew Morton

On Wed, Sep 30, 2026 at 01:09:58AM -0700, SJ Park wrote:
> On Wed, 30 Sep 2026 06:34:35 +0200 Greg KH <greg@kroah.com> wrote:
> 
> > On Tue, Sep 29, 2026 at 12:13:19PM -0700, SJ Park wrote:
> > > Hello stable team,
> > > 
> > > 
> > > Please don't apply this patch.
> > > 
> > > On Tue, 29 Sep 2026 10:44:55 -0700 SJ Park <sj@kernel.org> wrote:
> > > 
> > > > From: Liew Rui Yan <aethernet65535@gmail.com>
> > > > 
> > > > 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.
> > > > 
> > > > Link: https://lore.kernel.org/20260908135413.97570-1-sj@kernel.org
> > > > 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.

Great, I'll take that one now, thanks.

greg k-h

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-09-30 12:29 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-29 17:44 [PATCH 6.18.y 1/2] mm/damon/core: allow esz to be set to zero SJ Park
2026-09-29 17:44 ` [PATCH 6.18.y 2/2] mm/damon/core: fix unconditionally skip last region SJ Park
2026-09-29 17:55   ` sashiko-bot
2026-09-29 17:59 ` [PATCH 6.18.y 1/2] mm/damon/core: allow esz to be set to zero sashiko-bot
2026-09-29 19:13 ` SJ Park
2026-09-30  4:34   ` Greg KH
2026-09-30  8:09     ` SJ Park
2026-09-30 12:29       ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox