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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox