mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Kunwu Chan <kunwu.chan@gmail.com>
To: john <love_goo@163.com>
Cc: Kunwu Chan <kunwu.chan@gmail.com>,
	akpm@linux-foundation.org, liuye@kylinos.cn, hannes@cmpxchg.org,
	mhocko@kernel.org, david@kernel.org, ljs@kernel.org,
	hughd@google.com, mgorman@techsingularity.net,
	yang@os.amperecomputing.com, zhangqiuhao@huawei.com,
	wangkefeng.wang@huawei.com, mawupeng1@huwei.com,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	Wupeng Ma <mawupeng1@huawei.com>
Subject: Re: [PATCH resend 1/2] mm: vmscan: charge isolate overshoot against scan quota
Date: Wed,  9 Sep 2026 17:52:22 +0800	[thread overview]
Message-ID: <20260909095227.2522994-1-kunwu.chan@gmail.com> (raw)
In-Reply-To: <20260901084706.3784449-2-love_goo@163.com>

On Tue,  1 Sep 2026 16:47:05 +0800 john <love_goo@163.com> wrote:

> From: Wupeng Ma <mawupeng1@huawei.com>
> 
> shrink_lruvec() charges the per-LRU budget nr[lru] in SWAP_CLUSTER_MAX
> (32) chunks, but isolate_lru_folios() may scan far more per call: a
> large folio can jump scan by many pages at once (a PMD-sized folio
> counts 512), and a zone-ineligible LRU walks the whole list without
> feeding scan back.  The overshoot is never refunded, so shrink_lruvec()
> keeps charging only 32 per round and rescans the same folios.
> 
> Have isolate_lru_folios() record its scanned count in sc->nr_isolate_scanned
> and let shrink_lruvec() subtract the overshoot from the remaining quota so
> the next round skips already-scanned folios.  The field is reset to 0

I'm not sure this is true across shrink_lruvec() invocations.

isolate_lru_folios() splices folios_skipped back to the head of the LRU, 
while get_scan_count() provides a fresh nr[lru] each time shrink_lruvec() 
is entered. Thus, charging sc->nr_isolate_scanned against nr[lru] appears 
to prevent repeated 32-page scans within the same shrink_lruvec() 
invocation, but the same ineligible folios can still be encountered 
again by a subsequent invocation.

Is the intended fix specifically to avoid repeated scanning within one 
shrink_lruvec() invocation, or is there another mechanism that prevents 
these skipped folios from being rescanned by a subsequent shrink_lruvec() 
invocation?

Thanks,
KunWu

