From: "Björn Töpel" <bjorn@kernel.org>
To: Paul Walmsley <paul.walmsley@sifive.com>,
Palmer Dabbelt <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
linux-riscv@lists.infradead.org
Cc: "Björn Töpel" <bjorn@rivosinc.com>,
linux-kernel@vger.kernel.org, linux-mm@kvack.org,
"David Hildenbrand" <david@redhat.com>,
"Oscar Salvador" <osalvador@suse.de>,
virtualization@lists.linux-foundation.org, linux@rivosinc.com,
"Alexandre Ghiti" <alexghiti@rivosinc.com>
Subject: [PATCH 1/7] riscv: mm: Pre-allocate PGD leaves to avoid synchronization
Date: Fri, 12 May 2023 16:57:31 +0200 [thread overview]
Message-ID: <20230512145737.985671-2-bjorn@kernel.org> (raw)
In-Reply-To: <20230512145737.985671-1-bjorn@kernel.org>
From: Björn Töpel <bjorn@rivosinc.com>
The RISC-V port copies PGD from init_mm to all userland pages-tables,
which means that when the PGD level of the init_mm table is changed,
other page-tables has to be updated.
One way to avoid synchronizing page-tables is to pre-allocate the
pages that are copied (need to be synchronized). For memory
hotswapping builds, prefer to waste some pages, rather than do
explicit synchronization.
Prepare the RISC-V port for memory add/remove, by getting rid of PGD
synchronization. Pre-allocate vmemmap, and direct map pages. This will
roughly waste ~128 worth of 4K pages.
Note that this is only done for memory hotswap enabled configuration.
Signed-off-by: Björn Töpel <bjorn@rivosinc.com>
---
arch/riscv/include/asm/kasan.h | 4 +-
arch/riscv/mm/init.c | 86 ++++++++++++++++++++++++++++++++++
2 files changed, 88 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/include/asm/kasan.h b/arch/riscv/include/asm/kasan.h
index 0b85e363e778..e6a0071bdb56 100644
--- a/arch/riscv/include/asm/kasan.h
+++ b/arch/riscv/include/asm/kasan.h
@@ -6,8 +6,6 @@
#ifndef __ASSEMBLY__
-#ifdef CONFIG_KASAN
-
/*
* The following comment was copied from arm64:
* KASAN_SHADOW_START: beginning of the kernel virtual addresses.
@@ -34,6 +32,8 @@
*/
#define KASAN_SHADOW_START ((KASAN_SHADOW_END - KASAN_SHADOW_SIZE) & PGDIR_MASK)
#define KASAN_SHADOW_END MODULES_LOWEST_VADDR
+
+#ifdef CONFIG_KASAN
#define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
void kasan_init(void);
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 747e5b1ef02d..d2595cc33a1c 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -31,6 +31,7 @@
#include <asm/io.h>
#include <asm/ptdump.h>
#include <asm/numa.h>
+#include <asm/kasan.h>
#include "../kernel/head.h"
@@ -156,6 +157,90 @@ static void __init print_vm_layout(void)
static void print_vm_layout(void) { }
#endif /* CONFIG_DEBUG_VM */
+#ifdef CONFIG_MEMORY_HOTPLUG
+/*
+ * Pre-allocates page-table pages for a specific area in the kernel
+ * page-table. Only the level which needs to be synchronized between
+ * all page-tables is allocated because the synchronization can be
+ * expensive.
+ */
+static void __init preallocate_pgd_pages_range(unsigned long start, unsigned long end,
+ const char *area)
+{
+ unsigned long addr;
+ const char *lvl;
+
+ for (addr = start; addr < end; addr = ALIGN(addr + 1, PGDIR_SIZE)) {
+ pgd_t *pgd = pgd_offset_k(addr);
+ p4d_t *p4d;
+ pud_t *pud;
+ pmd_t *pmd;
+
+ lvl = "p4d";
+ p4d = p4d_alloc(&init_mm, pgd, addr);
+ if (!p4d)
+ goto failed;
+
+ if (pgtable_l5_enabled)
+ continue;
+
+ /*
+ * The goal here is to allocate all possibly required
+ * hardware page tables pointed to by the top hardware
+ * level.
+ *
+ * On 4-level systems, the P4D layer is folded away
+ * and the above code does no preallocation. Below,
+ * go down to the pud _software_ level to ensure the
+ * second hardware level is allocated on 4-level
+ * systems too.
+ */
+ lvl = "pud";
+ pud = pud_alloc(&init_mm, p4d, addr);
+ if (!pud)
+ goto failed;
+
+ if (pgtable_l4_enabled)
+ continue;
+ /*
+ * The goal here is to allocate all possibly required
+ * hardware page tables pointed to by the top hardware
+ * level.
+ *
+ * On 3-level systems, the PUD layer is folded away
+ * and the above code does no preallocation. Below,
+ * go down to the pmd _software_ level to ensure the
+ * second hardware level is allocated on 3-level
+ * systems too.
+ */
+ lvl = "pmd";
+ pmd = pmd_alloc(&init_mm, pud, addr);
+ if (!pmd)
+ goto failed;
+ }
+
+ return;
+
+failed:
+
+ /*
+ * The pages have to be there now or they will be missing in
+ * process page-tables later.
+ */
+ panic("Failed to pre-allocate %s pages for %s area\n", lvl, area);
+}
+
+#define PAGE_END KASAN_SHADOW_START
+#endif
+
+static void __init prepare_memory_hotplug(void)
+{
+#ifdef CONFIG_MEMORY_HOTPLUG
+ preallocate_pgd_pages_range(VMEMMAP_START, VMEMMAP_END, "vmemmap");
+ preallocate_pgd_pages_range(PAGE_OFFSET, PAGE_END, "direct map");
+#endif
+}
+
void __init mem_init(void)
{
#ifdef CONFIG_FLATMEM
@@ -164,6 +249,7 @@ void __init mem_init(void)
swiotlb_init(max_pfn > PFN_DOWN(dma32_phys_limit), SWIOTLB_VERBOSE);
memblock_free_all();
+ prepare_memory_hotplug();
print_vm_layout();
}
--
2.39.2
next prev parent reply other threads:[~2023-05-12 14:58 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-12 14:57 [PATCH 0/7] riscv: Memory Hot(Un)Plug support Björn Töpel
2023-05-12 14:57 ` Björn Töpel [this message]
2023-05-12 14:57 ` [PATCH 2/7] riscv: mm: Change attribute from __init to __meminit for page functions Björn Töpel
2023-05-12 14:57 ` [PATCH 3/7] riscv: mm: Refactor create_linear_mapping_range() for hot add Björn Töpel
2023-06-21 23:56 ` Palmer Dabbelt
2023-06-22 4:56 ` Björn Töpel
2023-05-12 14:57 ` [PATCH 4/7] riscv: mm: Add memory hot add/remove support Björn Töpel
2023-05-12 14:57 ` [PATCH 5/7] riscv: Enable memory hot add/remove arch kbuild support Björn Töpel
2023-05-12 14:57 ` [PATCH 6/7] virtio-mem: Enable virtio-mem for RISC-V Björn Töpel
2023-05-12 14:57 ` [PATCH 7/7] riscv: mm: Pre-allocate vmalloc PGD leaves Björn Töpel
2023-05-17 13:49 ` [PATCH 0/7] riscv: Memory Hot(Un)Plug support David Hildenbrand
2023-05-17 18:53 ` Björn Töpel
2023-05-21 9:15 ` Björn Töpel
2023-05-22 8:21 ` David Hildenbrand
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=20230512145737.985671-2-bjorn@kernel.org \
--to=bjorn@kernel.org \
--cc=alexghiti@rivosinc.com \
--cc=aou@eecs.berkeley.edu \
--cc=bjorn@rivosinc.com \
--cc=david@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-riscv@lists.infradead.org \
--cc=linux@rivosinc.com \
--cc=osalvador@suse.de \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=virtualization@lists.linux-foundation.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).