From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A74842F7F1F for ; Tue, 1 Sep 2026 03:40:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788234003; cv=none; b=OlXvJhXQ2ja5Cbta1cU4HMNbV0zUtIkMHyXUN8YYBhbFX8Iq0+xUAFdRO6Wbfnh/enVcNDLEZGEtjPsFQp+3aFoKstz+zx1qOv6W1A9jL21ZMqfSY7lUOeKYxl8s6OWPxI9LKn2KKIzTt/VSQuoGRsxE2G8AGenXscnhcWV+eOA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788234003; c=relaxed/simple; bh=X0CChhXCCHMMt5loJLMxUxMRNHUt5H/yd4fLlwXEYKY=; h=Date:To:From:Subject:Message-Id; b=pT3CXAesA+W60Xs0xZ7Jk21LaJkYsbo1Jgpr3CZLDB4MRBLO3u+1dEQaZ50khRPvAHB4xgCNKLni9bOgVQS2X6eDK2ZY5SJZ4230oF3dWipWzITACMvJBy+xPO2mBvflElddagTRiivxWniSKegoo3dmeFkRB2sTCL2i8YS2FdE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b=Qm4eLcpr; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b="Qm4eLcpr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 49FE21F000E9; Tue, 1 Sep 2026 03:40:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux-foundation.org; s=korg; t=1788234001; bh=TpxJvUMhgW19Jp4ZFiVBJff8a0OOK7MNVYKWRL5vJr0=; h=Date:To:From:Subject; b=Qm4eLcprCpCHKDn5IKTm9iwKuGEzSjazEc9Fyex3VKhc47x3SPdIShifvTOFwnpFT krAte2SuNvG3LWcOtmO1Z2CgBsHXdbSZ6ZUO3Wuwa6/8Z3pujJJuq7huQ87zWQTmzJ FcjVvi/KQGqrTrVcbNT1zFYZyXdOtntbS+zZ/T1M= Date: Mon, 31 Aug 2026 20:40:00 -0700 To: mm-commits@vger.kernel.org,zhaonanzhe@xiaomi.com,youngjun.park@lge.com,xueyuan.chen21@gmail.com,shikemeng@huaweicloud.com,shakeel.butt@linux.dev,ryncsn@gmail.com,roman.gushchin@linux.dev,nphamcs@gmail.com,muchun.song@linux.dev,mhocko@kernel.org,ljs@kernel.org,hughd@google.com,david@kernel.org,chrisl@kernel.org,baoquan.he@linux.dev,baolin.wang@linux.alibaba.com,baohua@kernel.org,hannes@cmpxchg.org,akpm@linux-foundation.org From: Andrew Morton Subject: + mm-add-page_counter_margin.patch added to mm-new branch Message-Id: <20260901034001.49FE21F000E9@smtp.kernel.org> Precedence: bulk X-Mailing-List: mm-commits@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: The patch titled Subject: mm: add page_counter_margin() has been added to the -mm mm-new branch. Its filename is mm-add-page_counter_margin.patch This patch will shortly appear at https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-add-page_counter_margin.patch This patch will later appear in the mm-new branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Note, mm-new is a provisional staging ground for work-in-progress patches, and acceptance into mm-new is a notification for others take notice and to finish up reviews. Please do not hesitate to respond to review feedback and post updated versions to replace or incrementally fixup patches in mm-new. The mm-new branch of mm.git is not included in linux-next If a few days of testing in mm-new is successful, the patch will me moved into mm.git's mm-unstable branch, which is included in linux-next Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next via various branches at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm and is updated there most days ------------------------------------------------------ From: Johannes Weiner Subject: mm: add page_counter_margin() Date: Sun, 30 Aug 2026 12:29:17 +0800 Patch series "mm: avoid large folio splits when swap is unavailable", v7. This is v7 of Barry's original RFC patch, "mm: Avoiding split large folios if swap has no space": https://lore.kernel.org/r/20260618221720.71768-1-baohua@kernel.org Barry's RFC showed the no-swap case with MADV_PAGEOUT on 16KB mTHP: the large-folio split counter increased by 1024 even though no swapout progress was possible. Skipping the split in that case kept the counter at 0. This series makes folio_alloc_swap() classify failures according to whether splitting a large folio might allow swapout to make progress. Callers can then avoid destroying the large folio when neither global swap availability nor the folio's memcg swap hierarchy has capacity for even a smaller folio. Patch #1 adds page_counter_margin(), a small helper that computes the minimum remaining chargeable space across a page_counter hierarchy. Patch #2 establishes the folio_alloc_swap() return-value contract: - -E2BIG: splitting may let smaller folios make progress - -ENOSPC: no global swap space is available - -ENOMEM: splitting is not expected to help, including when the folio's memcg swap hierarchy has no remaining capacity Patch #3 makes vmscan split a large folio only when folio_alloc_swap() returns -E2BIG. Other failures keep the existing activation path and avoid destroying the large folio when no smaller part can be backed by swap either. Patch #4 applies the same contract to shmem_writeout(), which currently splits a large folio on every folio_alloc_swap() failure. It now enters the split fallback only on -E2BIG; other failures redirty and reactivate the folio as before. Testing: With a 1GB anonymous mapping backed by 16KB mTHPs and memory.swap.max=0, the patch reduced the median latency of 30 process_madvise(MADV_PAGEOUT) runs from 743.8 ms to 181.7 ms, while the number of large-folio splits per run dropped from 65536 to 0. Neither kernel swapped out any pages. I also ran DaCapo h2 under swap pressure and found no statistically significant change in wall time or CPU time. The overall benefit appears minor and workload-dependent. This patch (of 4): mem_cgroup_get_nr_swap_pages() open-codes the remaining capacity across the memcg swap counter hierarchy. Add page_counter_margin() to return the minimum usable space from a page counter to the root, and use it in mem_cgroup_get_nr_swap_pages(). This is a pure refactoring with no intended behavior change. Link: https://lore.kernel.org/20260830042920.2280454-1-xueyuan.chen21@gmail.com Link: https://lore.kernel.org/20260830042920.2280454-2-xueyuan.chen21@gmail.com Signed-off-by: Johannes Weiner Signed-off-by: Xueyuan Chen Reviewed-by: David Hildenbrand (Arm) Reviewed-by: Barry Song Cc: Baolin Wang Cc: Baoquan He Cc: Chris Li Cc: Hugh Dickins Cc: Kairui Song Cc: Kemeng Shi Cc: Lorenzo Stoakes Cc: Michal Hocko Cc: Muchun Song Cc: Nhat Pham Cc: Roman Gushchin Cc: Shakeel Butt Cc: Nanzhe Zhao Cc: Youngjun Park Signed-off-by: Andrew Morton --- include/linux/page_counter.h | 1 + mm/memcontrol.c | 9 +++------ mm/page_counter.c | 20 ++++++++++++++++++++ 3 files changed, 24 insertions(+), 6 deletions(-) --- a/include/linux/page_counter.h~mm-add-page_counter_margin +++ a/include/linux/page_counter.h @@ -68,6 +68,7 @@ static inline unsigned long page_counter return atomic_long_read(&counter->usage); } +long page_counter_margin(struct page_counter *counter); void page_counter_cancel(struct page_counter *counter, unsigned long nr_pages); void page_counter_charge(struct page_counter *counter, unsigned long nr_pages); bool page_counter_try_charge(struct page_counter *counter, --- a/mm/memcontrol.c~mm-add-page_counter_margin +++ a/mm/memcontrol.c @@ -5826,12 +5826,9 @@ long mem_cgroup_get_nr_swap_pages(struct { long nr_swap_pages = get_nr_swap_pages(); - if (mem_cgroup_disabled() || do_memsw_account()) - return nr_swap_pages; - for (; !mem_cgroup_is_root(memcg); memcg = parent_mem_cgroup(memcg)) - nr_swap_pages = min_t(long, nr_swap_pages, - READ_ONCE(memcg->swap.max) - - page_counter_read(&memcg->swap)); + if (!mem_cgroup_disabled() && !do_memsw_account()) + nr_swap_pages = min(nr_swap_pages, page_counter_margin(&memcg->swap)); + return nr_swap_pages; } --- a/mm/page_counter.c~mm-add-page_counter_margin +++ a/mm/page_counter.c @@ -47,6 +47,26 @@ static void propagate_protected_usage(st } /** + * page_counter_margin - remaining usable space within hierarchical limits + * @counter: counter + * + * Return: The minimum value of max minus usage across @counter and all of + * its ancestors. The value may be negative during a concurrent charge. + */ +long page_counter_margin(struct page_counter *counter) +{ + long margin = PAGE_COUNTER_MAX; + + do { + long m = READ_ONCE(counter->max) - page_counter_read(counter); + + margin = min(margin, m); + } while ((counter = counter->parent)); + + return margin; +} + +/** * page_counter_cancel - take pages out of the local counter * @counter: counter * @nr_pages: number of pages to cancel _ Patches currently in -mm which might be from hannes@cmpxchg.org are mm-add-page_counter_margin.patch