From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f182.google.com (mail-pf1-f182.google.com [209.85.210.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0E5D037A829 for ; Thu, 30 Jul 2026 06:41:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.182 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785393693; cv=none; b=Pglo5DKYjXiMzbktQsQYpohEVMESsR3mcmlGCiHM9ZFpCWNpnd4TFADSLEtrztOZRseyMXQLADWjlSRayTz+Vu6w7EvR1lHTNvXYbrycC5xOOzeeLeHqI8Fv53iMDdLwGVAMHWGdtGQMuGZ0WiwjJYS0d0bTuZaSCPOeGYP3Kgk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785393693; c=relaxed/simple; bh=ncGx2x034kPe7uRveA+s1OBkCgUEUOn4UYyCmdCZi+g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=c4Kd7hNu4g4R95UN1MajNPXUmlyK6ZdQDnPjz5zIJZKrEHk8TDW8WI01NfOu+pCl5RjlarJ67/n5wT0yPBaGi5/1qhTM7bRK/qEw8ihJcfsINlI/VBoRfP54pNYORpb9qJHxQc8tixDLATCYl+JtBaOjn7j+CkcddpaW76kEueE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=nIhn3vSl; arc=none smtp.client-ip=209.85.210.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="nIhn3vSl" Received: by mail-pf1-f182.google.com with SMTP id d2e1a72fcca58-8487214ad2bso2667768b3a.1 for ; Wed, 29 Jul 2026 23:41:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785393691; x=1785998491; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=tykFrDMkx1MM1VG4l80NgytbO4sYhJ8jcy8WA1wreI0=; b=nIhn3vSlurq/BtrYtBnxj6IEpoNd8xrudCU2SerG2o/rFd108UDRTM2RWSSYU9YVDT Ffkk9xqp6MHQX+MPbVOpidNc23e9uD4aP1EHIWWY5LOIGjY40HeZDwYajnlCcwMnQ272 hDicBleAoVdK3sESX2g52pd0K7RdZGGI/JQC6Z0mTnvvHxjxoGxG3TM5Fpg7iMCvKjBI 9PykNvorhAlRXObBFWSsXldbSsVb3fG+GIeONsQkUfL4guReG+RluRU2T3pBVPQVCkSO j5WgmDxZ6qL6ztYSTz25Aw69qtWMcTf+Hc75FoIssPgvSgQvki8VIPQMbQcDp48hecty f/tg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785393691; x=1785998491; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=tykFrDMkx1MM1VG4l80NgytbO4sYhJ8jcy8WA1wreI0=; b=TF3JPLy2eGkgRttnNTGmGP/RzrrEgWheaSaJzx6kXaj2ihd7rsyr5+dptLFAKgpfzo CDJDdScryAFP3bHjT6a4lqWO6iwoVKDE4V4qgks+rjdrebsQQ0vwtAj33uDqtQASdCrf PZkjGvTTN8Y07wyRbVKhRt7fofel+5Sbt1XytnAXjf76m8/B6Z0RRpIwNvDnH312QTOT edJI4XfNSgfPVrcMX6KE1kcRQi9HDtfz9lOEbScnV68SGVaScjKysJc5qeint8hkIqz6 8U237mIOXaXxYuBuFnvwhdH0n15LEbzVPoByFL60DFPCUxo38aisMLhOnRXRbL0JmVKs oknQ== X-Forwarded-Encrypted: i=1; AHgh+RqUraE0QW20fIHf1rhOk0xrokI3lVDMjpdosUoZVJ5pvGnCYXqOwipeezWyDPqmn3qves4ucHpVzJlrR8w=@vger.kernel.org X-Gm-Message-State: AOJu0Yx5zpRCjEZw5rk7BFQKNzcMz5Vk0Hb2GWXOJFgaLWcbM4UC4BV4 1qFohFnyIQgQHgIO1Ip/myS3ayEVTmcfZrMEyEu2ztpia25msefS3I9X X-Gm-Gg: AR+sD10NAcsnp2BoodR+KfW8juV4euJatFfqcLkFU2CuCCm4V0QTWnQhj1tsO4EAfAk fTSRm6rTCNP0XdWKx8XiJyeT5T/Iq1NpLzkUj+4Ls5j18da2mQV2K11lxoeBmSsHqIHjw6L3keL n3oC9nuGAIQY4ERvQj01qp7hg/ElorDOM5J0C9lMgPys7rJE+vt6ng1Xiu4JqqZ7feKCsAzfPGi 3RPrTTtxdmAVZD1N8aL4yf8/1FwKY5IFESsVktkbUvxOCRN/Fo/z69YUbetWyTQX06FbAUbR9K4 GttKBwsI9MfGeB/EBOeHOdoG9FV5BQkJBRuxaA8KFWA6eGfpqdtkX3mIf3qFPE4FTmCk8eyqD2Z IpS2yFc1F7FItVDZztJng78oryg9uLdzLryThgi+qm5lVv+Y3Q4/mORVsu1bzPitZNSpKdtLQ0g UeqKWas/jGPBRDM2dfkit8eZL93PNbdR3fg48Zp0yW6yQY8S3w/7WLYDU0w/5eRvXBpQsXeZcSQ 0ldygHFssV5bA== X-Received: by 2002:a05:6a20:d612:b0:3c0:e6c3:224a with SMTP id adf61e73a8af0-3c900671988mr1409473637.37.1785393691247; Wed, 29 Jul 2026 23:41:31 -0700 (PDT) Received: from localhost.localdomain ([112.65.87.25]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cbdb79a3796sm1739829a12.3.2026.07.29.23.41.25 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Wed, 29 Jul 2026 23:41:30 -0700 (PDT) From: Lian Wang To: Barry Song Cc: Lian Wang , akpm@linux-foundation.org, linux-mm@kvack.org, hannes@cmpxchg.org, david@kernel.org, mhocko@kernel.org, qi.zheng@linux.dev, shakeel.butt@linux.dev, ljs@kernel.org, kasong@tencent.com, axelrasmussen@google.com, yuanchu@google.com, weixugc@google.com, linux-kernel@vger.kernel.org, lyugaofei@xiaomi.com, stevensd@chromium.org Subject: Re: [RFC PATCH v2 1/5] mm: mglru: avoid scanning empty generations in scan_folios() Date: Thu, 30 Jul 2026 14:41:22 +0800 Message-ID: <20260730064122.11785-1-lianux.mm@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Hi Barry, I tested a list-based exhaustion check on top of the v2 series. Using remaining > 0 still misses the case where remaining reaches zero exactly when the last folio leaves the oldest generation. Since scan_folios() still holds the lruvec lock, checking the generation's zone lists directly avoids both this boundary and the scanned/nr_to_scan page-versus-folio mismatch. The change below only replaces the exhaustion check. It keeps the priority-gated fallback unchanged, and reports the MIN_NR_GENS early return as exhausted to preserve the current v2 behavior. diff --git a/mm/vmscan.c b/mm/vmscan.c index 6a73be7590cd..59b8725a0650 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -4635,7 +4635,8 @@ static bool isolate_folio(struct lruvec *lruvec, struct folio *folio, struct sca static int scan_folios(unsigned long nr_to_scan, struct lruvec *lruvec, struct scan_control *sc, int type, int tier, - struct list_head *list, int *isolatedp) + struct list_head *list, int *isolatedp, + bool *scan_exhausted) { int i; int gen; @@ -4650,8 +4651,10 @@ static int scan_folios(unsigned long nr_to_scan, struct lruvec *lruvec, VM_WARN_ON_ONCE(nr_to_scan > MAX_LRU_BATCH); VM_WARN_ON_ONCE(!list_empty(list)); - if (get_nr_gens(lruvec, type) == MIN_NR_GENS) + if (get_nr_gens(lruvec, type) == MIN_NR_GENS) { + *scan_exhausted = true; return 0; + } gen = lru_gen_from_seq(lrugen->min_seq[type]); @@ -4704,6 +4707,14 @@ static int scan_folios(unsigned long nr_to_scan, struct lruvec *lruvec, scanned, skipped, isolated, type ? LRU_INACTIVE_FILE : LRU_INACTIVE_ANON); + *scan_exhausted = true; + for (i = 0; i < MAX_NR_ZONES; i++) { + if (!list_empty(&lrugen->folios[gen][type][i])) { + *scan_exhausted = false; + break; + } + } + *isolatedp = isolated; return scanned; } @@ -4757,11 +4768,13 @@ static int isolate_folios(unsigned long nr_to_scan, struct lruvec *lruvec, int type = get_type_to_scan(lruvec, swappiness); for_each_evictable_type(i, swappiness) { + bool scan_exhausted; int scanned; int tier = get_tier_idx(lruvec, type); scanned = scan_folios(nr_to_scan, lruvec, sc, - type, tier, list, isolated); + type, tier, list, isolated, + &scan_exhausted); total_scanned += scanned; if (*isolated) { @@ -4770,15 +4783,12 @@ static int isolate_folios(unsigned long nr_to_scan, struct lruvec *lruvec, break; } /* - * If scanned >= nr_to_scan or isolated >= MIN_LRU_BATCH, - * avoid falling back to the other type. The preferred - * type is still reclaimable; otherwise, it would have - * already run out of reclaimable generations. Falling - * back too readily can disrupt the positive_ctrl_err() - * bias. Also, only fall back when reclaim is running at - * a high priority. + * The preferred type is still reclaimable unless this scan + * target is exhausted. Preserve the existing priority-gated + * fallback without inferring exhaustion from scanned, which + * counts base pages rather than iterations. */ - if (scanned < nr_to_scan && *isolated < MIN_LRU_BATCH) { + if (scan_exhausted) { if (sc->priority > 2) break; type = !type; I built and booted this on an arm64 VM with MGLRU enabled. A fresh swappiness=200 pressure smoke with a 2 GiB file-cache setup and about 7 GiB of touched anonymous memory completed without a WARN/Oops/BUG/panic. Would this be worth considering for the next revision? If I misunderstood the intended semantics, please ignore this. Thanks, Lian