From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from out30-132.freemail.mail.aliyun.com (out30-132.freemail.mail.aliyun.com [115.124.30.132]) (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 B45243537EE for ; Mon, 22 Jun 2026 04:07:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.132 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782101230; cv=none; b=aaWWiYN3snsRnRd8syWvr8e7m1ZLNqclgzGVAVBgZgt3IIpQIdOzjIDVzKrABfCXu4eKnF9d4huihhsVgfpNOSqTVdoLD4GbOcJoNsHEEkSTAwuRCf4wK0TFYDA0KYE7YslA4C8jPEQ0M9NYhEqtsfMQoWtSCkGwgWLP6gcVj3Y= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782101230; c=relaxed/simple; bh=TAlyclel+uzhxtPpcndJN+cYfDsnhGpP24SOpvC7X50=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=NGyE0SphjQanM9GYv20mZ/Uw5pLIdgGUr0jO8t5GSsttNpcRz31V5nr5z+IrU5hKZXjScGR25GddEJsgyZbvbPgkmOycbUBUWiAS4clCQi8MSu0hixBnpbAO5raQuxj4g61HB+zXrx1nLR+0usK9W76lFE2OTt4+tpxBbd+C9Lc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=CNaLxT9x; arc=none smtp.client-ip=115.124.30.132 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="CNaLxT9x" DKIM-Signature:v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1782101217; h=Message-ID:Date:MIME-Version:Subject:To:From:Content-Type; bh=rOuZYODIvBG/kbzslXXXSihA6AhxcXkn77Yw1lY3LFs=; b=CNaLxT9xgda4HGQP31qVcGKdsYs2k76eTyaEp9W+nBm748HR2T4hSF+un28Z3yOvoTId1365LgdGJPDJypyxspK9EyGbs0xWuGj6rTmPjmWtSjCJeBGXzC+NteFDuI9vyCzmcGlaRljhzn4zyltciAG2He6FeJYi5NuITfh6aFE= X-Alimail-AntiSpam:AC=PASS;BC=-1|-1;BR=01201311R691e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam011083073210;MF=baolin.wang@linux.alibaba.com;NM=1;PH=DS;RN=19;SR=0;TI=SMTPD_---0X5H70mj_1782101214; Received: from 30.74.144.120(mailfrom:baolin.wang@linux.alibaba.com fp:SMTPD_---0X5H70mj_1782101214 cluster:ay36) by smtp.aliyun-inc.com; Mon, 22 Jun 2026 12:06:55 +0800 Message-ID: Date: Mon, 22 Jun 2026 12:06:54 +0800 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [RFC PATCH] mm: Avoiding split large folios if swap has no space To: Barry Song Cc: david@kernel.org, akpm@linux-foundation.org, axelrasmussen@google.com, dev.jain@arm.com, kasong@tencent.com, lance.yang@linux.dev, liam@infradead.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, ljs@kernel.org, npache@redhat.com, qi.zheng@linux.dev, ryan.roberts@arm.com, shakeel.butt@linux.dev, weixugc@google.com, yuanchu@google.com, zhaonanzhe@xiaomi.com, ziy@nvidia.com References: <5790c4a4-d502-4180-82f5-47de5809a4fe@kernel.org> <20260620081017.89085-1-baohua@kernel.org> <6e89f868-ca7a-484f-aeea-5d8d029714f2@linux.alibaba.com> From: Baolin Wang In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit On 6/22/26 11:36 AM, Barry Song wrote: > On Mon, Jun 22, 2026 at 11:04 AM Baolin Wang > wrote: >> >> >> >> On 6/20/26 4:10 PM, Barry Song (Xiaomi) wrote: >>> On Fri, Jun 19, 2026 at 10:04 PM David Hildenbrand (Arm) wrote: >>> [...] >>>>> /* >>>>> * The page can not be swapped. >>>>> * >>>>> @@ -1280,6 +1289,8 @@ static unsigned int shrink_folio_list(struct list_head *folio_list, >>>>> >>>>> if (!folio_test_large(folio)) >>>>> goto activate_locked_split; >>>>> + if (!__can_reclaim_anon_pages(memcg, sc)) >>>>> + goto activate_locked_split; >>>> >>>> Why are we even trying to allocate swap space if we cannot reclaim such pages? >>>> Makes we wonder whether we would want to have that check earlier, before the >>>> folio_alloc_swap(). >>>> >>>> Any downsides? >>> >>> I don't think there are any obvious downsides there. One issue is that >>> the memcg may not be passed from reclaim_pages(), so memcg would >>> always be NULL. However, the folio could still belong to a memcg >>> whose swap quota has been exhausted. In that case, my >>> __can_reclaim_anon_pages() will fail when checking whether we can >>> swap out. But switching to folio_memcg() also seems awkward. >>> >>> So I feel Kairui’s suggestion [1] might be the best approach. In >>> folio_alloc_swap(), we return -EAGAIN to tell vmscan.c that >>> we can split the folio and retry the swap-out. >>> only when there are sufficient swap slots and sufficient memcg swap >>> quota do we return -EAGAIN, allowing vmscan to perform a split. >>> >>> diff --git a/mm/swapfile.c b/mm/swapfile.c >>> index 78b49b0658ad..62e2c506ccae 100644 >>> --- a/mm/swapfile.c >>> +++ b/mm/swapfile.c >>> @@ -1755,6 +1755,9 @@ int folio_alloc_swap(struct folio *folio) >>> VM_WARN_ON_ONCE(1); >>> return -EINVAL; >>> } >>> + >>> + if (get_nr_swap_pages() < (1 << order)) >>> + return -ENOMEM; >> >> Shouldn't this return -EAGAIN? Suppose we try to swap out an order-9 >> large folio but get_nr_swap_pages() returns 256, then we'd still need to >> split the order-9 large folio to reclaim some memory. > > I guess Kairui has the opposite view. Quoting Kairui: > > "- 1. the mem_cgroup_try_charge_swap in it failed > - 2. allocation failed but nr_swap_pages > folio size > - 3. allocation failed because all devices are full or unusable > (roughly nr_swap_pages < folio size) > > Only case 2 requires splitting. __can_reclaim_anon_pages also checks > demote which is not related to swap." > > For example, if get_nr_swap_pages() returns 1, we can only > swap out a single page after splitting. Is that really worth > it? On the other hand, if it returns 256, we could at least > swap out half of an order-9 large folio. Isn't that worthwhile? The former doesn't seem necessary, but the latter might be worthwhile. After splitting, we could potentially avoid premature OOM. Of course, splitting also means losing an order-9 large folio, but we can rely on khugepaged to collapse it into a THP again. But the consequences of OOM are arguably more severe? Anyway, just raising my concern here (I don't have data at this point to justify whether more complex logic is needed). >>> again: >>> @@ -1769,11 +1772,13 @@ int folio_alloc_swap(struct folio *folio) >>> } >>> >>> /* Need to call this even if allocation failed, for MEMCG_SWAP_FAIL. */ >>> - if (unlikely(mem_cgroup_try_charge_swap(folio))) >>> + if (unlikely(mem_cgroup_try_charge_swap(folio))) { >>> swap_cache_del_folio(folio); >>> + return -ENOMEM; >>> + } >>> >>> if (unlikely(!folio_test_swapcache(folio))) >>> - return -ENOMEM; >>> + return -EAGAIN; >>> >>> return 0; >>> } >>> diff --git a/mm/vmscan.c b/mm/vmscan.c >>> index 299b5d9e8836..63e8578454ea 100644 >>> --- a/mm/vmscan.c >>> +++ b/mm/vmscan.c >>> @@ -1257,6 +1257,8 @@ static unsigned int shrink_folio_list(struct list_head *folio_list, >>> */ >>> if (folio_test_anon(folio) && folio_test_swapbacked(folio) && >>> !folio_test_swapcache(folio)) { >>> + int ret; >>> + >>> if (!(sc->gfp_mask & __GFP_IO)) >>> goto keep_locked; >>> if (folio_maybe_dma_pinned(folio)) >>> @@ -1275,10 +1277,10 @@ static unsigned int shrink_folio_list(struct list_head *folio_list, >>> split_folio_to_list(folio, folio_list)) >>> goto activate_locked; >>> } >>> - if (folio_alloc_swap(folio)) { >>> + if ((ret = folio_alloc_swap(folio))) { >> >> Also, please give shmem some love (shmem also calls folio_alloc_swap() >> when swapping out) :) > > Sure. I'm pretty sure I love shmem. :-) Thanks.