All of lore.kernel.org
 help / color / mirror / Atom feed
From: James Houghton <jthoughton@google.com>
To: Will Deacon <will@kernel.org>,
	Catalin Marinas <catalin.marinas@arm.com>,
	 Muchun Song <muchun.song@linux.dev>,
	Oscar Salvador <osalvador@suse.de>
Cc: Nikos Nikoleris <nikos.nikoleris@arm.com>,
	Linu Cherian <linu.cherian@arm.com>,
	 Mark Rutland <mark.rutland@arm.com>,
	David Hildenbrand <david@kernel.org>,
	 Andrew Morton <akpm@linux-foundation.org>,
	Ryan Roberts <ryan.roberts@arm.com>,
	 Nanyong Sun <sunnanyong@huawei.com>, Yu Zhao <yuzhao@google.com>,
	 Frank van der Linden <fvdl@google.com>,
	David Rientjes <rientjes@google.com>,
	 James Houghton <jthoughton@google.com>,
	linux-kernel@vger.kernel.org,
	 linux-arm-kernel@lists.infradead.org, linux-mm@kvack.org
Subject: [PATCH 03/18] hugetlb_vmemmap: Leave pages partially HVOed upon restore failure
Date: Wed,  8 Jul 2026 03:11:13 +0000	[thread overview]
Message-ID: <20260708031129.3503195-4-jthoughton@google.com> (raw)
In-Reply-To: <20260708031129.3503195-1-jthoughton@google.com>

Right now it is assumed that the restore routine in vmemmap_remap_free()
will not fail; that is, if we fail to fully optimize a folio, it is
assumed that restoring the folio to its pre-HVO state is guaranteed to
succeed.

Although vmemmap restoration may never fail in practice, properly handle
such failure cases now. This will leave folios in a partially HVOed
state. In a follow-up patch, failure certainly becomes possible.

In the event we end up with partially-HVOed folios, make sure to:
  1. Leave the HVO page flag in place.
  2. Free any unused vmemmap pages.

Always pass the vmemmap_tail page to the restore routine to avoid
leaking the non-optimized vmemmap pages for a partially HVOed page.

Signed-off-by: James Houghton <jthoughton@google.com>
---
 mm/hugetlb_vmemmap.c | 49 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 38 insertions(+), 11 deletions(-)

diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c
index 8d4e8ee51fdd..5fee01bf5b34 100644
--- a/mm/hugetlb_vmemmap.c
+++ b/mm/hugetlb_vmemmap.c
@@ -236,12 +236,15 @@ static void vmemmap_restore_pte(pte_t *pte, unsigned long addr,
 {
 	struct page *src = pte_page(ptep_get(pte)), *dst;
 
+	if (WARN_ON_ONCE(!walk->vmemmap_tail))
+		return;
+
 	/*
-	 * When rolling back vmemmap_remap_free(), keep the copied head page
+	 * When restoring a partially-HVOed page, keep the copied head page
 	 * mapping and restore only PTEs currently pointing at the shared tail
 	 * page.
 	 */
-	if (walk->vmemmap_tail && walk->vmemmap_tail != src)
+	if (walk->vmemmap_tail != src)
 		return;
 
 	VM_WARN_ON_ONCE(PageHead((const struct page *)addr));
@@ -277,6 +280,7 @@ static int vmemmap_remap_split(unsigned long start, unsigned long end)
 	return vmemmap_remap_range(start, end, &walk);
 }
 
+static const int VMEMMAP_REMAP_INCOMPLETE = 1;
 /**
  * vmemmap_remap_free - remap the vmemmap virtual address range [@start, @end)
  *			to use @vmemmap_head/tail, then free vmemmap which
@@ -291,7 +295,8 @@ static int vmemmap_remap_split(unsigned long start, unsigned long end)
  *		responsibility to free pages.
  * @flags:	modifications to vmemmap_remap_walk flags
  *
- * Return: %0 on success, negative error code otherwise.
+ * Return: %0 on success, VMEMMAP_REMAP_INCOMPLETE if the page is incompletely
+ *         optimized, negative error code otherwise.
  */
 static int vmemmap_remap_free(unsigned long start, unsigned long end,
 			      struct page *vmemmap_head,
@@ -326,7 +331,8 @@ static int vmemmap_remap_free(unsigned long start, unsigned long end,
 		.flags		= 0,
 	};
 
-	vmemmap_remap_range(start, end, &walk);
+	if (vmemmap_remap_range(start, end, &walk))
+		return VMEMMAP_REMAP_INCOMPLETE;
 
 	return ret;
 }
@@ -385,6 +391,8 @@ static struct page *vmemmap_get_tail(unsigned int order, struct zone *zone)
  * vmemmap_remap_alloc - remap the vmemmap virtual address range [@start, end)
  *			 to the page which is from the @vmemmap_pages
  *			 respectively.
+ * @h:		the hstate for the folio whose vmemmap is getting remapped
+ * @folio:	the folio whose vmemmap is getting remapped
  * @start:	start address of the vmemmap virtual address range that we want
  *		to remap.
  * @end:	end address of the vmemmap virtual address range that we want to
@@ -393,20 +401,35 @@ static struct page *vmemmap_get_tail(unsigned int order, struct zone *zone)
  *
  * Return: %0 on success, negative error code otherwise.
  */
-static int vmemmap_remap_alloc(unsigned long start, unsigned long end,
+static int vmemmap_remap_alloc(const struct hstate *h, struct folio *folio,
+			       unsigned long start, unsigned long end,
 			       unsigned long flags)
 {
 	LIST_HEAD(vmemmap_pages);
-	struct vmemmap_remap_walk walk = {
+	struct vmemmap_remap_walk walk;
+	struct page *vmemmap_tail;
+	int ret;
+
+	vmemmap_tail = vmemmap_get_tail(h->order, folio_zone(folio));
+	if (WARN_ON_ONCE(!vmemmap_tail))
+		return -ENOMEM;
+
+	if (alloc_vmemmap_page_list(start, end, &vmemmap_pages))
+		return -ENOMEM;
+
+	walk = (struct vmemmap_remap_walk) {
 		.remap_pte	= vmemmap_restore_pte,
+		.vmemmap_tail	= vmemmap_tail,
 		.vmemmap_pages	= &vmemmap_pages,
 		.flags		= flags,
 	};
 
-	if (alloc_vmemmap_page_list(start, end, &vmemmap_pages))
-		return -ENOMEM;
+	ret = vmemmap_remap_range(start, end, &walk);
 
-	return vmemmap_remap_range(start, end, &walk);
+	/* Not all pages may have been consumed */
+	free_vmemmap_page_list(&vmemmap_pages);
+
+	return ret;
 }
 
 static bool vmemmap_optimize_enabled = IS_ENABLED(CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON);
@@ -439,7 +462,7 @@ static int __hugetlb_vmemmap_restore_folio(const struct hstate *h,
 	 * When a HugeTLB page is freed to the buddy allocator, previously
 	 * discarded vmemmap pages must be allocated and remapping.
 	 */
-	ret = vmemmap_remap_alloc(vmemmap_start, vmemmap_end, flags);
+	ret = vmemmap_remap_alloc(h, folio, vmemmap_start, vmemmap_end, flags);
 	if (!ret)
 		folio_clear_hugetlb_vmemmap_optimized(folio);
 
@@ -572,7 +595,11 @@ static int __hugetlb_vmemmap_optimize_folio(const struct hstate *h,
 				 vmemmap_head, vmemmap_tail,
 				 vmemmap_pages, flags);
 out:
-	if (ret)
+	/*
+	 * If ret == VMEMMAP_REMAP_INCOMPLETE, the folio might be partially
+	 * HVOed. Leave the HVO page folio flag in place.
+	 */
+	if (ret < 0)
 		folio_clear_hugetlb_vmemmap_optimized(folio);
 
 	return ret;
-- 
2.55.0.795.g602f6c329a-goog



  parent reply	other threads:[~2026-07-08  3:11 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-08  3:11 [PATCH 00/18] Another attempt at HVO support on arm64 James Houghton
2026-07-08  3:11 ` [PATCH 01/18] hugetlb_vmemmap: Always flush TLB if needed upon PTE remapping James Houghton
2026-07-08  3:11 ` [PATCH 02/18] hugetlb_vmemmap: Move vmemmap_get_tail up James Houghton
2026-07-08  3:11 ` James Houghton [this message]
2026-08-18 14:07   ` [PATCH 03/18] hugetlb_vmemmap: Leave pages partially HVOed upon restore failure Catalin Marinas
2026-07-08  3:11 ` [PATCH 04/18] hugetlb_vmemmap: Use try_update_vmemmap_pte to update in-use PTEs James Houghton
2026-07-08  3:11 ` [PATCH 05/18] hugetlb_vmemmap: Allow architectures not to allow HVO at runtime James Houghton
2026-07-08  3:11 ` [PATCH 06/18] arm64: Rename cpu_has_hw_af to system_has_hw_af James Houghton
2026-07-08  3:11 ` [PATCH 07/18] arm64: Add system_supports_hvo James Houghton
2026-08-18 14:07   ` Catalin Marinas
2026-07-08  3:11 ` [PATCH 08/18] arm64: Implement try_update_vmemmap_pte using the AF trick James Houghton
2026-08-18 14:10   ` Catalin Marinas
2026-07-08  3:11 ` [PATCH 09/18] arm64: Prevent HVO if the HVO system feature is not enabled James Houghton
2026-07-08  3:11 ` [PATCH 10/18] arm64: Support hugetlb vmemmap optimization James Houghton
2026-08-18 14:16   ` Catalin Marinas
2026-07-08  3:11 ` [PATCH 11/18] hugetlb_vmemmap: Use try_populate_vmemmap_pmd for replacing in-use PMDs James Houghton
2026-08-18 15:53   ` Catalin Marinas
2026-07-08  3:11 ` [PATCH 12/18] arm64: Implement try_populate_vmemmap_pmd using AF trick James Houghton
2026-08-18 16:33   ` Catalin Marinas
2026-07-08  3:11 ` [PATCH 13/18] arm64: Drop BBML2_NOABORT requirement for HVO James Houghton
2026-07-08  3:11 ` [PATCH 14/18] hugetlb_vmemmap: Rename mm/hugetlb_vmemmap.h to mm/hugetlb_vmemmap_internal.h James Houghton
2026-07-08  3:11 ` [PATCH 15/18] hugetlb_vmemmap: Add a way to permanently disable HVO when needed James Houghton
2026-07-08  3:11 ` [PATCH 16/18] arm64: Allow "optional" CPU features to be required sometimes James Houghton
2026-07-08  3:11 ` [PATCH 17/18] arm64: Permit onlining of HVO-incompatible late CPUs if HVO is not in use James Houghton
2026-07-08  3:11 ` [PATCH 18/18] arm64: Remove user-selectable HVO Kconfig James Houghton
2026-07-08  8:40 ` [PATCH 00/18] Another attempt at HVO support on arm64 Muchun Song
2026-07-08 16:49   ` James Houghton
2026-07-09  9:54     ` Muchun Song
2026-07-09 19:04       ` James Houghton
2026-07-10  3:40         ` Muchun Song
2026-07-13  4:09           ` James Houghton
2026-07-14  6:40             ` Muchun Song
2026-07-11  2:22         ` Muchun Song
2026-07-13  4:09           ` James Houghton
2026-07-09  9:58 ` David Hildenbrand (Arm)
2026-07-10  4:58 ` Muchun Song
2026-07-13  4:59   ` James Houghton
2026-07-13  7:41     ` Muchun Song
2026-07-13 11:26       ` Dev Jain
2026-07-14  8:46 ` Pedro Falcato
2026-07-15  9:38   ` James Houghton
2026-08-17 17:34 ` Catalin Marinas

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=20260708031129.3503195-4-jthoughton@google.com \
    --to=jthoughton@google.com \
    --cc=akpm@linux-foundation.org \
    --cc=catalin.marinas@arm.com \
    --cc=david@kernel.org \
    --cc=fvdl@google.com \
    --cc=linu.cherian@arm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mark.rutland@arm.com \
    --cc=muchun.song@linux.dev \
    --cc=nikos.nikoleris@arm.com \
    --cc=osalvador@suse.de \
    --cc=rientjes@google.com \
    --cc=ryan.roberts@arm.com \
    --cc=sunnanyong@huawei.com \
    --cc=will@kernel.org \
    --cc=yuzhao@google.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.