From: SJ Park <sj@kernel.org>
To: SJ Park <sj@kernel.org>
Cc: sashiko-bot@kernel.org, damon@lists.linux.dev
Subject: Re: [RFC PATCH v1.1 7/9] mm/damon/core: handle extreme memory state in damon_get_node_mem_bp()
Date: Sun, 2 Aug 2026 10:59:24 -0700 [thread overview]
Message-ID: <20260802175926.2322-1-sj@kernel.org> (raw)
In-Reply-To: <20260802174951.1878-1-sj@kernel.org>
On Sun, 2 Aug 2026 10:49:50 -0700 SJ Park <sj@kernel.org> wrote:
> On Sun, 02 Aug 2026 16:35:44 +0000 sashiko-bot@kernel.org wrote:
>
> > Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
> >
> > New issues:
> > - [High] Returning 0 for DAMOS_QUOTA_NODE_MEM_FREE_BP when freeram > totalram incorrectly forces maximum scheme aggressiveness instead of reporting 100% free memory.
> > - [Medium] The commit message contradicts the implementation, and the unconditional return of 10000 for zero totalram breaks metric semantics.
> >
> > Pre-existing issues:
> > - [High] Unhandled integer underflow in MEM_USED_BP and MEMCG_FREE_BP calculations when counters drift.
> > - [High] The patch fixes a potential divide-by-zero in damos_get_node_mem_bp() but misses identical unvalidated divisions in related functions.
> > --
> >
> > --- Patch [7]: [RFC PATCH v1.1 7/9] mm/damon/core: handle extreme memory state in damon_get_node_mem_bp() ---
> > commit 05d27d4d51952669ff23ec9285ccb83a273556ad
> > Author: SJ Park <sj@kernel.org>
> >
> > mm/damon/core: handle extreme memory state in damon_get_node_mem_bp()
> >
> > In an extreme and unlikely situation, si_meminfo_node() might let the
> > caller show zero total ram. That could cause a divide by zero in
> > damon_get_node_mem_bp(). Fix it by setting the totalram one byte in the
> > case.
> >
> > Link: https://lore.kernel.org/20260328133216.9697-1-sj@kernel.org
> >
> > > In an extreme and unlikely situation, si_meminfo_node() might let the
> > > caller show zero total ram. That could cause a divide by zero in
> > > damon_get_node_mem_bp(). Fix it by setting the totalram one byte in the
> > > case.
> >
> > [Severity: Medium]
> > The commit message states "Fix it by setting the totalram one byte in the
> > case."
> >
> > However, the implementation actually bypasses the metric type check and returns
> > 10000.
> >
> > Does this unconditional return contradict the intent documented in the commit
> > message?
>
> Good catch, I will update the commit message.
>
> >
> > > diff --git a/mm/damon/core.c b/mm/damon/core.c
> > > index 3bdbf4fbf7147..e3f3ee75a3d33 100644
> > > --- a/mm/damon/core.c
> > > +++ b/mm/damon/core.c
> > > @@ -2816,10 +2816,16 @@ static __kernel_ulong_t damos_get_node_mem_bp(
> > > }
> > >
> > > si_meminfo_node(&i, goal->nid);
> > > - if (goal->metric = DAMOS_QUOTA_NODE_MEM_USED_BP)
> > > + if (!i.totalram)
> > > + return 10000;
> >
> > [Severity: Medium]
> > If the metric is DAMOS_QUOTA_NODE_MEM_FREE_BP, shouldn't it report 0% free
> > rather than 100% free if the memory is absent (which is what totalram=1,
> > freeram=0 would yield)?
> >
> > Does returning 10000 here break the semantic constraint that used + free = 100%?
>
> I made mistakes at revisioning. I will fix this.
And this semantic gap exist in the next patch, too. I will fix it together.
>
> >
> > > + if (goal->metric = DAMOS_QUOTA_NODE_MEM_USED_BP) {
> > > numerator = i.totalram - i.freeram;
> >
> > [Severity: High]
> > This is a pre-existing issue, but if counter drift results in
> > freeram > totalram, does this subtraction silently underflow, producing a
> > massive unsigned value?
> >
> > If this is passed to mult_frac(), could it generate a huge metric value,
> > leading the auto-tuner to mistakenly act as if the memory is massively
> > overused?
> >
> > An identical unhandled underflow also appears to exist in
> > damos_get_node_memcg_used_bp() when evaluating DAMOS_QUOTA_NODE_MEMCG_FREE_BP
> > if used_pages exceeds totalram:
> >
> > mm/damon/core.c:damos_get_node_memcg_used_bp() {
> > ...
> > numerator = i.totalram - used_pages;
> > ...
> > }
>
> The intention of this revision was handling this, but I made a complete
> mistake. I will fix.
>
> >
> > > - else /* DAMOS_QUOTA_NODE_MEM_FREE_BP */
> > > + } else {
> > > + /* DAMOS_QUOTA_NODE_MEM_FREE_BP */
> > > + if (i.totalram < i.freeram)
> > > + return 0;
> >
> > [Severity: High]
> > When counter drift causes freeram > totalram, the node effectively has
> > ~100% free memory.
> >
> > By returning 0 (0% free memory) in this scenario, doesn't the DAMON quota
> > auto-tuning feedback loop interpret this as severely under-achieving the free
> > memory goal, causing it to wastefully and drastically increase the reclamation
> > budget (e.g., pageout/demotion) on a node that is already completely free?
> >
> > Should this return 10000 (100% free) instead?
>
> That depends on the perspective. I think 0% makes sense.
>
> >
> > > numerator = i.freeram;
> > > + }
> > > return mult_frac(numerator, 10000, i.totalram);
> > > }
> >
> > [Severity: High]
> > This is a pre-existing issue, but while this patch addresses a potential
> > divide-by-zero when si_meminfo_node() reports totalram = 0, does the same
> > unvalidated division exist in related functions?
> >
> > For example, damos_get_node_memcg_used_bp() divides by i.totalram without a
> > zero-check:
> >
> > mm/damon/core.c:damos_get_node_memcg_used_bp() {
> > ...
> > si_meminfo_node(&i, goal->nid);
> > ...
> > return mult_frac(numerator, 10000, i.totalram);
> > }
> >
> > Similarly, damos_get_in_active_mem_bp() divides by total (active + inactive)
> > via mult_frac() without checking if total is zero:
> >
> > mm/damon/core.c:damos_get_in_active_mem_bp() {
> > ...
> > if (goal->metric = DAMOS_QUOTA_SOME_MEM_USED_BP)
> > return mult_frac(active, 10000, total);
> > return mult_frac(inactive, 10000, total);
> > }
>
> Later patches in this series fix those.
>
> >
> > --
> > Sashiko AI review · https://sashiko.dev/#/patchset/20260802162631.90304-1-sj@kernel.org?part=7
> >
>
>
> Thanks,
> SJ
>
Thanks,
SJ
next prev parent reply other threads:[~2026-08-02 17:59 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-02 16:26 [RFC PATCH v1.1 0/9] mm/damon: fix DAMOS bugs in core, paddr and vaddr SJ Park
2026-08-02 16:26 ` [RFC PATCH v1.1 1/9] mm/damon/core: skip applying scheme if region split for quota fails SJ Park
2026-08-02 16:26 ` [RFC PATCH v1.1 2/9] mm/damon/core: initialize damos_quota_goal->last_psi_total SJ Park
2026-08-02 16:43 ` sashiko-bot
2026-08-02 17:41 ` SJ Park
2026-08-02 16:26 ` [RFC PATCH v1.1 3/9] mm/damon/paddr: respect folio end for DAMOS_STAT SJ Park
2026-08-02 16:34 ` sashiko-bot
2026-08-02 17:43 ` SJ Park
2026-08-02 16:26 ` [RFC PATCH v1.1 4/9] mm/damon/paddr: respect folio end for DAMOS actions except STAT SJ Park
2026-08-02 16:26 ` [RFC PATCH v1.1 5/9] mm/damon/vaddr: respect folio end for DAMOS_STAT SJ Park
2026-08-02 16:36 ` sashiko-bot
2026-08-02 17:45 ` SJ Park
2026-08-02 16:26 ` [RFC PATCH v1.1 6/9] mm/damon/vaddr: respect folio end for DAMOS_MIGRATE_{HOT,COLD} SJ Park
2026-08-02 16:26 ` [RFC PATCH v1.1 7/9] mm/damon/core: handle extreme memory state in damon_get_node_mem_bp() SJ Park
2026-08-02 16:35 ` sashiko-bot
2026-08-02 17:49 ` SJ Park
2026-08-02 17:59 ` SJ Park [this message]
2026-08-02 16:26 ` [RFC PATCH v1.1 8/9] mm/damon/core: handle extreme memory state in get_node_memcg_used_bp() SJ Park
2026-08-02 16:38 ` sashiko-bot
2026-08-02 17:51 ` SJ Park
2026-08-02 16:26 ` [RFC PATCH v1.1 9/9] mm/damon/core: handle extreme memory state in get_in_active_mem_bp() SJ Park
2026-08-02 16:51 ` sashiko-bot
2026-08-02 17:51 ` SJ Park
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260802175926.2322-1-sj@kernel.org \
--to=sj@kernel.org \
--cc=damon@lists.linux.dev \
--cc=sashiko-bot@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.