> before each shrink_list() call, as shrink_list() only reaches
> isolate_lru_folios() on some paths (active + skipped_deactivate,
> too_many_isolated stall bail out early); a stale value would otherwise
> be charged.  The budget floor stays nr_to_scan via max() so an empty
> LRU (sc->nr_isolate_scanned = 0) still advances and cannot deadlock.
> 
> Co-developed-by: Qiuhao Zhang <zhangqiuhao@huawei.com>
> Signed-off-by: Qiuhao Zhang <zhangqiuhao@huawei.com>
> Signed-off-by: Wupeng Ma <mawupeng1@huawei.com>
> ---
>  mm/vmscan.c | 32 +++++++++++++++++++++-----------
>  1 file changed, 21 insertions(+), 11 deletions(-)
> 
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index f11491ee9ed5c..823af9e86efd3 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -166,6 +166,9 @@ struct scan_control {
>  	/* Incremented by the number of inactive pages that were scanned */
>  	unsigned long nr_scanned;
>  
> +	/* Number of pages that were scanned from isolate_lru_folios() */
> +	unsigned long nr_isolate_scanned;
> +
>  	/* Number of pages freed so far during a call to shrink_zones() */
>  	unsigned long nr_reclaimed;
>  
> @@ -1670,7 +1673,6 @@ static __always_inline void update_lru_sizes(struct lruvec *lruvec,
>   * @nr_to_scan:	The number of eligible pages to look through on the list.
>   * @lruvec:	The LRU vector to pull pages from.
>   * @dst:	The temp list to put pages on to.
> - * @nr_scanned:	The number of pages that were scanned.
>   * @sc:		The scan_control struct for this reclaim session
>   * @lru:	LRU list id for isolating
>   *
> @@ -1678,8 +1680,7 @@ static __always_inline void update_lru_sizes(struct lruvec *lruvec,
>   */
>  static unsigned long isolate_lru_folios(unsigned long nr_to_scan,
>  		struct lruvec *lruvec, struct list_head *dst,
> -		unsigned long *nr_scanned, struct scan_control *sc,
> -		enum lru_list lru)
> +		struct scan_control *sc, enum lru_list lru)
>  {
>  	struct list_head *src = &lruvec->lists[lru];
>  	unsigned long nr_taken = 0;
> @@ -1763,7 +1764,7 @@ static unsigned long isolate_lru_folios(unsigned long nr_to_scan,
>  			skipped += nr_skipped[zid];
>  		}
>  	}
> -	*nr_scanned = total_scan;
> +	sc->nr_isolate_scanned = total_scan;
>  	trace_mm_vmscan_lru_isolate(sc->reclaim_idx, sc->order, nr_to_scan,
>  				    total_scan, skipped, nr_taken, lru);
>  	update_lru_sizes(lruvec, lru, nr_zone_taken);
> @@ -2011,8 +2012,8 @@ static unsigned long shrink_inactive_list(unsigned long nr_to_scan,
>  
>  	lruvec_lock_irq(lruvec);
>  
> -	nr_taken = isolate_lru_folios(nr_to_scan, lruvec, &folio_list,
> -				     &nr_scanned, sc, lru);
> +	nr_taken = isolate_lru_folios(nr_to_scan, lruvec, &folio_list, sc, lru);
> +	nr_scanned = sc->nr_isolate_scanned;
>  
>  	__mod_node_page_state(pgdat, NR_ISOLATED_ANON + file, nr_taken);
>  	item = PGSCAN_KSWAPD + reclaimer_offset(sc);
> @@ -2068,7 +2069,6 @@ static void shrink_active_list(unsigned long nr_to_scan,
>  			       enum lru_list lru)
>  {
>  	unsigned long nr_taken;
> -	unsigned long nr_scanned;
>  	vma_flags_t vma_flags;
>  	LIST_HEAD(l_hold);	/* The folios which were snipped off */
>  	LIST_HEAD(l_active);
> @@ -2082,12 +2082,11 @@ static void shrink_active_list(unsigned long nr_to_scan,
>  
>  	lruvec_lock_irq(lruvec);
>  
> -	nr_taken = isolate_lru_folios(nr_to_scan, lruvec, &l_hold,
> -				     &nr_scanned, sc, lru);
> +	nr_taken = isolate_lru_folios(nr_to_scan, lruvec, &l_hold, sc, lru);
>  
>  	__mod_node_page_state(pgdat, NR_ISOLATED_ANON + file, nr_taken);
>  
> -	mod_lruvec_state(lruvec, PGREFILL, nr_scanned);
> +	mod_lruvec_state(lruvec, PGREFILL, sc->nr_isolate_scanned);
>  
>  	lruvec_unlock_irq(lruvec);
>  
> @@ -6013,10 +6012,21 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
>  		for_each_evictable_lru(lru) {
>  			if (nr[lru]) {
>  				nr_to_scan = min(nr[lru], SWAP_CLUSTER_MAX);
> -				nr[lru] -= nr_to_scan;
>  
> +				sc->nr_isolate_scanned = 0;
>  				nr_reclaimed += shrink_list(lru, nr_to_scan,
>  							    lruvec, sc);
> +				/*
> +				 * isolate_lru_folios() may scan far more
> +				 * than nr_to_scan when the LRU holds
> +				 * ineligible folios (zone-skip) or large
> +				 * folios. Charge that overshoot against the
> +				 * remaining quota (clamped by min() so it
> +				 * cannot go negative) so the next iteration
> +				 * does not rescan the same skipped folios.
> +				 */
> +				nr[lru] -= min(nr[lru],
> +					       max(nr_to_scan, sc->nr_isolate_scanned));
>  			}
>  		}
>  
> -- 
> 2.53.0
> 
> 


  reply	other threads:[~2026-09-09  9:52 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-01  8:47 [PATCH resend 0/2] mm: vmscan: fix scan overshoot and ineligible folio scanning john
2026-09-01  8:47 ` [PATCH resend 1/2] mm: vmscan: charge isolate overshoot against scan quota john
2026-09-09  9:52   ` Kunwu Chan [this message]
2026-09-01  8:47 ` [PATCH resend 2/2] mm: vmscan: stop scanning ineligible folios after max_nr_skipped john
2026-09-09  9:56   ` Kunwu Chan
2026-09-08  1:49 ` [PATCH resend 0/2] mm: vmscan: fix scan overshoot and ineligible folio scanning john
2026-09-09  2:11 ` Andrew Morton

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=20260909095227.2522994-1-kunwu.chan@gmail.com \
    --to=kunwu.chan@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=david@kernel.org \
    --cc=hannes@cmpxchg.org \
    --cc=hughd@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=liuye@kylinos.cn \
    --cc=ljs@kernel.org \
    --cc=love_goo@163.com \
    --cc=mawupeng1@huawei.com \
    --cc=mawupeng1@huwei.com \
    --cc=mgorman@techsingularity.net \
    --cc=mhocko@kernel.org \
    --cc=wangkefeng.wang@huawei.com \
    --cc=yang@os.amperecomputing.com \
    --cc=zhangqiuhao@huawei.com \
    /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

all inboxes | Powered by JetHome®