Re: [PATCH v2] powerpc/mm: Fix growth direction for hugepages mmaps with slice
From: Aneesh Kumar K.V <hidden>
Date: 2018-01-16 16:11:09
Also in:
lkml
Christophe Leroy [off-list ref] writes:
An application running with libhugetlbfs fails to allocate additional pages to HEAP due to the hugemap being done inconditionally as topdown mapping: mmap(0x10080000, 1572864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x40000, -1, 0) = 0x73e80000 [...] mmap(0x74000000, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x40000, -1, 0x180000) = 0x73d80000 munmap(0x73d80000, 1048576) = 0 [...] mmap(0x74000000, 1572864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x40000, -1, 0x180000) = 0x73d00000 munmap(0x73d00000, 1572864) = 0 [...] mmap(0x74000000, 1572864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x40000, -1, 0x180000) = 0x73d00000 munmap(0x73d00000, 1572864) = 0 [...]
Can you explain the failure details above. I am not sure I understand what to read from the above output.
As one can see from the above strace log, mmap() allocates further pages below the initial one. This patch fixes it by taking into account MAP_GROWSDOWN flag.
Rest of the kernel don't depend on that flag to select a topdown search or not. So what is special with hugetlb? IF we select legacy mmap that is when we select a bottomup search. Hugetlb on ppc64 always did a topdown search.
quoted hunk ↗ jump to hunk
Fixes: d0f13e3c20b6f ("[POWERPC] Introduce address space "slices" ") Signed-off-by: Christophe Leroy <redacted> --- v2: Added missing include arch/powerpc/mm/hugetlbpage.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 79e1378ee303..0eadf9f199de 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c@@ -19,6 +19,7 @@ #include <linux/moduleparam.h> #include <linux/swap.h> #include <linux/swapops.h> +#include <linux/mman.h> #include <asm/pgtable.h> #include <asm/pgalloc.h> #include <asm/tlb.h>@@ -558,7 +559,8 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, return radix__hugetlb_get_unmapped_area(file, addr, len, pgoff, flags); #endif - return slice_get_unmapped_area(addr, len, flags, mmu_psize, 1); + return slice_get_unmapped_area(addr, len, flags, mmu_psize, + flags & MAP_GROWSDOWN); } #endif-- 2.13.3