All of lore.kernel.org
 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 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.