From patchwork Sat Jun 29 11:10:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Barry Song <21cnbao@gmail.com> X-Patchwork-Id: 13716891 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8B04BC30658 for ; Sat, 29 Jun 2024 11:10:53 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 1AC236B008A; Sat, 29 Jun 2024 07:10:53 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 15B566B008C; Sat, 29 Jun 2024 07:10:53 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id F3E3F6B0092; Sat, 29 Jun 2024 07:10:52 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0017.hostedemail.com [216.40.44.17]) by kanga.kvack.org (Postfix) with ESMTP id D75EC6B008A for ; Sat, 29 Jun 2024 07:10:52 -0400 (EDT) Received: from smtpin23.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id 487F3A300C for ; Sat, 29 Jun 2024 11:10:52 +0000 (UTC) X-FDA: 82283658744.23.7B52A04 Received: from mail-pl1-f171.google.com (mail-pl1-f171.google.com [209.85.214.171]) by imf11.hostedemail.com (Postfix) with ESMTP id 6B6884001C for ; Sat, 29 Jun 2024 11:10:50 +0000 (UTC) Authentication-Results: imf11.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=QCvFejjp; spf=pass (imf11.hostedemail.com: domain of 21cnbao@gmail.com designates 209.85.214.171 as permitted sender) smtp.mailfrom=21cnbao@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1719659440; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=Ew+Hn1X3ubfi24qMFkHWDEj0VD3/JfMS/ycW8uy8Ae0=; b=WPuGQr5dfpQ+5LNbwkbHHRIhQ6yyz5MsmvgbiWcOd08xG0euIyR4F96AMFPdwp+kAzWNp8 gCQVEctVHpvxD4kDxnNIDwGE+JAhqX8zYKunXWkNn1ww/HbdkM+tyoL36FMNqE43rujDNF iH1vMoWSh0/Xk6+vfTY/f4OuO4oIoNw= ARC-Authentication-Results: i=1; imf11.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=QCvFejjp; spf=pass (imf11.hostedemail.com: domain of 21cnbao@gmail.com designates 209.85.214.171 as permitted sender) smtp.mailfrom=21cnbao@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1719659440; a=rsa-sha256; cv=none; b=Jazppxh987C00wpnm6e0U8hgbNuqvqAvVH/wti8ODLHtgMXNVQHcxmmSBaf1s/VrUzsylF L+CNd5mg2JYlZAqS1TBA8Gl14tsiEHt0ynwLQARaVbbwbMsd+T15zHeX4WMLXWR9f8jYf1 GPqehYz4BOFiEUtg5AdFVj47s5xfgZc= Received: by mail-pl1-f171.google.com with SMTP id d9443c01a7336-1f9b523a15cso9669265ad.0 for ; Sat, 29 Jun 2024 04:10:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719659449; x=1720264249; darn=kvack.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; bh=Ew+Hn1X3ubfi24qMFkHWDEj0VD3/JfMS/ycW8uy8Ae0=; b=QCvFejjp82R0ZhQrOsi2yCwSQAyM0/cWALLuiTo4MMbTOuHSulqixzat4dU1Nj7TS4 rpv+G1xC9dKP9JIwr38zIuugFV9uD+0GnWv2SlwGfBtn6D3Y+nTYGAwyM7raO8FmlENe TGJY93wDHurwja0ekXi4zueduPuQDQd1tcUQmpwcneUSPA8s8v67lJ7wTbmay9qEMmUV 6C822mWmMVWH1fKgDp6r+bRGzAMct5i2zsCj6fNaI6KEZT8/Mci+4KIZAjRf0poncN0U vISdcKd7uM5Qh40PQ2Hcz1/JiWihLZ2RU79c6Shf+6XdRM5uLukURIw3sLbRS4NltM7X 6FuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719659449; x=1720264249; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Ew+Hn1X3ubfi24qMFkHWDEj0VD3/JfMS/ycW8uy8Ae0=; b=r8wJXKtnrLQiESkCiCFvTNyiES28CihpKA/Yvl8Tu2pFIK/PMkUzyBcp+01KhUh70A yKNuPu018JotlPZeaCfv2tNKBGq87mgiOtvT/BfprJr0z/F0p2Az9TPOaC2ORoww83EY M5ouS+Ks1SG6nHbk7knCie9EFa+ANuS12JUtK9M4Jp50Lqjo0VDLjBil2jmmhKR4Yeqj OBTpBULQN8y+Li0agNJB45LPcRlxh24nWAfw8LWtfOlhA8Wq33IfMdhtP/fwV24st3Ar DUckei7VP14aLW/Nq92LvQBh43JskvI0lBvhVEoyr/sJoSL0RoeIcWA0Kl+4T1Fjl/Uf 9k6g== X-Forwarded-Encrypted: i=1; AJvYcCXZkQKOCaEEe1Jj//5hi8upGYPUgUJcNNDF4a8qMMK3tQ71tJ0Mqoyhrq3kBrt+YitXxhWGcEDL5vtPAm5ITxSQNiI= X-Gm-Message-State: AOJu0YwkmeN9IO861pm9Y1R9x1sr9SsRwctVKzm8zhCgDxkGeYtEjhSF uK2lvV/+caIGO14fSEDWQGlHDy7aWpwd/Hsy5HvFbqNuOveFqJjl X-Google-Smtp-Source: AGHT+IF2LvXe/M/aBKc7IHeoM2uFyQ99DWns8BLeSfOB7NogMxfp7QfZubs9znaxk8dANr939azsTA== X-Received: by 2002:a17:902:f68c:b0:1f9:e3fa:d932 with SMTP id d9443c01a7336-1fadb433a92mr15486365ad.9.1719659449115; Sat, 29 Jun 2024 04:10:49 -0700 (PDT) Received: from localhost.localdomain ([2407:7000:8942:5500:aaa1:59ff:fe57:eb97]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fac1596920sm30068975ad.268.2024.06.29.04.10.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 29 Jun 2024 04:10:48 -0700 (PDT) From: Barry Song <21cnbao@gmail.com> To: akpm@linux-foundation.org, linux-mm@kvack.org Cc: chrisl@kernel.org, david@redhat.com, hannes@cmpxchg.org, kasong@tencent.com, linux-kernel@vger.kernel.org, mhocko@suse.com, nphamcs@gmail.com, ryan.roberts@arm.com, shy828301@gmail.com, surenb@google.com, kaleshsingh@google.com, hughd@google.com, v-songbaohua@oppo.com, willy@infradead.org, xiang@kernel.org, ying.huang@intel.com, yosryahmed@google.com, baolin.wang@linux.alibaba.com, shakeel.butt@linux.dev, senozhatsky@chromium.org, minchan@kernel.org, Chuanhua Han Subject: [PATCH RFC v4 2/2] mm: support large folios swapin as a whole for zRAM-like swapfile Date: Sat, 29 Jun 2024 23:10:10 +1200 Message-Id: <20240629111010.230484-3-21cnbao@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240629111010.230484-1-21cnbao@gmail.com> References: <20240629111010.230484-1-21cnbao@gmail.com> MIME-Version: 1.0 X-Rspamd-Server: rspam11 X-Rspamd-Queue-Id: 6B6884001C X-Stat-Signature: 3gs8j3dhg4zoxpzj76b4xgejpwdnadap X-Rspam-User: X-HE-Tag: 1719659450-10072 X-HE-Meta: U2FsdGVkX18HHANtaL/2NiZnjNRaWCTYsMHwHuPq6MYVjhDcge6NJI+xo46mdiu6GJ6sVmeCs2vWrQZiyGur1IPeAoiJumPqRwCrs8WvSTknP+uDJC6LZhZLVYYV0FickuduEjwUHUoZ5xni4HLtfjhavPB265pNAyCxwgRkf8jKznN3Ul3JhYwqfh2ncUixPk3yysKuOr/U0moWnwfgO/0ibpSGBeIISLpYfKFENsRy894H4Q6ZaoQaBA3CY8X99m9UeqTpYyTRRT4DjQZtqyVLXt4iQwKfCfyPRpn53ZXQ2/lmgmN6+jcxsSWYYcsp175PsITNUHBeyd9jbnh33wZt+CfjPGT+WC6XcMX3piIr6o2Eh5eUG9KBrXRGqC1mfSAf1Jb1w5kQlJTnBaDpfwrtqxBesnnQzg7nX8C2aVxpCotJMBCFmIf5MzoTTqFhn+z4L+KZHEu29R+nve7x0yywHkklHmuB/n/+1dHkXfioz7HEhWnyPA9TT9Wt+cvH6xj48+R7/gzwoMKZB/L44/5FJB1g2zt+nzcGuikBEPyuGx8w+m6oVQbaOD3fNGTC0yf1mc/bvQAaSYvX83hpZM76ogNgCdXjeKMLoqFAt4mCkDK4gTd4ypsY5VH6talpt32BsnGaTDBBegbzfvN+kESMK0tqxJqdohsS0q6LeZdMPdzYxTW9LKnqKyb6m0uI/YqJBWNSUhCeTzMx/iTkb9TgdGmjek8QjdfRgtGAAWETNdk9BUoN1GaRfD4DfQ7fWBftPhfNWOZC9ERUUyKUlRBNRYeKMTH5BTRjh+GLC1Rc4SfGOEuyARXr3uDn57qEpmC6wu8Q2qWk8zIH3SxSSehjQ+tZVJiaIMe6lcpmgFsTcciaFCyMebPkmV0+GMVYj3w2CfS48ufY3PufTPvu3Y+35pLKWzzPk6T81EVJTaA1nXq/EKdawq8h5GYwVbWtXCQ0yr8fYVq3/wNMT32 8f2+KlOm O2qei6YX5hsiwMK8L4P03Xtu9R9XL2P7xawoaU9Q+fLp9hR+ECCZ9Uppxak4o5TFkIBxbKttzxrsCgvD3dYWo1hx57xrgoBMxuyYH9VvalpopVJArk6sx7KX8Bt2kEGAVwZlfZpar/bCejB7virYM1GJImWgiwFx9LzjAUDS+gSLmtPsnP2HtfUplWjEtB7Ec02256qlPfIqQQUDiBbL7Z/QfGpd+AYPeaiR0RiVwBepUjwjHdKacXiiQnvAwaIvEG7+8nXSBoJEa2eoMdphSDn0UNk55RuPJNojdEAJiYLevMrpYPnVXHReV/foL9hRKEK1Ys+Pv+x/f5ZhmoqFgbk6yW/G1bsnqlPoiMsnkparcG58eXp0Vl1B5H8UYv7sKlAPzxEh0hKFO+BTkqwyPbmEIZqUfThqoQwmnoBW8b+O3kzhhLGRPfkUymA== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: From: Chuanhua Han In an embedded system like Android, more than half of anonymous memory is actually stored in swap devices such as zRAM. For instance, when an app is switched to the background, most of its memory might be swapped out. Currently, we have mTHP features, but unfortunately, without support for large folio swap-ins, once those large folios are swapped out, we lose them immediately because mTHP is a one-way ticket. This patch introduces mTHP swap-in support. For now, we limit mTHP swap-ins to contiguous swaps that were likely swapped out from mTHP as a whole. Additionally, the current implementation only covers the SWAP_SYNCHRONOUS case. This is the simplest and most common use case, benefiting millions of Android phones and similar devices with minimal implementation cost. In this straightforward scenario, large folios are always exclusive, eliminating the need to handle complex rmap and swapcache issues. It offers several benefits: 1. Enables bidirectional mTHP swapping, allowing retrieval of mTHP after swap-out and swap-in. 2. Eliminates fragmentation in swap slots and supports successful THP_SWPOUT without fragmentation. 3. Enables zRAM/zsmalloc to compress and decompress mTHP, reducing CPU usage and enhancing compression ratios significantly. Deploying this on millions of actual products, we haven't observed any noticeable increase in memory footprint for 64KiB mTHP based on CONT-PTE on ARM64. Signed-off-by: Chuanhua Han Co-developed-by: Barry Song Signed-off-by: Barry Song --- include/linux/zswap.h | 2 +- mm/memory.c | 210 +++++++++++++++++++++++++++++++++++------- mm/swap_state.c | 2 +- 3 files changed, 181 insertions(+), 33 deletions(-) diff --git a/include/linux/zswap.h b/include/linux/zswap.h index bf83ae5e285d..6cecb4a4f68b 100644 --- a/include/linux/zswap.h +++ b/include/linux/zswap.h @@ -68,7 +68,7 @@ static inline bool zswap_is_enabled(void) static inline bool zswap_never_enabled(void) { - return false; + return true; } #endif diff --git a/mm/memory.c b/mm/memory.c index 0a769f34bbb2..41ec7b919c2e 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -3987,6 +3987,141 @@ static vm_fault_t handle_pte_marker(struct vm_fault *vmf) return VM_FAULT_SIGBUS; } +/* + * check a range of PTEs are completely swap entries with + * contiguous swap offsets and the same SWAP_HAS_CACHE. + * ptep must be first one in the range + */ +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +static bool can_swapin_thp(struct vm_fault *vmf, pte_t *ptep, int nr_pages) +{ + struct swap_info_struct *si; + unsigned long addr; + swp_entry_t entry; + pgoff_t offset; + char has_cache; + int idx, i; + pte_t pte; + + addr = ALIGN_DOWN(vmf->address, nr_pages * PAGE_SIZE); + idx = (vmf->address - addr) / PAGE_SIZE; + pte = ptep_get(ptep); + + if (!pte_same(pte, pte_move_swp_offset(vmf->orig_pte, -idx))) + return false; + entry = pte_to_swp_entry(pte); + offset = swp_offset(entry); + if (!IS_ALIGNED(offset, nr_pages)) + return false; + if (swap_pte_batch(ptep, nr_pages, pte) != nr_pages) + return false; + + si = swp_swap_info(entry); + has_cache = si->swap_map[offset] & SWAP_HAS_CACHE; + for (i = 1; i < nr_pages; i++) { + /* + * while allocating a large folio and doing swap_read_folio for the + * SWP_SYNCHRONOUS_IO path, which is the case the being faulted pte + * doesn't have swapcache. We need to ensure all PTEs have no cache + * as well, otherwise, we might go to swap devices while the content + * is in swapcache + */ + if ((si->swap_map[offset + i] & SWAP_HAS_CACHE) != has_cache) + return false; + } + + return true; +} + +/* + * Get a list of all the (large) orders below PMD_ORDER that are enabled + * for this vma. Then filter out the orders that can't be allocated over + * the faulting address and still be fully contained in the vma. + */ +static inline unsigned long get_alloc_folio_orders(struct vm_fault *vmf) +{ + struct vm_area_struct *vma = vmf->vma; + unsigned long orders; + + orders = thp_vma_allowable_orders(vma, vma->vm_flags, + TVA_IN_PF | TVA_ENFORCE_SYSFS, BIT(PMD_ORDER) - 1); + orders = thp_vma_suitable_orders(vma, vmf->address, orders); + return orders; +} +#else +static inline bool can_swapin_thp(struct vm_fault *vmf, pte_t *ptep, int nr_pages) +{ + return false; +} +#endif + +static struct folio *alloc_swap_folio(struct vm_fault *vmf) +{ + struct vm_area_struct *vma = vmf->vma; +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + unsigned long orders; + struct folio *folio; + unsigned long addr; + spinlock_t *ptl; + pte_t *pte; + gfp_t gfp; + int order; + + /* + * If uffd is active for the vma we need per-page fault fidelity to + * maintain the uffd semantics. + */ + if (unlikely(userfaultfd_armed(vma))) + goto fallback; + + /* + * a large folio being swapped-in could be partially in + * zswap and partially in swap devices, zswap doesn't + * support large folios yet, we might get corrupted + * zero-filled data by reading all subpages from swap + * devices while some of them are actually in zswap + */ + if (!zswap_never_enabled()) + goto fallback; + + orders = get_alloc_folio_orders(vmf); + if (!orders) + goto fallback; + + pte = pte_offset_map_lock(vmf->vma->vm_mm, vmf->pmd, vmf->address & PMD_MASK, &ptl); + if (unlikely(!pte)) + goto fallback; + + /* + * For do_swap_page, find the highest order where the aligned range is + * completely swap entries with contiguous swap offsets. + */ + order = highest_order(orders); + while (orders) { + addr = ALIGN_DOWN(vmf->address, PAGE_SIZE << order); + if (can_swapin_thp(vmf, pte + pte_index(addr), 1 << order)) + break; + order = next_order(&orders, order); + } + + pte_unmap_unlock(pte, ptl); + + /* Try allocating the highest of the remaining orders. */ + gfp = vma_thp_gfp_mask(vma); + while (orders) { + addr = ALIGN_DOWN(vmf->address, PAGE_SIZE << order); + folio = vma_alloc_folio(gfp, order, vma, addr, true); + if (folio) + return folio; + order = next_order(&orders, order); + } + +fallback: +#endif + return vma_alloc_folio(GFP_HIGHUSER_MOVABLE, 0, vma, vmf->address, false); +} + + /* * We enter with non-exclusive mmap_lock (to exclude vma changes, * but allow concurrent faults), and pte mapped but not yet locked. @@ -4075,35 +4210,38 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) if (!folio) { if (data_race(si->flags & SWP_SYNCHRONOUS_IO) && __swap_count(entry) == 1) { - /* - * Prevent parallel swapin from proceeding with - * the cache flag. Otherwise, another thread may - * finish swapin first, free the entry, and swapout - * reusing the same entry. It's undetectable as - * pte_same() returns true due to entry reuse. - */ - if (swapcache_prepare(entry)) { - /* Relax a bit to prevent rapid repeated page faults */ - schedule_timeout_uninterruptible(1); - goto out; - } - need_clear_cache = true; - /* skip swapcache */ - folio = vma_alloc_folio(GFP_HIGHUSER_MOVABLE, 0, - vma, vmf->address, false); + folio = alloc_swap_folio(vmf); page = &folio->page; if (folio) { __folio_set_locked(folio); __folio_set_swapbacked(folio); + nr_pages = folio_nr_pages(folio); + if (folio_test_large(folio)) + entry.val = ALIGN_DOWN(entry.val, nr_pages); + /* + * Prevent parallel swapin from proceeding with + * the cache flag. Otherwise, another thread may + * finish swapin first, free the entry, and swapout + * reusing the same entry. It's undetectable as + * pte_same() returns true due to entry reuse. + */ + if (swapcache_prepare_nr(entry, nr_pages)) { + /* Relax a bit to prevent rapid repeated page faults */ + schedule_timeout_uninterruptible(1); + goto out_page; + } + need_clear_cache = true; + if (mem_cgroup_swapin_charge_folio(folio, vma->vm_mm, GFP_KERNEL, entry)) { ret = VM_FAULT_OOM; goto out_page; } - mem_cgroup_swapin_uncharge_swap(entry); + for (swp_entry_t e = entry; e.val < entry.val + nr_pages; e.val++) + mem_cgroup_swapin_uncharge_swap(e); shadow = get_shadow_from_swap_cache(entry); if (shadow) @@ -4210,6 +4348,22 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) goto out_nomap; } + /* allocated large folios for SWP_SYNCHRONOUS_IO */ + if (folio_test_large(folio) && !folio_test_swapcache(folio)) { + unsigned long nr = folio_nr_pages(folio); + unsigned long folio_start = ALIGN_DOWN(vmf->address, nr * PAGE_SIZE); + unsigned long idx = (vmf->address - folio_start) / PAGE_SIZE; + pte_t *folio_ptep = vmf->pte - idx; + + if (!can_swapin_thp(vmf, folio_ptep, nr)) + goto out_nomap; + + page_idx = idx; + address = folio_start; + ptep = folio_ptep; + goto check_folio; + } + nr_pages = 1; page_idx = 0; address = vmf->address; @@ -4341,11 +4495,12 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) folio_add_lru_vma(folio, vma); } else if (!folio_test_anon(folio)) { /* - * We currently only expect small !anon folios, which are either - * fully exclusive or fully shared. If we ever get large folios - * here, we have to be careful. + * We currently only expect small !anon folios which are either + * fully exclusive or fully shared, or new allocated large folios + * which are fully exclusive. If we ever get large folios within + * swapcache here, we have to be careful. */ - VM_WARN_ON_ONCE(folio_test_large(folio)); + VM_WARN_ON_ONCE(folio_test_large(folio) && folio_test_swapcache(folio)); VM_WARN_ON_FOLIO(!folio_test_locked(folio), folio); folio_add_new_anon_rmap(folio, vma, address, rmap_flags); } else { @@ -4388,7 +4543,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) out: /* Clear the swap cache pin for direct swapin after PTL unlock */ if (need_clear_cache) - swapcache_clear(si, entry); + swapcache_clear_nr(si, entry, nr_pages); if (si) put_swap_device(si); return ret; @@ -4404,7 +4559,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) folio_put(swapcache); } if (need_clear_cache) - swapcache_clear(si, entry); + swapcache_clear_nr(si, entry, nr_pages); if (si) put_swap_device(si); return ret; @@ -4440,14 +4595,7 @@ static struct folio *alloc_anon_folio(struct vm_fault *vmf) if (unlikely(userfaultfd_armed(vma))) goto fallback; - /* - * Get a list of all the (large) orders below PMD_ORDER that are enabled - * for this vma. Then filter out the orders that can't be allocated over - * the faulting address and still be fully contained in the vma. - */ - orders = thp_vma_allowable_orders(vma, vma->vm_flags, - TVA_IN_PF | TVA_ENFORCE_SYSFS, BIT(PMD_ORDER) - 1); - orders = thp_vma_suitable_orders(vma, vmf->address, orders); + orders = get_alloc_folio_orders(vmf); if (!orders) goto fallback; diff --git a/mm/swap_state.c b/mm/swap_state.c index 994723cef821..7e20de975350 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c @@ -478,7 +478,7 @@ struct folio *__read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask, /* * Swap entry may have been freed since our caller observed it. */ - err = swapcache_prepare(entry); + err = swapcache_prepare_nr(entry, 1); if (!err) break;