Commit 8abddd96 authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman
Browse files

powerpc/64s/radix: Enable huge vmalloc mappings



This reduces TLB misses by nearly 30x on a `git diff` workload on a
2-node POWER9 (59,800 -> 2,100) and reduces CPU cycles by 0.54%, due
to vfs hashes being allocated with 2MB pages.

Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
Reviewed-by: default avatarChristophe Leroy <christophe.leroy@csgroup.eu>
Acked-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210503091755.613393-1-npiggin@gmail.com
parent 562d1e20
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -3251,6 +3251,8 @@

	nohugeiomap	[KNL,X86,PPC,ARM64] Disable kernel huge I/O mappings.

	nohugevmalloc	[PPC] Disable kernel huge vmalloc mappings.

	nosmt		[KNL,S390] Disable symmetric multithreading (SMT).
			Equivalent to smt=1.

+1 −0
Original line number Diff line number Diff line
@@ -185,6 +185,7 @@ config PPC
	select GENERIC_VDSO_TIME_NS
	select HAVE_ARCH_AUDITSYSCALL
	select HAVE_ARCH_HUGE_VMAP		if PPC_BOOK3S_64 && PPC_RADIX_MMU
	select HAVE_ARCH_HUGE_VMALLOC		if HAVE_ARCH_HUGE_VMAP
	select HAVE_ARCH_JUMP_LABEL
	select HAVE_ARCH_JUMP_LABEL_RELATIVE
	select HAVE_ARCH_KASAN			if PPC32 && PPC_PAGE_SHIFT <= 14
+13 −5
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include <linux/moduleloader.h>
#include <linux/err.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/bug.h>
#include <asm/module.h>
#include <linux/uaccess.h>
@@ -88,17 +89,22 @@ int module_finalize(const Elf_Ehdr *hdr,
	return 0;
}

#ifdef MODULES_VADDR
static __always_inline void *
__module_alloc(unsigned long size, unsigned long start, unsigned long end)
{
	return __vmalloc_node_range(size, 1, start, end, GFP_KERNEL,
				    PAGE_KERNEL_EXEC, VM_FLUSH_RESET_PERMS, NUMA_NO_NODE,
				    __builtin_return_address(0));
	/*
	 * Don't do huge page allocations for modules yet until more testing
	 * is done. STRICT_MODULE_RWX may require extra work to support this
	 * too.
	 */
	return __vmalloc_node_range(size, 1, start, end, GFP_KERNEL, PAGE_KERNEL_EXEC,
				    VM_FLUSH_RESET_PERMS | VM_NO_HUGE_VMAP,
				    NUMA_NO_NODE, __builtin_return_address(0));
}

void *module_alloc(unsigned long size)
{
#ifdef MODULES_VADDR
	unsigned long limit = (unsigned long)_etext - SZ_32M;
	void *ptr = NULL;

@@ -112,5 +118,7 @@ void *module_alloc(unsigned long size)
		ptr = __module_alloc(size, MODULES_VADDR, MODULES_END);

	return ptr;
}
#else
	return __module_alloc(size, VMALLOC_START, VMALLOC_END);
#endif
}