* [PATCH v2 0/9] Unify hugetlb into arch_get_unmapped_area functions
@ 2024-07-29 9:10 Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 1/9] mm/mmap: Teach generic_get_unmapped_area{_topdown} to handle hugetlb mappings Oscar Salvador
` (8 more replies)
0 siblings, 9 replies; 22+ messages in thread
From: Oscar Salvador @ 2024-07-29 9:10 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, linux-mm, Peter Xu, Muchun Song, David Hildenbrand,
Donet Tom, Matthew Wilcox, Vlastimil Babka, Michal Hocko,
Oscar Salvador
rfc -> v1: Fix s390 compilation errors
Tested on s390
v1 -> v2: Rebased on top of mm-unstable
Fix sparc64 compilation errors
This is an attempt to get rid of a fair amount of duplicated code
wrt. hugetlb and *get_unmapped_area* functions.
HugeTLB registers a .get_unmapped_area function which gets called from
__get_unmapped_area().
hugetlb_get_unmapped_area() is defined by a bunch of architectures and
it also has a generic definition for those that do not define it.
Short-long story is that there is a ton of duplicated code between
specific hugetlb *_get_unmapped_area_* functions and mm-core functions,
so we can do better by teaching arch_get_unmapped_area* functions how
to deal with hugetlb mappings.
Note that not a lot of things need to be taught though.
hugetlb_mmap_check_and_align(), that gets called for hugetlb mappings
prior to call mm_get_unmapped_area_vmflags(), runs some sanity checks
and aligns the addr to huge_page_size(), so we do not need to that
down the road in the respective {generic,arch}_get_unmapped_area*
functions.
More information can be found in the respective patches.
LTP mmapstress and hugemmap testcases were ran succesfully on:
- arm64
- powerpc64
- s390
- x86_64
Oscar Salvador (9):
mm/mmap: Teach generic_get_unmapped_area{_topdown} to handle hugetlb
mappings
arch/s390: Teach arch_get_unmapped_area{_topdown} to handle hugetlb
mappings
arch/x86: Teach arch_get_unmapped_area_vmflags to handle hugetlb
mappings
arch/sparc: Teach arch_get_unmapped_area{_topdown} to handle hugetlb
mappings
arch/powerpc: Teach book3s64 arch_get_unmapped_area{_topdown} to
handle hugetlb mappings
mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags
mm: Drop hugetlb_get_unmapped_area{_*} functions
arch/s390: Clean up hugetlb definitions
mm: Consolidate common checks in hugetlb_mmap_check_and_align
arch/loongarch/include/asm/hugetlb.h | 4 -
arch/mips/include/asm/hugetlb.h | 4 -
arch/parisc/include/asm/hugetlb.h | 15 ----
arch/parisc/mm/hugetlbpage.c | 21 ------
arch/powerpc/mm/book3s64/slice.c | 49 +++++++-----
arch/s390/include/asm/hugetlb.h | 73 ++++--------------
arch/s390/mm/hugetlbpage.c | 85 ---------------------
arch/s390/mm/mmap.c | 9 ++-
arch/sh/include/asm/hugetlb.h | 15 ----
arch/sparc/kernel/sys_sparc_32.c | 17 ++++-
arch/sparc/kernel/sys_sparc_64.c | 37 +++++++--
arch/sparc/mm/hugetlbpage.c | 108 ---------------------------
arch/x86/kernel/sys_x86_64.c | 24 ++++--
arch/x86/mm/hugetlbpage.c | 101 -------------------------
fs/hugetlbfs/inode.c | 97 ++----------------------
include/asm-generic/hugetlb.h | 15 ++--
include/linux/hugetlb.h | 22 +++---
mm/mmap.c | 19 ++++-
18 files changed, 156 insertions(+), 559 deletions(-)
--
2.45.2
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 1/9] mm/mmap: Teach generic_get_unmapped_area{_topdown} to handle hugetlb mappings
2024-07-29 9:10 [PATCH v2 0/9] Unify hugetlb into arch_get_unmapped_area functions Oscar Salvador
@ 2024-07-29 9:10 ` Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 2/9] arch/s390: Teach arch_get_unmapped_area{_topdown} " Oscar Salvador
` (7 subsequent siblings)
8 siblings, 0 replies; 22+ messages in thread
From: Oscar Salvador @ 2024-07-29 9:10 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, linux-mm, Peter Xu, Muchun Song, David Hildenbrand,
Donet Tom, Matthew Wilcox, Vlastimil Babka, Michal Hocko,
Oscar Salvador
We want to stop special casing hugetlb mappings and make them go
through generic channels, so teach generic_get_unmapped_area{_topdown}
to handle those.
The main difference is that we set info.align_mask for huge mappings.
Signed-off-by: Oscar Salvador <osalvador@suse.de>
---
include/linux/hugetlb.h | 10 ++++++++++
mm/mmap.c | 4 ++++
2 files changed, 14 insertions(+)
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index c9bf68c239a0..0ec14e5e0890 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -1007,9 +1007,19 @@ void hugetlb_unregister_node(struct node *node);
*/
bool is_raw_hwpoison_page_in_hugepage(struct page *page);
+static inline unsigned long huge_page_mask_align(struct file *file)
+{
+ return PAGE_MASK & ~huge_page_mask(hstate_file(file));
+}
+
#else /* CONFIG_HUGETLB_PAGE */
struct hstate {};
+static inline unsigned long huge_page_mask_align(struct file *file)
+{
+ return 0;
+}
+
static inline struct hugepage_subpool *hugetlb_folio_subpool(struct folio *folio)
{
return NULL;
diff --git a/mm/mmap.c b/mm/mmap.c
index b74d2967cfc0..7b623811d82a 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -732,6 +732,8 @@ generic_get_unmapped_area(struct file *filp, unsigned long addr,
info.length = len;
info.low_limit = mm->mmap_base;
info.high_limit = mmap_end;
+ if (filp && is_file_hugepages(filp))
+ info.align_mask = huge_page_mask_align(filp);
return vm_unmapped_area(&info);
}
@@ -780,6 +782,8 @@ generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
info.length = len;
info.low_limit = PAGE_SIZE;
info.high_limit = arch_get_mmap_base(addr, mm->mmap_base);
+ if (filp && is_file_hugepages(filp))
+ info.align_mask = huge_page_mask_align(filp);
addr = vm_unmapped_area(&info);
/*
--
2.45.2
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 2/9] arch/s390: Teach arch_get_unmapped_area{_topdown} to handle hugetlb mappings
2024-07-29 9:10 [PATCH v2 0/9] Unify hugetlb into arch_get_unmapped_area functions Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 1/9] mm/mmap: Teach generic_get_unmapped_area{_topdown} to handle hugetlb mappings Oscar Salvador
@ 2024-07-29 9:10 ` Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 3/9] arch/x86: Teach arch_get_unmapped_area_vmflags " Oscar Salvador
` (6 subsequent siblings)
8 siblings, 0 replies; 22+ messages in thread
From: Oscar Salvador @ 2024-07-29 9:10 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, linux-mm, Peter Xu, Muchun Song, David Hildenbrand,
Donet Tom, Matthew Wilcox, Vlastimil Babka, Michal Hocko,
Oscar Salvador
We want to stop special casing hugetlb mappings and make them go
through generic channels, so teach arch_get_unmapped_area{_topdown}
to handle those.
s390 specific hugetlb function does not set info.align_offset, so do
the same here for compability.
Signed-off-by: Oscar Salvador <osalvador@suse.de>
---
arch/s390/mm/mmap.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
index 206756946589..408b5a541a28 100644
--- a/arch/s390/mm/mmap.c
+++ b/arch/s390/mm/mmap.c
@@ -17,6 +17,7 @@
#include <linux/random.h>
#include <linux/compat.h>
#include <linux/security.h>
+#include <linux/hugetlb.h>
#include <asm/elf.h>
static unsigned long stack_maxrandom_size(void)
@@ -73,6 +74,8 @@ static inline unsigned long mmap_base(unsigned long rnd,
static int get_align_mask(struct file *filp, unsigned long flags)
{
+ if (filp && is_file_hugepages(filp))
+ return huge_page_mask_align(filp);
if (!(current->flags & PF_RANDOMIZE))
return 0;
if (filp || (flags & MAP_SHARED))
@@ -106,7 +109,8 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
info.low_limit = mm->mmap_base;
info.high_limit = TASK_SIZE;
info.align_mask = get_align_mask(filp, flags);
- info.align_offset = pgoff << PAGE_SHIFT;
+ if (!(filp && is_file_hugepages(filp)))
+ info.align_offset = pgoff << PAGE_SHIFT;
addr = vm_unmapped_area(&info);
if (offset_in_page(addr))
return addr;
@@ -144,7 +148,8 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long ad
info.low_limit = PAGE_SIZE;
info.high_limit = mm->mmap_base;
info.align_mask = get_align_mask(filp, flags);
- info.align_offset = pgoff << PAGE_SHIFT;
+ if (!(filp && is_file_hugepages(filp)))
+ info.align_offset = pgoff << PAGE_SHIFT;
addr = vm_unmapped_area(&info);
/*
--
2.45.2
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 3/9] arch/x86: Teach arch_get_unmapped_area_vmflags to handle hugetlb mappings
2024-07-29 9:10 [PATCH v2 0/9] Unify hugetlb into arch_get_unmapped_area functions Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 1/9] mm/mmap: Teach generic_get_unmapped_area{_topdown} to handle hugetlb mappings Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 2/9] arch/s390: Teach arch_get_unmapped_area{_topdown} " Oscar Salvador
@ 2024-07-29 9:10 ` Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 4/9] arch/sparc: Teach arch_get_unmapped_area{_topdown} " Oscar Salvador
` (5 subsequent siblings)
8 siblings, 0 replies; 22+ messages in thread
From: Oscar Salvador @ 2024-07-29 9:10 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, linux-mm, Peter Xu, Muchun Song, David Hildenbrand,
Donet Tom, Matthew Wilcox, Vlastimil Babka, Michal Hocko,
Oscar Salvador
We want to stop special casing hugetlb mappings and make them go
through generic channels, so teach arch_get_unmapped_area_{topdown_}vmflags
to handle those.
x86 specific hugetlb function does not set either info.start_gap or
info.align_offset so the same here for compability.
Signed-off-by: Oscar Salvador <osalvador@suse.de>
---
arch/x86/kernel/sys_x86_64.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index 01d7cd85ef97..aa7491f036a7 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -18,6 +18,7 @@
#include <linux/random.h>
#include <linux/uaccess.h>
#include <linux/elf.h>
+#include <linux/hugetlb.h>
#include <asm/elf.h>
#include <asm/ia32.h>
@@ -25,8 +26,10 @@
/*
* Align a virtual address to avoid aliasing in the I$ on AMD F15h.
*/
-static unsigned long get_align_mask(void)
+static unsigned long get_align_mask(struct file *filp)
{
+ if (filp && is_file_hugepages(filp))
+ return huge_page_mask_align(filp);
/* handle 32- and 64-bit case with a single conditional */
if (va_align.flags < 0 || !(va_align.flags & (2 - mmap_is_ia32())))
return 0;
@@ -49,7 +52,7 @@ static unsigned long get_align_mask(void)
*/
static unsigned long get_align_bits(void)
{
- return va_align.bits & get_align_mask();
+ return va_align.bits & get_align_mask(NULL);
}
static int __init control_va_addr_alignment(char *str)
@@ -148,12 +151,15 @@ arch_get_unmapped_area_vmflags(struct file *filp, unsigned long addr, unsigned l
info.length = len;
info.low_limit = begin;
info.high_limit = end;
- info.align_offset = pgoff << PAGE_SHIFT;
- info.start_gap = stack_guard_placement(vm_flags);
+ if (!(filp && is_file_hugepages(filp))) {
+ info.align_offset = pgoff << PAGE_SHIFT;
+ info.start_gap = stack_guard_placement(vm_flags);
+ }
if (filp) {
- info.align_mask = get_align_mask();
+ info.align_mask = get_align_mask(filp);
info.align_offset += get_align_bits();
}
+
return vm_unmapped_area(&info);
}
@@ -199,7 +205,10 @@ arch_get_unmapped_area_topdown_vmflags(struct file *filp, unsigned long addr0,
info.low_limit = PAGE_SIZE;
info.high_limit = get_mmap_base(0);
- info.start_gap = stack_guard_placement(vm_flags);
+ if (!(filp && is_file_hugepages(filp))) {
+ info.start_gap = stack_guard_placement(vm_flags);
+ info.align_offset = pgoff << PAGE_SHIFT;
+ }
/*
* If hint address is above DEFAULT_MAP_WINDOW, look for unmapped area
@@ -211,9 +220,8 @@ arch_get_unmapped_area_topdown_vmflags(struct file *filp, unsigned long addr0,
if (addr > DEFAULT_MAP_WINDOW && !in_32bit_syscall())
info.high_limit += TASK_SIZE_MAX - DEFAULT_MAP_WINDOW;
- info.align_offset = pgoff << PAGE_SHIFT;
if (filp) {
- info.align_mask = get_align_mask();
+ info.align_mask = get_align_mask(filp);
info.align_offset += get_align_bits();
}
addr = vm_unmapped_area(&info);
--
2.45.2
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 4/9] arch/sparc: Teach arch_get_unmapped_area{_topdown} to handle hugetlb mappings
2024-07-29 9:10 [PATCH v2 0/9] Unify hugetlb into arch_get_unmapped_area functions Oscar Salvador
` (2 preceding siblings ...)
2024-07-29 9:10 ` [PATCH v2 3/9] arch/x86: Teach arch_get_unmapped_area_vmflags " Oscar Salvador
@ 2024-07-29 9:10 ` Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 5/9] arch/powerpc: Teach book3s64 " Oscar Salvador
` (4 subsequent siblings)
8 siblings, 0 replies; 22+ messages in thread
From: Oscar Salvador @ 2024-07-29 9:10 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, linux-mm, Peter Xu, Muchun Song, David Hildenbrand,
Donet Tom, Matthew Wilcox, Vlastimil Babka, Michal Hocko,
Oscar Salvador
We want to stop special casing hugetlb mappings and make them go
through generic channels, so teach arch_get_unmapped_area{_topdown}
to handle those.
sparc specific hugetlb function does not set info.align_offset, and
does not care about adjusting the align_mask for MAP_SHARED cases,
so the same here for compability.
Signed-off-by: Oscar Salvador <osalvador@suse.de>
---
arch/sparc/kernel/sys_sparc_32.c | 17 +++++++++++----
arch/sparc/kernel/sys_sparc_64.c | 37 +++++++++++++++++++++++++-------
2 files changed, 42 insertions(+), 12 deletions(-)
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c
index 08a19727795c..852b340a7f9b 100644
--- a/arch/sparc/kernel/sys_sparc_32.c
+++ b/arch/sparc/kernel/sys_sparc_32.c
@@ -23,6 +23,7 @@
#include <linux/utsname.h>
#include <linux/smp.h>
#include <linux/ipc.h>
+#include <linux/hugetlb.h>
#include <linux/uaccess.h>
#include <asm/unistd.h>
@@ -42,12 +43,16 @@ SYSCALL_DEFINE0(getpagesize)
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
{
struct vm_unmapped_area_info info = {};
+ bool file_hugepage = false;
+
+ if (filp && is_file_hugepages(filp))
+ file_hugepage = true;
if (flags & MAP_FIXED) {
/* We do not accept a shared mapping if it would violate
* cache aliasing constraints.
*/
- if ((flags & MAP_SHARED) &&
+ if (!file_hugepage && (flags & MAP_SHARED) &&
((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
return -EINVAL;
return addr;
@@ -62,9 +67,13 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
info.length = len;
info.low_limit = addr;
info.high_limit = TASK_SIZE;
- info.align_mask = (flags & MAP_SHARED) ?
- (PAGE_MASK & (SHMLBA - 1)) : 0;
- info.align_offset = pgoff << PAGE_SHIFT;
+ if (!file_hugepage) {
+ info.align_mask = (flags & MAP_SHARED) ?
+ (PAGE_MASK & (SHMLBA - 1)) : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
+ } else {
+ info.align_mask = huge_page_mask_align(filp);
+ }
return vm_unmapped_area(&info);
}
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index d9c3b34ca744..1b271db41542 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -30,6 +30,7 @@
#include <linux/context_tracking.h>
#include <linux/timex.h>
#include <linux/uaccess.h>
+#include <linux/hugetlb.h>
#include <asm/utrap.h>
#include <asm/unistd.h>
@@ -87,6 +88,16 @@ static inline unsigned long COLOR_ALIGN(unsigned long addr,
return base + off;
}
+static unsigned long get_align_mask(struct file *filp, unsigned long flags)
+{
+ if (filp && is_file_hugepages(filp))
+ return huge_page_mask_align(filp);
+ if (filp || (flags & MAP_SHARED))
+ return PAGE_MASK & (SHMLBA - 1);
+
+ return 0;
+}
+
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
{
struct mm_struct *mm = current->mm;
@@ -94,12 +105,16 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
unsigned long task_size = TASK_SIZE;
int do_color_align;
struct vm_unmapped_area_info info = {};
+ bool file_hugepage = false;
+
+ if (filp && is_file_hugepages(filp))
+ file_hugepage = true;
if (flags & MAP_FIXED) {
/* We do not accept a shared mapping if it would violate
* cache aliasing constraints.
*/
- if ((flags & MAP_SHARED) &&
+ if (!file_hugepage && (flags & MAP_SHARED) &&
((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
return -EINVAL;
return addr;
@@ -111,7 +126,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
return -ENOMEM;
do_color_align = 0;
- if (filp || (flags & MAP_SHARED))
+ if ((filp || (flags & MAP_SHARED)) && !file_hugepage)
do_color_align = 1;
if (addr) {
@@ -129,8 +144,9 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
info.length = len;
info.low_limit = TASK_UNMAPPED_BASE;
info.high_limit = min(task_size, VA_EXCLUDE_START);
- info.align_mask = do_color_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
- info.align_offset = pgoff << PAGE_SHIFT;
+ info.align_mask = get_align_mask(filp, flags);
+ if (!file_hugepage)
+ info.align_offset = pgoff << PAGE_SHIFT;
addr = vm_unmapped_area(&info);
if ((addr & ~PAGE_MASK) && task_size > VA_EXCLUDE_END) {
@@ -154,15 +170,19 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
unsigned long addr = addr0;
int do_color_align;
struct vm_unmapped_area_info info = {};
+ bool file_hugepage = false;
/* This should only ever run for 32-bit processes. */
BUG_ON(!test_thread_flag(TIF_32BIT));
+ if (filp && is_file_hugepages(filp))
+ file_hugepage = true;
+
if (flags & MAP_FIXED) {
/* We do not accept a shared mapping if it would violate
* cache aliasing constraints.
*/
- if ((flags & MAP_SHARED) &&
+ if (!file_hugepage && (flags & MAP_SHARED) &&
((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
return -EINVAL;
return addr;
@@ -172,7 +192,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
return -ENOMEM;
do_color_align = 0;
- if (filp || (flags & MAP_SHARED))
+ if ((filp || (flags & MAP_SHARED)) && !file_hugepage)
do_color_align = 1;
/* requesting a specific address */
@@ -192,8 +212,9 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
info.length = len;
info.low_limit = PAGE_SIZE;
info.high_limit = mm->mmap_base;
- info.align_mask = do_color_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
- info.align_offset = pgoff << PAGE_SHIFT;
+ info.align_mask = get_align_mask(filp, flags);
+ if (!file_hugepage)
+ info.align_offset = pgoff << PAGE_SHIFT;
addr = vm_unmapped_area(&info);
/*
--
2.45.2
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 5/9] arch/powerpc: Teach book3s64 arch_get_unmapped_area{_topdown} to handle hugetlb mappings
2024-07-29 9:10 [PATCH v2 0/9] Unify hugetlb into arch_get_unmapped_area functions Oscar Salvador
` (3 preceding siblings ...)
2024-07-29 9:10 ` [PATCH v2 4/9] arch/sparc: Teach arch_get_unmapped_area{_topdown} " Oscar Salvador
@ 2024-07-29 9:10 ` Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags Oscar Salvador
` (3 subsequent siblings)
8 siblings, 0 replies; 22+ messages in thread
From: Oscar Salvador @ 2024-07-29 9:10 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, linux-mm, Peter Xu, Muchun Song, David Hildenbrand,
Donet Tom, Matthew Wilcox, Vlastimil Babka, Michal Hocko,
Oscar Salvador
We want to stop special casing hugetlb mappings and make them go
through generic channels, so teach arch_get_unmapped_area{_topdown}
to handle those.
Reshuffle file_to_psize() definition so arch_get_unmapped_area{_topdown}
can make use of it.
Signed-off-by: Oscar Salvador <osalvador@suse.de>
---
arch/powerpc/mm/book3s64/slice.c | 39 ++++++++++++++++++++++++--------
1 file changed, 29 insertions(+), 10 deletions(-)
diff --git a/arch/powerpc/mm/book3s64/slice.c b/arch/powerpc/mm/book3s64/slice.c
index ef3ce37f1bb3..6914b8de627c 100644
--- a/arch/powerpc/mm/book3s64/slice.c
+++ b/arch/powerpc/mm/book3s64/slice.c
@@ -633,17 +633,36 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
}
EXPORT_SYMBOL_GPL(slice_get_unmapped_area);
+#ifdef CONFIG_HUGETLB_PAGE
+static int file_to_psize(struct file *file)
+{
+ struct hstate *hstate = hstate_file(file);
+ return shift_to_mmu_psize(huge_page_shift(hstate));
+}
+#else
+static int file_to_psize(struct file *file)
+{
+ return 0;
+}
+#endif
+
unsigned long arch_get_unmapped_area(struct file *filp,
unsigned long addr,
unsigned long len,
unsigned long pgoff,
unsigned long flags)
{
+ unsigned int psize;
+
if (radix_enabled())
return generic_get_unmapped_area(filp, addr, len, pgoff, flags);
- return slice_get_unmapped_area(addr, len, flags,
- mm_ctx_user_psize(¤t->mm->context), 0);
+ if (filp && is_file_hugepages(filp))
+ psize = file_to_psize(filp);
+ else
+ psize = mm_ctx_user_psize(¤t->mm->context);
+
+ return slice_get_unmapped_area(addr, len, flags, psize, 0);
}
unsigned long arch_get_unmapped_area_topdown(struct file *filp,
@@ -652,11 +671,17 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp,
const unsigned long pgoff,
const unsigned long flags)
{
+ unsigned int psize;
+
if (radix_enabled())
return generic_get_unmapped_area_topdown(filp, addr0, len, pgoff, flags);
- return slice_get_unmapped_area(addr0, len, flags,
- mm_ctx_user_psize(¤t->mm->context), 1);
+ if (filp && is_file_hugepages(filp))
+ psize = file_to_psize(filp);
+ else
+ psize = mm_ctx_user_psize(¤t->mm->context);
+
+ return slice_get_unmapped_area(addr0, len, flags, psize, 1);
}
unsigned int notrace get_slice_psize(struct mm_struct *mm, unsigned long addr)
@@ -787,12 +812,6 @@ unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
return 1UL << mmu_psize_to_shift(get_slice_psize(vma->vm_mm, vma->vm_start));
}
-static int file_to_psize(struct file *file)
-{
- struct hstate *hstate = hstate_file(file);
- return shift_to_mmu_psize(huge_page_shift(hstate));
-}
-
unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
unsigned long len, unsigned long pgoff,
unsigned long flags)
--
2.45.2
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags
2024-07-29 9:10 [PATCH v2 0/9] Unify hugetlb into arch_get_unmapped_area functions Oscar Salvador
` (4 preceding siblings ...)
2024-07-29 9:10 ` [PATCH v2 5/9] arch/powerpc: Teach book3s64 " Oscar Salvador
@ 2024-07-29 9:10 ` Oscar Salvador
2024-07-31 11:02 ` Lorenzo Stoakes
` (2 more replies)
2024-07-29 9:10 ` [PATCH v2 7/9] mm: Drop hugetlb_get_unmapped_area{_*} functions Oscar Salvador
` (2 subsequent siblings)
8 siblings, 3 replies; 22+ messages in thread
From: Oscar Salvador @ 2024-07-29 9:10 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, linux-mm, Peter Xu, Muchun Song, David Hildenbrand,
Donet Tom, Matthew Wilcox, Vlastimil Babka, Michal Hocko,
Oscar Salvador
Hugetlb mappings will no longer be special cased but rather go through
the generic mm_get_unmapped_area_vmflags function.
For that to happen, let us remove the .get_unmapped_area from
hugetlbfs_file_operations struct, and hint __get_unmapped_area
that it should not send hugetlb mappings through thp_get_unmapped_area_vmflags
but through mm_get_unmapped_area_vmflags.
Create also a function called hugetlb_mmap_check_and_align() where a
couple of safety checks are being done and the addr is aligned to
the huge page size.
Otherwise we will have to do this in every single function, which
duplicates quite a lot of code.
Signed-off-by: Oscar Salvador <osalvador@suse.de>
---
fs/hugetlbfs/inode.c | 22 ++++++++++++++--------
include/linux/hugetlb.h | 8 +++-----
mm/mmap.c | 15 ++++++++++++++-
3 files changed, 31 insertions(+), 14 deletions(-)
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 9f6cff356796..5d47a2785a5d 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -258,15 +258,22 @@ generic_hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
pgoff, flags);
}
-#ifndef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
-static unsigned long
-hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
- unsigned long len, unsigned long pgoff,
- unsigned long flags)
+unsigned long
+hugetlb_mmap_check_and_align(struct file *file, unsigned long addr,
+ unsigned long len, unsigned long flags)
{
- return generic_hugetlb_get_unmapped_area(file, addr, len, pgoff, flags);
+ unsigned long addr0 = 0;
+ struct hstate *h = hstate_file(file);
+
+ if (len & ~huge_page_mask(h))
+ return -EINVAL;
+ if ((flags & MAP_FIXED) && prepare_hugepage_range(file, addr, len))
+ return -EINVAL;
+ if (addr)
+ addr0 = ALIGN(addr, huge_page_size(h));
+
+ return addr0;
}
-#endif
/*
* Someone wants to read @bytes from a HWPOISON hugetlb @page from @offset.
@@ -1300,7 +1307,6 @@ static const struct file_operations hugetlbfs_file_operations = {
.read_iter = hugetlbfs_read_iter,
.mmap = hugetlbfs_file_mmap,
.fsync = noop_fsync,
- .get_unmapped_area = hugetlb_get_unmapped_area,
.llseek = default_llseek,
.fallocate = hugetlbfs_fallocate,
.fop_flags = FOP_HUGE_PAGES,
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 0ec14e5e0890..1413cdcfdb1a 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -549,11 +549,9 @@ static inline struct hstate *hstate_inode(struct inode *i)
}
#endif /* !CONFIG_HUGETLBFS */
-#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
-unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
- unsigned long len, unsigned long pgoff,
- unsigned long flags);
-#endif /* HAVE_ARCH_HUGETLB_UNMAPPED_AREA */
+unsigned long
+hugetlb_mmap_check_and_align(struct file *file, unsigned long addr,
+ unsigned long len, unsigned long flags);
unsigned long
generic_hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
diff --git a/mm/mmap.c b/mm/mmap.c
index 7b623811d82a..f755d8a298c5 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -849,6 +849,7 @@ __get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
unsigned long, unsigned long, unsigned long)
= NULL;
+ bool is_hugetlb = false;
unsigned long error = arch_mmap_check(addr, len, flags);
if (error)
return error;
@@ -857,6 +858,9 @@ __get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
if (len > TASK_SIZE)
return -ENOMEM;
+ if (file && is_file_hugepages(file))
+ is_hugetlb = true;
+
if (file) {
if (file->f_op->get_unmapped_area)
get_area = file->f_op->get_unmapped_area;
@@ -874,11 +878,20 @@ __get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
if (get_area) {
addr = get_area(file, addr, len, pgoff, flags);
- } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) {
+ } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && !is_hugetlb) {
/* Ensures that larger anonymous mappings are THP aligned. */
addr = thp_get_unmapped_area_vmflags(file, addr, len,
pgoff, flags, vm_flags);
} else {
+ /*
+ * Consolidate hugepages checks in one place, and also align addr
+ * to hugepage size.
+ */
+ if (is_hugetlb) {
+ addr = hugetlb_mmap_check_and_align(file, addr, len, flags);
+ if (IS_ERR_VALUE(addr))
+ return addr;
+ }
addr = mm_get_unmapped_area_vmflags(current->mm, file, addr, len,
pgoff, flags, vm_flags);
}
--
2.45.2
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 7/9] mm: Drop hugetlb_get_unmapped_area{_*} functions
2024-07-29 9:10 [PATCH v2 0/9] Unify hugetlb into arch_get_unmapped_area functions Oscar Salvador
` (5 preceding siblings ...)
2024-07-29 9:10 ` [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags Oscar Salvador
@ 2024-07-29 9:10 ` Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 8/9] arch/s390: Clean up hugetlb definitions Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 9/9] mm: Consolidate common checks in hugetlb_mmap_check_and_align Oscar Salvador
8 siblings, 0 replies; 22+ messages in thread
From: Oscar Salvador @ 2024-07-29 9:10 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, linux-mm, Peter Xu, Muchun Song, David Hildenbrand,
Donet Tom, Matthew Wilcox, Vlastimil Babka, Michal Hocko,
Oscar Salvador
Hugetlb mappings are now handled through normal channels just like any
other mapping, so we no longer need hugetlb_get_unmapped_area* specific
functions.
Signed-off-by: Oscar Salvador <osalvador@suse.de>
---
arch/parisc/mm/hugetlbpage.c | 21 ------
arch/powerpc/mm/book3s64/slice.c | 10 ---
arch/s390/mm/hugetlbpage.c | 85 ------------------------
arch/sparc/mm/hugetlbpage.c | 108 -------------------------------
arch/x86/mm/hugetlbpage.c | 101 -----------------------------
fs/hugetlbfs/inode.c | 91 --------------------------
include/linux/hugetlb.h | 4 --
7 files changed, 420 deletions(-)
diff --git a/arch/parisc/mm/hugetlbpage.c b/arch/parisc/mm/hugetlbpage.c
index 0356199bd9e7..e9d18cf25b79 100644
--- a/arch/parisc/mm/hugetlbpage.c
+++ b/arch/parisc/mm/hugetlbpage.c
@@ -21,27 +21,6 @@
#include <asm/mmu_context.h>
-unsigned long
-hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
- unsigned long len, unsigned long pgoff, unsigned long flags)
-{
- struct hstate *h = hstate_file(file);
-
- if (len & ~huge_page_mask(h))
- return -EINVAL;
- if (len > TASK_SIZE)
- return -ENOMEM;
-
- if (flags & MAP_FIXED)
- if (prepare_hugepage_range(file, addr, len))
- return -EINVAL;
-
- if (addr)
- addr = ALIGN(addr, huge_page_size(h));
-
- /* we need to make sure the colouring is OK */
- return arch_get_unmapped_area(file, addr, len, pgoff, flags);
-}
pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
diff --git a/arch/powerpc/mm/book3s64/slice.c b/arch/powerpc/mm/book3s64/slice.c
index 6914b8de627c..6ce16bc330a2 100644
--- a/arch/powerpc/mm/book3s64/slice.c
+++ b/arch/powerpc/mm/book3s64/slice.c
@@ -811,14 +811,4 @@ unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
return 1UL << mmu_psize_to_shift(get_slice_psize(vma->vm_mm, vma->vm_start));
}
-
-unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
- unsigned long len, unsigned long pgoff,
- unsigned long flags)
-{
- if (radix_enabled())
- return generic_hugetlb_get_unmapped_area(file, addr, len, pgoff, flags);
-
- return slice_get_unmapped_area(addr, len, flags, file_to_psize(file), 1);
-}
#endif
diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c
index ded0eff58a19..7c79cf1bc7d7 100644
--- a/arch/s390/mm/hugetlbpage.c
+++ b/arch/s390/mm/hugetlbpage.c
@@ -242,88 +242,3 @@ bool __init arch_hugetlb_valid_size(unsigned long size)
else
return false;
}
-
-static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
- unsigned long addr, unsigned long len,
- unsigned long pgoff, unsigned long flags)
-{
- struct hstate *h = hstate_file(file);
- struct vm_unmapped_area_info info = {};
-
- info.length = len;
- info.low_limit = current->mm->mmap_base;
- info.high_limit = TASK_SIZE;
- info.align_mask = PAGE_MASK & ~huge_page_mask(h);
- return vm_unmapped_area(&info);
-}
-
-static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
- unsigned long addr0, unsigned long len,
- unsigned long pgoff, unsigned long flags)
-{
- struct hstate *h = hstate_file(file);
- struct vm_unmapped_area_info info = {};
- unsigned long addr;
-
- info.flags = VM_UNMAPPED_AREA_TOPDOWN;
- info.length = len;
- info.low_limit = PAGE_SIZE;
- info.high_limit = current->mm->mmap_base;
- info.align_mask = PAGE_MASK & ~huge_page_mask(h);
- addr = vm_unmapped_area(&info);
-
- /*
- * A failed mmap() very likely causes application failure,
- * so fall back to the bottom-up function here. This scenario
- * can happen with large stack limits and large mmap()
- * allocations.
- */
- if (addr & ~PAGE_MASK) {
- VM_BUG_ON(addr != -ENOMEM);
- info.flags = 0;
- info.low_limit = TASK_UNMAPPED_BASE;
- info.high_limit = TASK_SIZE;
- addr = vm_unmapped_area(&info);
- }
-
- return addr;
-}
-
-unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
- unsigned long len, unsigned long pgoff, unsigned long flags)
-{
- struct hstate *h = hstate_file(file);
- struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma;
-
- if (len & ~huge_page_mask(h))
- return -EINVAL;
- if (len > TASK_SIZE - mmap_min_addr)
- return -ENOMEM;
-
- if (flags & MAP_FIXED) {
- if (prepare_hugepage_range(file, addr, len))
- return -EINVAL;
- goto check_asce_limit;
- }
-
- if (addr) {
- addr = ALIGN(addr, huge_page_size(h));
- vma = find_vma(mm, addr);
- if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
- (!vma || addr + len <= vm_start_gap(vma)))
- goto check_asce_limit;
- }
-
- if (!test_bit(MMF_TOPDOWN, &mm->flags))
- addr = hugetlb_get_unmapped_area_bottomup(file, addr, len,
- pgoff, flags);
- else
- addr = hugetlb_get_unmapped_area_topdown(file, addr, len,
- pgoff, flags);
- if (offset_in_page(addr))
- return addr;
-
-check_asce_limit:
- return check_asce_limit(mm, addr, len);
-}
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
index cc91ca7a1e18..eee601a0d2cf 100644
--- a/arch/sparc/mm/hugetlbpage.c
+++ b/arch/sparc/mm/hugetlbpage.c
@@ -19,114 +19,6 @@
#include <asm/cacheflush.h>
#include <asm/mmu_context.h>
-/* Slightly simplified from the non-hugepage variant because by
- * definition we don't have to worry about any page coloring stuff
- */
-
-static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp,
- unsigned long addr,
- unsigned long len,
- unsigned long pgoff,
- unsigned long flags)
-{
- struct hstate *h = hstate_file(filp);
- unsigned long task_size = TASK_SIZE;
- struct vm_unmapped_area_info info = {};
-
- if (test_thread_flag(TIF_32BIT))
- task_size = STACK_TOP32;
-
- info.length = len;
- info.low_limit = TASK_UNMAPPED_BASE;
- info.high_limit = min(task_size, VA_EXCLUDE_START);
- info.align_mask = PAGE_MASK & ~huge_page_mask(h);
- addr = vm_unmapped_area(&info);
-
- if ((addr & ~PAGE_MASK) && task_size > VA_EXCLUDE_END) {
- VM_BUG_ON(addr != -ENOMEM);
- info.low_limit = VA_EXCLUDE_END;
- info.high_limit = task_size;
- addr = vm_unmapped_area(&info);
- }
-
- return addr;
-}
-
-static unsigned long
-hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
- const unsigned long len,
- const unsigned long pgoff,
- const unsigned long flags)
-{
- struct hstate *h = hstate_file(filp);
- struct mm_struct *mm = current->mm;
- unsigned long addr = addr0;
- struct vm_unmapped_area_info info = {};
-
- /* This should only ever run for 32-bit processes. */
- BUG_ON(!test_thread_flag(TIF_32BIT));
-
- info.flags = VM_UNMAPPED_AREA_TOPDOWN;
- info.length = len;
- info.low_limit = PAGE_SIZE;
- info.high_limit = mm->mmap_base;
- info.align_mask = PAGE_MASK & ~huge_page_mask(h);
- addr = vm_unmapped_area(&info);
-
- /*
- * A failed mmap() very likely causes application failure,
- * so fall back to the bottom-up function here. This scenario
- * can happen with large stack limits and large mmap()
- * allocations.
- */
- if (addr & ~PAGE_MASK) {
- VM_BUG_ON(addr != -ENOMEM);
- info.flags = 0;
- info.low_limit = TASK_UNMAPPED_BASE;
- info.high_limit = STACK_TOP32;
- addr = vm_unmapped_area(&info);
- }
-
- return addr;
-}
-
-unsigned long
-hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
- unsigned long len, unsigned long pgoff, unsigned long flags)
-{
- struct hstate *h = hstate_file(file);
- struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma;
- unsigned long task_size = TASK_SIZE;
-
- if (test_thread_flag(TIF_32BIT))
- task_size = STACK_TOP32;
-
- if (len & ~huge_page_mask(h))
- return -EINVAL;
- if (len > task_size)
- return -ENOMEM;
-
- if (flags & MAP_FIXED) {
- if (prepare_hugepage_range(file, addr, len))
- return -EINVAL;
- return addr;
- }
-
- if (addr) {
- addr = ALIGN(addr, huge_page_size(h));
- vma = find_vma(mm, addr);
- if (task_size - len >= addr &&
- (!vma || addr + len <= vm_start_gap(vma)))
- return addr;
- }
- if (!test_bit(MMF_TOPDOWN, &mm->flags))
- return hugetlb_get_unmapped_area_bottomup(file, addr, len,
- pgoff, flags);
- else
- return hugetlb_get_unmapped_area_topdown(file, addr, len,
- pgoff, flags);
-}
static pte_t sun4u_hugepage_shift_to_tte(pte_t entry, unsigned int shift)
{
diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
index 807a5859a3c4..58f7f2bd535d 100644
--- a/arch/x86/mm/hugetlbpage.c
+++ b/arch/x86/mm/hugetlbpage.c
@@ -19,107 +19,6 @@
#include <asm/tlbflush.h>
#include <asm/elf.h>
-#ifdef CONFIG_HUGETLB_PAGE
-static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
- unsigned long addr, unsigned long len,
- unsigned long pgoff, unsigned long flags)
-{
- struct hstate *h = hstate_file(file);
- struct vm_unmapped_area_info info = {};
-
- info.length = len;
- info.low_limit = get_mmap_base(1);
-
- /*
- * If hint address is above DEFAULT_MAP_WINDOW, look for unmapped area
- * in the full address space.
- */
- info.high_limit = in_32bit_syscall() ?
- task_size_32bit() : task_size_64bit(addr > DEFAULT_MAP_WINDOW);
-
- info.align_mask = PAGE_MASK & ~huge_page_mask(h);
- return vm_unmapped_area(&info);
-}
-
-static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
- unsigned long addr, unsigned long len,
- unsigned long pgoff, unsigned long flags)
-{
- struct hstate *h = hstate_file(file);
- struct vm_unmapped_area_info info = {};
-
- info.flags = VM_UNMAPPED_AREA_TOPDOWN;
- info.length = len;
- info.low_limit = PAGE_SIZE;
- info.high_limit = get_mmap_base(0);
-
- /*
- * If hint address is above DEFAULT_MAP_WINDOW, look for unmapped area
- * in the full address space.
- */
- if (addr > DEFAULT_MAP_WINDOW && !in_32bit_syscall())
- info.high_limit += TASK_SIZE_MAX - DEFAULT_MAP_WINDOW;
-
- info.align_mask = PAGE_MASK & ~huge_page_mask(h);
- addr = vm_unmapped_area(&info);
-
- /*
- * A failed mmap() very likely causes application failure,
- * so fall back to the bottom-up function here. This scenario
- * can happen with large stack limits and large mmap()
- * allocations.
- */
- if (addr & ~PAGE_MASK) {
- VM_BUG_ON(addr != -ENOMEM);
- info.flags = 0;
- info.low_limit = TASK_UNMAPPED_BASE;
- info.high_limit = TASK_SIZE_LOW;
- addr = vm_unmapped_area(&info);
- }
-
- return addr;
-}
-
-unsigned long
-hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
- unsigned long len, unsigned long pgoff, unsigned long flags)
-{
- struct hstate *h = hstate_file(file);
- struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma;
-
- if (len & ~huge_page_mask(h))
- return -EINVAL;
-
- if (len > TASK_SIZE)
- return -ENOMEM;
-
- /* No address checking. See comment at mmap_address_hint_valid() */
- if (flags & MAP_FIXED) {
- if (prepare_hugepage_range(file, addr, len))
- return -EINVAL;
- return addr;
- }
-
- if (addr) {
- addr &= huge_page_mask(h);
- if (!mmap_address_hint_valid(addr, len))
- goto get_unmapped_area;
-
- vma = find_vma(mm, addr);
- if (!vma || addr + len <= vm_start_gap(vma))
- return addr;
- }
-
-get_unmapped_area:
- if (!test_bit(MMF_TOPDOWN, &mm->flags))
- return hugetlb_get_unmapped_area_bottomup(file, addr, len,
- pgoff, flags);
- else
- return hugetlb_get_unmapped_area_topdown(file, addr, len,
- pgoff, flags);
-}
-#endif /* CONFIG_HUGETLB_PAGE */
#ifdef CONFIG_X86_64
bool __init arch_hugetlb_valid_size(unsigned long size)
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 5d47a2785a5d..3f0b8abbf851 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -167,97 +167,6 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
return ret;
}
-/*
- * Called under mmap_write_lock(mm).
- */
-
-static unsigned long
-hugetlb_get_unmapped_area_bottomup(struct file *file, unsigned long addr,
- unsigned long len, unsigned long pgoff, unsigned long flags)
-{
- struct hstate *h = hstate_file(file);
- struct vm_unmapped_area_info info = {};
-
- info.length = len;
- info.low_limit = current->mm->mmap_base;
- info.high_limit = arch_get_mmap_end(addr, len, flags);
- info.align_mask = PAGE_MASK & ~huge_page_mask(h);
- return vm_unmapped_area(&info);
-}
-
-static unsigned long
-hugetlb_get_unmapped_area_topdown(struct file *file, unsigned long addr,
- unsigned long len, unsigned long pgoff, unsigned long flags)
-{
- struct hstate *h = hstate_file(file);
- struct vm_unmapped_area_info info = {};
-
- info.flags = VM_UNMAPPED_AREA_TOPDOWN;
- info.length = len;
- info.low_limit = PAGE_SIZE;
- info.high_limit = arch_get_mmap_base(addr, current->mm->mmap_base);
- info.align_mask = PAGE_MASK & ~huge_page_mask(h);
- addr = vm_unmapped_area(&info);
-
- /*
- * A failed mmap() very likely causes application failure,
- * so fall back to the bottom-up function here. This scenario
- * can happen with large stack limits and large mmap()
- * allocations.
- */
- if (unlikely(offset_in_page(addr))) {
- VM_BUG_ON(addr != -ENOMEM);
- info.flags = 0;
- info.low_limit = current->mm->mmap_base;
- info.high_limit = arch_get_mmap_end(addr, len, flags);
- addr = vm_unmapped_area(&info);
- }
-
- return addr;
-}
-
-unsigned long
-generic_hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
- unsigned long len, unsigned long pgoff,
- unsigned long flags)
-{
- struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma, *prev;
- struct hstate *h = hstate_file(file);
- const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags);
-
- if (len & ~huge_page_mask(h))
- return -EINVAL;
- if (len > mmap_end - mmap_min_addr)
- return -ENOMEM;
-
- if (flags & MAP_FIXED) {
- if (prepare_hugepage_range(file, addr, len))
- return -EINVAL;
- return addr;
- }
-
- if (addr) {
- addr = ALIGN(addr, huge_page_size(h));
- vma = find_vma_prev(mm, addr, &prev);
- if (mmap_end - len >= addr && addr >= mmap_min_addr &&
- (!vma || addr + len <= vm_start_gap(vma)) &&
- (!prev || addr >= vm_end_gap(prev)))
- return addr;
- }
-
- /*
- * Use MMF_TOPDOWN flag as a hint to use topdown routine.
- * If architectures have special needs, they should define their own
- * version of hugetlb_get_unmapped_area.
- */
- if (test_bit(MMF_TOPDOWN, &mm->flags))
- return hugetlb_get_unmapped_area_topdown(file, addr, len,
- pgoff, flags);
- return hugetlb_get_unmapped_area_bottomup(file, addr, len,
- pgoff, flags);
-}
-
unsigned long
hugetlb_mmap_check_and_align(struct file *file, unsigned long addr,
unsigned long len, unsigned long flags)
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 1413cdcfdb1a..bd82a0f34275 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -553,10 +553,6 @@ unsigned long
hugetlb_mmap_check_and_align(struct file *file, unsigned long addr,
unsigned long len, unsigned long flags);
-unsigned long
-generic_hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
- unsigned long len, unsigned long pgoff,
- unsigned long flags);
/*
* huegtlb page specific state flags. These flags are located in page.private
--
2.45.2
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 8/9] arch/s390: Clean up hugetlb definitions
2024-07-29 9:10 [PATCH v2 0/9] Unify hugetlb into arch_get_unmapped_area functions Oscar Salvador
` (6 preceding siblings ...)
2024-07-29 9:10 ` [PATCH v2 7/9] mm: Drop hugetlb_get_unmapped_area{_*} functions Oscar Salvador
@ 2024-07-29 9:10 ` Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 9/9] mm: Consolidate common checks in hugetlb_mmap_check_and_align Oscar Salvador
8 siblings, 0 replies; 22+ messages in thread
From: Oscar Salvador @ 2024-07-29 9:10 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, linux-mm, Peter Xu, Muchun Song, David Hildenbrand,
Donet Tom, Matthew Wilcox, Vlastimil Babka, Michal Hocko,
Oscar Salvador
s390 redefines functions that are already defined (and the same)
in include/asm-generic/hugetlb.h.
Do as the other architectures: 1) include include/asm-generic/hugetlb.h
2) drop the already defined functions in the generic hugetlb.h and
3) use the __HAVE_ARCH_HUGE_* macros to define our own.
This gets rid of quite some code.
Signed-off-by: Oscar Salvador <osalvador@suse.de>
---
arch/s390/include/asm/hugetlb.h | 58 +++++++++------------------------
include/asm-generic/hugetlb.h | 8 +++++
2 files changed, 24 insertions(+), 42 deletions(-)
diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h
index cf1b5d6fb1a6..37e80a32623a 100644
--- a/arch/s390/include/asm/hugetlb.h
+++ b/arch/s390/include/asm/hugetlb.h
@@ -12,21 +12,24 @@
#include <linux/pgtable.h>
#include <asm/page.h>
-#define hugetlb_free_pgd_range free_pgd_range
#define hugepages_supported() (MACHINE_HAS_EDAT1)
+#define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte, unsigned long sz);
void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte);
-pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
-pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+#define __HAVE_ARCH_HUGE_PTEP_GET
+extern pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
+#define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR
+extern pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
unsigned long addr, pte_t *ptep);
/*
* If the arch doesn't supply something else, assume that hugepage
* size aligned regions are ok without further preparation.
*/
+#define __HAVE_ARCH_PREPARE_HUGEPAGE_RANGE
static inline int prepare_hugepage_range(struct file *file,
unsigned long addr, unsigned long len)
{
@@ -45,6 +48,7 @@ static inline void arch_clear_hugetlb_flags(struct folio *folio)
}
#define arch_clear_hugetlb_flags arch_clear_hugetlb_flags
+#define __HAVE_ARCH_HUGE_PTE_CLEAR
static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, unsigned long sz)
{
@@ -54,12 +58,14 @@ static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
set_pte(ptep, __pte(_SEGMENT_ENTRY_EMPTY));
}
+#define __HAVE_ARCH_HUGE_PTEP_CLEAR_FLUSH
static inline pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
unsigned long address, pte_t *ptep)
{
return huge_ptep_get_and_clear(vma->vm_mm, address, ptep);
}
+#define __HAVE_ARCH_HUGE_PTEP_SET_ACCESS_FLAGS
static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep,
pte_t pte, int dirty)
@@ -72,6 +78,7 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
return changed;
}
+#define __HAVE_ARCH_HUGE_PTEP_SET_WRPROTECT
static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
unsigned long addr, pte_t *ptep)
{
@@ -79,69 +86,36 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
__set_huge_pte_at(mm, addr, ptep, pte_wrprotect(pte));
}
-static inline pte_t mk_huge_pte(struct page *page, pgprot_t pgprot)
-{
- return mk_pte(page, pgprot);
-}
-
+#define __HAVE_ARCH_HUGE_PTE_NONE
static inline int huge_pte_none(pte_t pte)
{
return pte_none(pte);
}
+#define __HAVE_ARCH_HUGE_PTE_NONE_MOSTLY
static inline int huge_pte_none_mostly(pte_t pte)
{
return huge_pte_none(pte);
}
-static inline int huge_pte_write(pte_t pte)
-{
- return pte_write(pte);
-}
-
-static inline int huge_pte_dirty(pte_t pte)
-{
- return pte_dirty(pte);
-}
-
-static inline pte_t huge_pte_mkwrite(pte_t pte)
-{
- return pte_mkwrite_novma(pte);
-}
-
-static inline pte_t huge_pte_mkdirty(pte_t pte)
-{
- return pte_mkdirty(pte);
-}
-
-static inline pte_t huge_pte_wrprotect(pte_t pte)
-{
- return pte_wrprotect(pte);
-}
-
-static inline pte_t huge_pte_modify(pte_t pte, pgprot_t newprot)
-{
- return pte_modify(pte, newprot);
-}
-
+#define __HAVE_ARCH_HUGE_PTE_MKUFFD_WP
static inline pte_t huge_pte_mkuffd_wp(pte_t pte)
{
return pte;
}
+#define __HAVE_ARCH_HUGE_PTE_CLEAR_UFFD_WP
static inline pte_t huge_pte_clear_uffd_wp(pte_t pte)
{
return pte;
}
+#define __HAVE_ARCH_HUGE_PTE_UFFD_WP
static inline int huge_pte_uffd_wp(pte_t pte)
{
return 0;
}
-static inline bool gigantic_page_runtime_supported(void)
-{
- return true;
-}
+#include <asm-generic/hugetlb.h>
#endif /* _ASM_S390_HUGETLB_H */
diff --git a/include/asm-generic/hugetlb.h b/include/asm-generic/hugetlb.h
index 594d5905f615..67bbdafcfc22 100644
--- a/include/asm-generic/hugetlb.h
+++ b/include/asm-generic/hugetlb.h
@@ -42,20 +42,26 @@ static inline pte_t huge_pte_modify(pte_t pte, pgprot_t newprot)
return pte_modify(pte, newprot);
}
+#ifndef __HAVE_ARCH_HUGE_PTE_MKUFFD_WP
static inline pte_t huge_pte_mkuffd_wp(pte_t pte)
{
return huge_pte_wrprotect(pte_mkuffd_wp(pte));
}
+#endif
+#ifndef __HAVE_ARCH_HUGE_PTE_CLEAR_UFFD_WP
static inline pte_t huge_pte_clear_uffd_wp(pte_t pte)
{
return pte_clear_uffd_wp(pte);
}
+#endif
+#ifndef __HAVE_ARCH_HUGE_PTE_UFFD_WP
static inline int huge_pte_uffd_wp(pte_t pte)
{
return pte_uffd_wp(pte);
}
+#endif
#ifndef __HAVE_ARCH_HUGE_PTE_CLEAR
static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
@@ -106,10 +112,12 @@ static inline int huge_pte_none(pte_t pte)
#endif
/* Please refer to comments above pte_none_mostly() for the usage */
+#ifndef __HAVE_ARCH_HUGE_PTE_NONE_MOSTLY
static inline int huge_pte_none_mostly(pte_t pte)
{
return huge_pte_none(pte) || is_pte_marker(pte);
}
+#endif
#ifndef __HAVE_ARCH_PREPARE_HUGEPAGE_RANGE
static inline int prepare_hugepage_range(struct file *file,
--
2.45.2
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 9/9] mm: Consolidate common checks in hugetlb_mmap_check_and_align
2024-07-29 9:10 [PATCH v2 0/9] Unify hugetlb into arch_get_unmapped_area functions Oscar Salvador
` (7 preceding siblings ...)
2024-07-29 9:10 ` [PATCH v2 8/9] arch/s390: Clean up hugetlb definitions Oscar Salvador
@ 2024-07-29 9:10 ` Oscar Salvador
2024-07-30 9:59 ` kernel test robot
8 siblings, 1 reply; 22+ messages in thread
From: Oscar Salvador @ 2024-07-29 9:10 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, linux-mm, Peter Xu, Muchun Song, David Hildenbrand,
Donet Tom, Matthew Wilcox, Vlastimil Babka, Michal Hocko,
Oscar Salvador
prepare_hugepage_range() performs almost the same checks for all
architectures that define it, with the exception of mips and loongarch
that also check for overflows.
The rest checks for the addr and len to be properly aligned, so we can
move that to the generic hugetlb_mmap_check_and_align() function and get
rid of a fair amount of duplicated code.
Signed-off-by: Oscar Salvador <osalvador@suse.de>
---
arch/loongarch/include/asm/hugetlb.h | 4 ----
arch/mips/include/asm/hugetlb.h | 4 ----
arch/parisc/include/asm/hugetlb.h | 15 ---------------
arch/s390/include/asm/hugetlb.h | 17 -----------------
arch/sh/include/asm/hugetlb.h | 15 ---------------
fs/hugetlbfs/inode.c | 8 ++++++--
include/asm-generic/hugetlb.h | 7 -------
7 files changed, 6 insertions(+), 64 deletions(-)
diff --git a/arch/loongarch/include/asm/hugetlb.h b/arch/loongarch/include/asm/hugetlb.h
index aa44b3fe43dd..107566c98938 100644
--- a/arch/loongarch/include/asm/hugetlb.h
+++ b/arch/loongarch/include/asm/hugetlb.h
@@ -18,10 +18,6 @@ static inline int prepare_hugepage_range(struct file *file,
unsigned long task_size = STACK_TOP;
struct hstate *h = hstate_file(file);
- if (len & ~huge_page_mask(h))
- return -EINVAL;
- if (addr & ~huge_page_mask(h))
- return -EINVAL;
if (len > task_size)
return -ENOMEM;
if (task_size - len < addr)
diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h
index fd69c8808554..6a63d82a8ab3 100644
--- a/arch/mips/include/asm/hugetlb.h
+++ b/arch/mips/include/asm/hugetlb.h
@@ -19,10 +19,6 @@ static inline int prepare_hugepage_range(struct file *file,
unsigned long task_size = STACK_TOP;
struct hstate *h = hstate_file(file);
- if (len & ~huge_page_mask(h))
- return -EINVAL;
- if (addr & ~huge_page_mask(h))
- return -EINVAL;
if (len > task_size)
return -ENOMEM;
if (task_size - len < addr)
diff --git a/arch/parisc/include/asm/hugetlb.h b/arch/parisc/include/asm/hugetlb.h
index 72daacc472a0..5b3a5429f71b 100644
--- a/arch/parisc/include/asm/hugetlb.h
+++ b/arch/parisc/include/asm/hugetlb.h
@@ -12,21 +12,6 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep);
-/*
- * If the arch doesn't supply something else, assume that hugepage
- * size aligned regions are ok without further preparation.
- */
-#define __HAVE_ARCH_PREPARE_HUGEPAGE_RANGE
-static inline int prepare_hugepage_range(struct file *file,
- unsigned long addr, unsigned long len)
-{
- if (len & ~HPAGE_MASK)
- return -EINVAL;
- if (addr & ~HPAGE_MASK)
- return -EINVAL;
- return 0;
-}
-
#define __HAVE_ARCH_HUGE_PTEP_CLEAR_FLUSH
static inline pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep)
diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h
index 37e80a32623a..6f815d4ba0ca 100644
--- a/arch/s390/include/asm/hugetlb.h
+++ b/arch/s390/include/asm/hugetlb.h
@@ -25,23 +25,6 @@ extern pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep
extern pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
unsigned long addr, pte_t *ptep);
-/*
- * If the arch doesn't supply something else, assume that hugepage
- * size aligned regions are ok without further preparation.
- */
-#define __HAVE_ARCH_PREPARE_HUGEPAGE_RANGE
-static inline int prepare_hugepage_range(struct file *file,
- unsigned long addr, unsigned long len)
-{
- struct hstate *h = hstate_file(file);
-
- if (len & ~huge_page_mask(h))
- return -EINVAL;
- if (addr & ~huge_page_mask(h))
- return -EINVAL;
- return 0;
-}
-
static inline void arch_clear_hugetlb_flags(struct folio *folio)
{
clear_bit(PG_arch_1, &folio->flags);
diff --git a/arch/sh/include/asm/hugetlb.h b/arch/sh/include/asm/hugetlb.h
index 75028bd568ba..4a92e6e4d627 100644
--- a/arch/sh/include/asm/hugetlb.h
+++ b/arch/sh/include/asm/hugetlb.h
@@ -5,21 +5,6 @@
#include <asm/cacheflush.h>
#include <asm/page.h>
-/*
- * If the arch doesn't supply something else, assume that hugepage
- * size aligned regions are ok without further preparation.
- */
-#define __HAVE_ARCH_PREPARE_HUGEPAGE_RANGE
-static inline int prepare_hugepage_range(struct file *file,
- unsigned long addr, unsigned long len)
-{
- if (len & ~HPAGE_MASK)
- return -EINVAL;
- if (addr & ~HPAGE_MASK)
- return -EINVAL;
- return 0;
-}
-
#define __HAVE_ARCH_HUGE_PTEP_CLEAR_FLUSH
static inline pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep)
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 3f0b8abbf851..1e35f0d3698b 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -176,8 +176,12 @@ hugetlb_mmap_check_and_align(struct file *file, unsigned long addr,
if (len & ~huge_page_mask(h))
return -EINVAL;
- if ((flags & MAP_FIXED) && prepare_hugepage_range(file, addr, len))
- return -EINVAL;
+ if (flags & MAP_FIXED) {
+ if (addr & ~huge_page_mask(h))
+ return -EINVAL;
+ if (prepare_hugepage_range(file, addr, len))
+ return -EINVAL;
+ }
if (addr)
addr0 = ALIGN(addr, huge_page_size(h));
diff --git a/include/asm-generic/hugetlb.h b/include/asm-generic/hugetlb.h
index 67bbdafcfc22..f42133dae68e 100644
--- a/include/asm-generic/hugetlb.h
+++ b/include/asm-generic/hugetlb.h
@@ -123,13 +123,6 @@ static inline int huge_pte_none_mostly(pte_t pte)
static inline int prepare_hugepage_range(struct file *file,
unsigned long addr, unsigned long len)
{
- struct hstate *h = hstate_file(file);
-
- if (len & ~huge_page_mask(h))
- return -EINVAL;
- if (addr & ~huge_page_mask(h))
- return -EINVAL;
-
return 0;
}
#endif
--
2.45.2
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 9/9] mm: Consolidate common checks in hugetlb_mmap_check_and_align
2024-07-29 9:10 ` [PATCH v2 9/9] mm: Consolidate common checks in hugetlb_mmap_check_and_align Oscar Salvador
@ 2024-07-30 9:59 ` kernel test robot
0 siblings, 0 replies; 22+ messages in thread
From: kernel test robot @ 2024-07-30 9:59 UTC (permalink / raw)
To: Oscar Salvador, Andrew Morton
Cc: oe-kbuild-all, Linux Memory Management List, linux-kernel,
Peter Xu, Muchun Song, David Hildenbrand, Donet Tom,
Matthew Wilcox, Vlastimil Babka, Michal Hocko, Oscar Salvador
Hi Oscar,
kernel test robot noticed the following build warnings:
[auto build test WARNING on s390/features]
[also build test WARNING on akpm-mm/mm-everything deller-parisc/for-next linus/master v6.11-rc1 next-20240730]
[cannot apply to powerpc/next powerpc/fixes arnd-asm-generic/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Oscar-Salvador/mm-mmap-Teach-generic_get_unmapped_area-_topdown-to-handle-hugetlb-mappings/20240729-171449
base: https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git features
patch link: https://lore.kernel.org/r/20240729091018.2152-10-osalvador%40suse.de
patch subject: [PATCH v2 9/9] mm: Consolidate common checks in hugetlb_mmap_check_and_align
config: mips-randconfig-r062-20240729 (https://download.01.org/0day-ci/archive/20240730/202407301708.tn4PRNvn-lkp@intel.com/config)
compiler: mips-linux-gcc (GCC) 14.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240730/202407301708.tn4PRNvn-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202407301708.tn4PRNvn-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from include/linux/hugetlb.h:792,
from kernel/fork.c:53:
arch/mips/include/asm/hugetlb.h: In function 'prepare_hugepage_range':
>> arch/mips/include/asm/hugetlb.h:20:24: warning: unused variable 'h' [-Wunused-variable]
20 | struct hstate *h = hstate_file(file);
| ^
vim +/h +20 arch/mips/include/asm/hugetlb.h
50a41ff292fafe David Daney 2009-05-27 13
78d6e4e8ea8700 Alexandre Ghiti 2018-10-26 14 #define __HAVE_ARCH_PREPARE_HUGEPAGE_RANGE
50a41ff292fafe David Daney 2009-05-27 15 static inline int prepare_hugepage_range(struct file *file,
50a41ff292fafe David Daney 2009-05-27 16 unsigned long addr,
50a41ff292fafe David Daney 2009-05-27 17 unsigned long len)
50a41ff292fafe David Daney 2009-05-27 18 {
50a41ff292fafe David Daney 2009-05-27 19 unsigned long task_size = STACK_TOP;
50a41ff292fafe David Daney 2009-05-27 @20 struct hstate *h = hstate_file(file);
50a41ff292fafe David Daney 2009-05-27 21
50a41ff292fafe David Daney 2009-05-27 22 if (len > task_size)
50a41ff292fafe David Daney 2009-05-27 23 return -ENOMEM;
50a41ff292fafe David Daney 2009-05-27 24 if (task_size - len < addr)
50a41ff292fafe David Daney 2009-05-27 25 return -EINVAL;
50a41ff292fafe David Daney 2009-05-27 26 return 0;
50a41ff292fafe David Daney 2009-05-27 27 }
50a41ff292fafe David Daney 2009-05-27 28
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags
2024-07-29 9:10 ` [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags Oscar Salvador
@ 2024-07-31 11:02 ` Lorenzo Stoakes
2024-07-31 15:08 ` Oscar Salvador
2024-08-05 21:03 ` kernel test robot
2024-08-11 13:23 ` kernel test robot
2 siblings, 1 reply; 22+ messages in thread
From: Lorenzo Stoakes @ 2024-07-31 11:02 UTC (permalink / raw)
To: Oscar Salvador
Cc: Andrew Morton, linux-kernel, linux-mm, Peter Xu, Muchun Song,
David Hildenbrand, Donet Tom, Matthew Wilcox, Vlastimil Babka,
Michal Hocko
On Mon, Jul 29, 2024 at 11:10:15AM GMT, Oscar Salvador wrote:
> Hugetlb mappings will no longer be special cased but rather go through
> the generic mm_get_unmapped_area_vmflags function.
> For that to happen, let us remove the .get_unmapped_area from
> hugetlbfs_file_operations struct, and hint __get_unmapped_area
> that it should not send hugetlb mappings through thp_get_unmapped_area_vmflags
> but through mm_get_unmapped_area_vmflags.
>
> Create also a function called hugetlb_mmap_check_and_align() where a
> couple of safety checks are being done and the addr is aligned to
> the huge page size.
> Otherwise we will have to do this in every single function, which
> duplicates quite a lot of code.
>
> Signed-off-by: Oscar Salvador <osalvador@suse.de>
> ---
> fs/hugetlbfs/inode.c | 22 ++++++++++++++--------
> include/linux/hugetlb.h | 8 +++-----
> mm/mmap.c | 15 ++++++++++++++-
> 3 files changed, 31 insertions(+), 14 deletions(-)
>
> diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
> index 9f6cff356796..5d47a2785a5d 100644
> --- a/fs/hugetlbfs/inode.c
> +++ b/fs/hugetlbfs/inode.c
> @@ -258,15 +258,22 @@ generic_hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
> pgoff, flags);
> }
>
> -#ifndef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
> -static unsigned long
> -hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
> - unsigned long len, unsigned long pgoff,
> - unsigned long flags)
> +unsigned long
> +hugetlb_mmap_check_and_align(struct file *file, unsigned long addr,
> + unsigned long len, unsigned long flags)
> {
> - return generic_hugetlb_get_unmapped_area(file, addr, len, pgoff, flags);
> + unsigned long addr0 = 0;
> + struct hstate *h = hstate_file(file);
> +
> + if (len & ~huge_page_mask(h))
> + return -EINVAL;
> + if ((flags & MAP_FIXED) && prepare_hugepage_range(file, addr, len))
> + return -EINVAL;
> + if (addr)
> + addr0 = ALIGN(addr, huge_page_size(h));
> +
> + return addr0;
> }
> -#endif
>
> /*
> * Someone wants to read @bytes from a HWPOISON hugetlb @page from @offset.
> @@ -1300,7 +1307,6 @@ static const struct file_operations hugetlbfs_file_operations = {
> .read_iter = hugetlbfs_read_iter,
> .mmap = hugetlbfs_file_mmap,
> .fsync = noop_fsync,
> - .get_unmapped_area = hugetlb_get_unmapped_area,
This is causing a NULL pointer deref error in the mm self-tests,
specifically hugepage-shm.
This is because in __get_unmapped_area(), you check to see if the file has
an f_ops->get_unampped_area() however ('wonderfully'...) the shm stuff
wraps it, so this will be shm_get_unmapped_area() which then accesses the
underlying hugetlb file and _unconditionally_ calls
f_op->get_unmapped_area(), which you just made NULL and... kaboom :)
You can't even add null check in to this wrapper as at this point
everything assumes that you _can_ get an unmapped area. So yeah, it's kinda
broken.
This makes me think the whole thing is super-delicate and you probably need
to rethink this approach carefully, or least _very carefully_ audit users
of this operation.
> .llseek = default_llseek,
> .fallocate = hugetlbfs_fallocate,
> .fop_flags = FOP_HUGE_PAGES,
> diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
> index 0ec14e5e0890..1413cdcfdb1a 100644
> --- a/include/linux/hugetlb.h
> +++ b/include/linux/hugetlb.h
> @@ -549,11 +549,9 @@ static inline struct hstate *hstate_inode(struct inode *i)
> }
> #endif /* !CONFIG_HUGETLBFS */
>
> -#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
> -unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
> - unsigned long len, unsigned long pgoff,
> - unsigned long flags);
> -#endif /* HAVE_ARCH_HUGETLB_UNMAPPED_AREA */
By doing this you are causing an compilation error (at least on my compiler
with an x86-64 defconfig-based build):
arch/x86/mm/hugetlbpage.c:84:1: error: no previous prototype for
‘hugetlb_get_unmapped_area’ [-Werror=missing-prototypes]
84 | hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
| ^~~~~~~~~~~~~~~~~~~~~~~~~
So you need to rethink how you are doing this. I am not sure why we'd leave
these arch-specific bits around unless you're calling into them somehow
elsewhere? But this error suggests you aren't.
> +unsigned long
> +hugetlb_mmap_check_and_align(struct file *file, unsigned long addr,
> + unsigned long len, unsigned long flags);
>
> unsigned long
> generic_hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
> diff --git a/mm/mmap.c b/mm/mmap.c
> index 7b623811d82a..f755d8a298c5 100644
> --- a/mm/mmap.c
> +++ b/mm/mmap.c
> @@ -849,6 +849,7 @@ __get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
> unsigned long, unsigned long, unsigned long)
> = NULL;
>
> + bool is_hugetlb = false;
> unsigned long error = arch_mmap_check(addr, len, flags);
> if (error)
> return error;
> @@ -857,6 +858,9 @@ __get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
> if (len > TASK_SIZE)
> return -ENOMEM;
>
> + if (file && is_file_hugepages(file))
> + is_hugetlb = true;
> +
> if (file) {
> if (file->f_op->get_unmapped_area)
> get_area = file->f_op->get_unmapped_area;
> @@ -874,11 +878,20 @@ __get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
>
> if (get_area) {
> addr = get_area(file, addr, len, pgoff, flags);
> - } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) {
> + } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && !is_hugetlb) {
> /* Ensures that larger anonymous mappings are THP aligned. */
> addr = thp_get_unmapped_area_vmflags(file, addr, len,
> pgoff, flags, vm_flags);
> } else {
> + /*
> + * Consolidate hugepages checks in one place, and also align addr
> + * to hugepage size.
> + */
> + if (is_hugetlb) {
> + addr = hugetlb_mmap_check_and_align(file, addr, len, flags);
> + if (IS_ERR_VALUE(addr))
> + return addr;
> + }
> addr = mm_get_unmapped_area_vmflags(current->mm, file, addr, len,
> pgoff, flags, vm_flags);
> }
> --
> 2.45.2
>
Andrew - could we drop this from mm-unstable until Oscar can respin? As
it's causing the mm self tests to kernel panic and I'm using them a lot in
my testing of a new series thanks :>)
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags
2024-07-31 11:02 ` Lorenzo Stoakes
@ 2024-07-31 15:08 ` Oscar Salvador
2024-07-31 15:11 ` Oscar Salvador
2024-07-31 15:19 ` Lorenzo Stoakes
0 siblings, 2 replies; 22+ messages in thread
From: Oscar Salvador @ 2024-07-31 15:08 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Andrew Morton, linux-kernel, linux-mm, Peter Xu, Muchun Song,
David Hildenbrand, Donet Tom, Matthew Wilcox, Vlastimil Babka,
Michal Hocko
On Wed, Jul 31, 2024 at 12:02:47PM +0100, Lorenzo Stoakes wrote:
> On Mon, Jul 29, 2024 at 11:10:15AM GMT, Oscar Salvador wrote:
> > * Someone wants to read @bytes from a HWPOISON hugetlb @page from @offset.
> > @@ -1300,7 +1307,6 @@ static const struct file_operations hugetlbfs_file_operations = {
> > .read_iter = hugetlbfs_read_iter,
> > .mmap = hugetlbfs_file_mmap,
> > .fsync = noop_fsync,
> > - .get_unmapped_area = hugetlb_get_unmapped_area,
>
> This is causing a NULL pointer deref error in the mm self-tests,
> specifically hugepage-shm.
>
> This is because in __get_unmapped_area(), you check to see if the file has
> an f_ops->get_unampped_area() however ('wonderfully'...) the shm stuff
> wraps it, so this will be shm_get_unmapped_area() which then accesses the
> underlying hugetlb file and _unconditionally_ calls
> f_op->get_unmapped_area(), which you just made NULL and... kaboom :)
>
> You can't even add null check in to this wrapper as at this point
> everything assumes that you _can_ get an unmapped area. So yeah, it's kinda
> broken.
>
> This makes me think the whole thing is super-delicate and you probably need
> to rethink this approach carefully, or least _very carefully_ audit users
> of this operation.
Thanks for reporting this Lorenzo, highly appreciated.
I will check, but..
> By doing this you are causing an compilation error (at least on my compiler
> with an x86-64 defconfig-based build):
>
> arch/x86/mm/hugetlbpage.c:84:1: error: no previous prototype for
> ‘hugetlb_get_unmapped_area’ [-Werror=missing-prototypes]
> 84 | hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
> | ^~~~~~~~~~~~~~~~~~~~~~~~~
Something is off here.
git grep hugetlb_get_unmapped_area
returns nothing.
After this, arch/x86/mm/hugetlbpage.c should only contain:
#ifdef CONFIG_X86_64
bool __init arch_hugetlb_valid_size(unsigned long size)
{
if (size == PMD_SIZE)
return true;
else if (size == PUD_SIZE && boot_cpu_has(X86_FEATURE_GBPAGES))
return true;
else
return false;
}
#ifdef CONFIG_CONTIG_ALLOC
static __init int gigantic_pages_init(void)
{
/* With compaction or CMA we can allocate gigantic pages at runtime */
if (boot_cpu_has(X86_FEATURE_GBPAGES))
hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
return 0;
}
arch_initcall(gigantic_pages_init);
#endif
#endif
so what is going here?
Maybe the series was not properly applied to mm-unstable?
I will have a look.
--
Oscar Salvador
SUSE Labs
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags
2024-07-31 15:08 ` Oscar Salvador
@ 2024-07-31 15:11 ` Oscar Salvador
2024-07-31 20:03 ` Andrew Morton
2024-07-31 15:19 ` Lorenzo Stoakes
1 sibling, 1 reply; 22+ messages in thread
From: Oscar Salvador @ 2024-07-31 15:11 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Andrew Morton, linux-kernel, linux-mm, Peter Xu, Muchun Song,
David Hildenbrand, Donet Tom, Matthew Wilcox, Vlastimil Babka,
Michal Hocko
On Wed, Jul 31, 2024 at 05:08:24PM +0200, Oscar Salvador wrote:
> On Wed, Jul 31, 2024 at 12:02:47PM +0100, Lorenzo Stoakes wrote:
> > On Mon, Jul 29, 2024 at 11:10:15AM GMT, Oscar Salvador wrote:
> > > * Someone wants to read @bytes from a HWPOISON hugetlb @page from @offset.
> > > @@ -1300,7 +1307,6 @@ static const struct file_operations hugetlbfs_file_operations = {
> > > .read_iter = hugetlbfs_read_iter,
> > > .mmap = hugetlbfs_file_mmap,
> > > .fsync = noop_fsync,
> > > - .get_unmapped_area = hugetlb_get_unmapped_area,
> >
> > This is causing a NULL pointer deref error in the mm self-tests,
> > specifically hugepage-shm.
> >
> > This is because in __get_unmapped_area(), you check to see if the file has
> > an f_ops->get_unampped_area() however ('wonderfully'...) the shm stuff
> > wraps it, so this will be shm_get_unmapped_area() which then accesses the
> > underlying hugetlb file and _unconditionally_ calls
> > f_op->get_unmapped_area(), which you just made NULL and... kaboom :)
> >
> > You can't even add null check in to this wrapper as at this point
> > everything assumes that you _can_ get an unmapped area. So yeah, it's kinda
> > broken.
> >
> > This makes me think the whole thing is super-delicate and you probably need
> > to rethink this approach carefully, or least _very carefully_ audit users
> > of this operation.
>
> Thanks for reporting this Lorenzo, highly appreciated.
>
> I will check, but..
>
> > By doing this you are causing an compilation error (at least on my compiler
> > with an x86-64 defconfig-based build):
> >
> > arch/x86/mm/hugetlbpage.c:84:1: error: no previous prototype for
> > ‘hugetlb_get_unmapped_area’ [-Werror=missing-prototypes]
> > 84 | hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
> > | ^~~~~~~~~~~~~~~~~~~~~~~~~
>
> Something is off here.
>
> git grep hugetlb_get_unmapped_area
Heh, of course I saw what is wrong after pressing intro.
Ok, with the entire series applied you should not see this problem as
hugetlb_get_unmapped_area gets totally wiped out, but checking out only
this commit indeed throws an error.
I will see how I can reshufle this.
thanks!
--
Oscar Salvador
SUSE Labs
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags
2024-07-31 15:08 ` Oscar Salvador
2024-07-31 15:11 ` Oscar Salvador
@ 2024-07-31 15:19 ` Lorenzo Stoakes
2024-07-31 16:04 ` Oscar Salvador
1 sibling, 1 reply; 22+ messages in thread
From: Lorenzo Stoakes @ 2024-07-31 15:19 UTC (permalink / raw)
To: Oscar Salvador
Cc: Andrew Morton, linux-kernel, linux-mm, Peter Xu, Muchun Song,
David Hildenbrand, Donet Tom, Matthew Wilcox, Vlastimil Babka,
Michal Hocko
On Wed, Jul 31, 2024 at 05:08:24PM GMT, Oscar Salvador wrote:
> On Wed, Jul 31, 2024 at 12:02:47PM +0100, Lorenzo Stoakes wrote:
> > On Mon, Jul 29, 2024 at 11:10:15AM GMT, Oscar Salvador wrote:
> > > * Someone wants to read @bytes from a HWPOISON hugetlb @page from @offset.
> > > @@ -1300,7 +1307,6 @@ static const struct file_operations hugetlbfs_file_operations = {
> > > .read_iter = hugetlbfs_read_iter,
> > > .mmap = hugetlbfs_file_mmap,
> > > .fsync = noop_fsync,
> > > - .get_unmapped_area = hugetlb_get_unmapped_area,
> >
> > This is causing a NULL pointer deref error in the mm self-tests,
> > specifically hugepage-shm.
> >
> > This is because in __get_unmapped_area(), you check to see if the file has
> > an f_ops->get_unampped_area() however ('wonderfully'...) the shm stuff
> > wraps it, so this will be shm_get_unmapped_area() which then accesses the
> > underlying hugetlb file and _unconditionally_ calls
> > f_op->get_unmapped_area(), which you just made NULL and... kaboom :)
> >
> > You can't even add null check in to this wrapper as at this point
> > everything assumes that you _can_ get an unmapped area. So yeah, it's kinda
> > broken.
> >
> > This makes me think the whole thing is super-delicate and you probably need
> > to rethink this approach carefully, or least _very carefully_ audit users
> > of this operation.
>
> Thanks for reporting this Lorenzo, highly appreciated.
>
No problem :)
> I will check, but..
Yeah this is obviously the priority.
>
> > By doing this you are causing an compilation error (at least on my compiler
> > with an x86-64 defconfig-based build):
> >
> > arch/x86/mm/hugetlbpage.c:84:1: error: no previous prototype for
> > ‘hugetlb_get_unmapped_area’ [-Werror=missing-prototypes]
> > 84 | hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
> > | ^~~~~~~~~~~~~~~~~~~~~~~~~
>
> Something is off here.
>
> git grep hugetlb_get_unmapped_area
>
> returns nothing.
Yeah this is at commit aee8efc95fc2 ("mm: make hugetlb mappings go through
mm_get_unmapped_area_vmflags").
If you:
git checkout aee8efc95fc2
git grep hugetlb_get_unmapped_area
You'll see it.
I'm guessing you remove this in future commits, but the kernel must be able
to build at every revision so we can bisect (I found this issue through a
bisect and had to fix this up to check).
A trivial fix is just to provide the prototype immediately prior to the
function decl, however the more correct solution is probably to do the
removals at the same time.
> After this, arch/x86/mm/hugetlbpage.c should only contain:
>
> #ifdef CONFIG_X86_64
> bool __init arch_hugetlb_valid_size(unsigned long size)
> {
> if (size == PMD_SIZE)
> return true;
> else if (size == PUD_SIZE && boot_cpu_has(X86_FEATURE_GBPAGES))
> return true;
> else
> return false;
> }
>
> #ifdef CONFIG_CONTIG_ALLOC
> static __init int gigantic_pages_init(void)
> {
> /* With compaction or CMA we can allocate gigantic pages at runtime */
> if (boot_cpu_has(X86_FEATURE_GBPAGES))
> hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
> return 0;
> }
> arch_initcall(gigantic_pages_init);
> #endif
> #endif
>
> so what is going here?
> Maybe the series was not properly applied to mm-unstable?
>
> I will have a look.
I see this being removed in commit 631dc86d2f95 ("mm: drop
hugetlb_get_unmapped_area{_*} functions") which comes after aee8efc95fc2,
so basically I think you should squash the two... or at least find a way to
adjust them so this error doesn't arise.
This bit is just a bit of a slightly nitty cleanup to make sure things
build at every commit, the first issue is the really key one, just needs
some tweaking to deal with the frankly bloody horrible SHM stuff... Do not
blame you for missing that one!
Cheers :)
>
>
> --
> Oscar Salvador
> SUSE Labs
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags
2024-07-31 15:19 ` Lorenzo Stoakes
@ 2024-07-31 16:04 ` Oscar Salvador
2024-07-31 16:15 ` Lorenzo Stoakes
0 siblings, 1 reply; 22+ messages in thread
From: Oscar Salvador @ 2024-07-31 16:04 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Andrew Morton, linux-kernel, linux-mm, Peter Xu, Muchun Song,
David Hildenbrand, Donet Tom, Matthew Wilcox, Vlastimil Babka,
Michal Hocko
On Wed, Jul 31, 2024 at 04:19:09PM +0100, Lorenzo Stoakes wrote:
> Yeah this is at commit aee8efc95fc2 ("mm: make hugetlb mappings go through
> mm_get_unmapped_area_vmflags").
>
> If you:
>
> git checkout aee8efc95fc2
> git grep hugetlb_get_unmapped_area
>
> You'll see it.
>
> I'm guessing you remove this in future commits, but the kernel must be able
> to build at every revision so we can bisect (I found this issue through a
> bisect and had to fix this up to check).
>
> A trivial fix is just to provide the prototype immediately prior to the
> function decl, however the more correct solution is probably to do the
> removals at the same time.
Yeah, I just squashed the removal commit and this one.
> This bit is just a bit of a slightly nitty cleanup to make sure things
> build at every commit, the first issue is the really key one, just needs
> some tweaking to deal with the frankly bloody horrible SHM stuff... Do not
> blame you for missing that one!
I did not check closely yet, but are blowing up in:
if (shmem_huge != SHMEM_HUGE_FORCE) {
...
if (file) {
VM_BUG_ON(file->f_op != &shmem_file_operations)
?
--
Oscar Salvador
SUSE Labs
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags
2024-07-31 16:04 ` Oscar Salvador
@ 2024-07-31 16:15 ` Lorenzo Stoakes
2024-08-01 8:14 ` Oscar Salvador
0 siblings, 1 reply; 22+ messages in thread
From: Lorenzo Stoakes @ 2024-07-31 16:15 UTC (permalink / raw)
To: Oscar Salvador
Cc: Andrew Morton, linux-kernel, linux-mm, Peter Xu, Muchun Song,
David Hildenbrand, Donet Tom, Matthew Wilcox, Vlastimil Babka,
Michal Hocko
On Wed, Jul 31, 2024 at 06:04:04PM GMT, Oscar Salvador wrote:
> On Wed, Jul 31, 2024 at 04:19:09PM +0100, Lorenzo Stoakes wrote:
> > Yeah this is at commit aee8efc95fc2 ("mm: make hugetlb mappings go through
> > mm_get_unmapped_area_vmflags").
> >
> > If you:
> >
> > git checkout aee8efc95fc2
> > git grep hugetlb_get_unmapped_area
> >
> > You'll see it.
> >
> > I'm guessing you remove this in future commits, but the kernel must be able
> > to build at every revision so we can bisect (I found this issue through a
> > bisect and had to fix this up to check).
> >
> > A trivial fix is just to provide the prototype immediately prior to the
> > function decl, however the more correct solution is probably to do the
> > removals at the same time.
>
> Yeah, I just squashed the removal commit and this one.
>
> > This bit is just a bit of a slightly nitty cleanup to make sure things
> > build at every commit, the first issue is the really key one, just needs
> > some tweaking to deal with the frankly bloody horrible SHM stuff... Do not
> > blame you for missing that one!
>
> I did not check closely yet, but are blowing up in:
>
> if (shmem_huge != SHMEM_HUGE_FORCE) {
> ...
> if (file) {
> VM_BUG_ON(file->f_op != &shmem_file_operations)
>
> ?
I've not got the vm debug on in my build, so it's blowing up here for me:
static unsigned long shm_get_unmapped_area(struct file *file,
unsigned long addr, unsigned long len, unsigned long pgoff,
unsigned long flags)
{
struct shm_file_data *sfd = shm_file_data(file);
return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len,
pgoff, flags);
}
Notice that that doesn't check whether sfd->file->f_op->get_unmapped_area
is NULL.
So since you remove this from the f_ops, it causes a NULL pointer deref.
In __get_unmapped_area() you have:
if (file) {
if (file->f_op->get_unmapped_area)
get_area = file->f_op->get_unmapped_area;
...
if (get_area) {
addr = get_area(file, addr, len, pgoff, flags);
Now since you are dealing with a shm file that has shm_file_operations
static const struct file_operations shm_file_operations = {
..
.get_unmapped_area = shm_get_unmapped_area,
...
};
Then this get_area() is invoked, which calls shm_get_unmapped_area(), which
calls f_op->get_unmapped_area() on your hugetlbfs_file_operations object
which you just deleted and it's NULL.
This is why you have to be super careful here, there's clearly stuff out
there that assumes that this can't happen, which you need to track down.
A quick grep however _suggests_ this might be the one landmine place. But
you need to find a smart way to deal with this.
>
>
> --
> Oscar Salvador
> SUSE Labs
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags
2024-07-31 15:11 ` Oscar Salvador
@ 2024-07-31 20:03 ` Andrew Morton
0 siblings, 0 replies; 22+ messages in thread
From: Andrew Morton @ 2024-07-31 20:03 UTC (permalink / raw)
To: Oscar Salvador
Cc: Lorenzo Stoakes, linux-kernel, linux-mm, Peter Xu, Muchun Song,
David Hildenbrand, Donet Tom, Matthew Wilcox, Vlastimil Babka,
Michal Hocko
On Wed, 31 Jul 2024 17:11:34 +0200 Oscar Salvador <osalvador@suse.de> wrote:
> > git grep hugetlb_get_unmapped_area
>
> Heh, of course I saw what is wrong after pressing intro.
> Ok, with the entire series applied you should not see this problem as
> hugetlb_get_unmapped_area gets totally wiped out, but checking out only
> this commit indeed throws an error.
>
> I will see how I can reshufle this.
I dropped the v2 series, so reshuffle away.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags
2024-07-31 16:15 ` Lorenzo Stoakes
@ 2024-08-01 8:14 ` Oscar Salvador
2024-08-01 10:11 ` Lorenzo Stoakes
0 siblings, 1 reply; 22+ messages in thread
From: Oscar Salvador @ 2024-08-01 8:14 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Andrew Morton, linux-kernel, linux-mm, Peter Xu, Muchun Song,
David Hildenbrand, Donet Tom, Matthew Wilcox, Vlastimil Babka,
Michal Hocko
On Wed, Jul 31, 2024 at 05:15:41PM +0100, Lorenzo Stoakes wrote:
> I've not got the vm debug on in my build, so it's blowing up here for me:
>
> static unsigned long shm_get_unmapped_area(struct file *file,
> unsigned long addr, unsigned long len, unsigned long pgoff,
> unsigned long flags)
> {
> struct shm_file_data *sfd = shm_file_data(file);
>
> return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len,
> pgoff, flags);
> }
>
> Notice that that doesn't check whether sfd->file->f_op->get_unmapped_area
> is NULL.
I see now, thanks.
> So since you remove this from the f_ops, it causes a NULL pointer deref.
...
> static const struct file_operations shm_file_operations = {
> ..
> .get_unmapped_area = shm_get_unmapped_area,
> ...
> };
>
> Then this get_area() is invoked, which calls shm_get_unmapped_area(), which
> calls f_op->get_unmapped_area() on your hugetlbfs_file_operations object
> which you just deleted and it's NULL.
>
> This is why you have to be super careful here, there's clearly stuff out
> there that assumes that this can't happen, which you need to track down.
>
> A quick grep however _suggests_ this might be the one landmine place. But
> you need to find a smart way to deal with this.
Probably, the most straightforward way to fix this is to instead of
setting .get_unmapped_area to NULL for hugetlbfs_file_operations, would
be to have it re-defined like:
.get_unmapped_area = mm_get_unmapped_area_vmflags
Which is what we call after this patchset.
So no more things have to tweaked.
On a more correct way, __maybe__ have something like:
diff --git a/ipc/shm.c b/ipc/shm.c
index 3e3071252dac..222dca8a3716 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -648,8 +648,11 @@ static unsigned long shm_get_unmapped_area(struct file *file,
{
struct shm_file_data *sfd = shm_file_data(file);
- return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len,
+ if (sfd->file->f_op->get_unmapped_area)
+ return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len,
pgoff, flags);
+
+ return mm_get_unmapped_area_vmflags(sfd->file, addr, len, pgoff, flags);
}
static const struct file_operations shm_file_operations = {
Still unsure about which approach looks more correct though.
--
Oscar Salvador
SUSE Labs
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags
2024-08-01 8:14 ` Oscar Salvador
@ 2024-08-01 10:11 ` Lorenzo Stoakes
0 siblings, 0 replies; 22+ messages in thread
From: Lorenzo Stoakes @ 2024-08-01 10:11 UTC (permalink / raw)
To: Oscar Salvador
Cc: Andrew Morton, linux-kernel, linux-mm, Peter Xu, Muchun Song,
David Hildenbrand, Donet Tom, Matthew Wilcox, Vlastimil Babka,
Michal Hocko
On Thu, Aug 01, 2024 at 10:14:26AM GMT, Oscar Salvador wrote:
> On Wed, Jul 31, 2024 at 05:15:41PM +0100, Lorenzo Stoakes wrote:
> > I've not got the vm debug on in my build, so it's blowing up here for me:
> >
> > static unsigned long shm_get_unmapped_area(struct file *file,
> > unsigned long addr, unsigned long len, unsigned long pgoff,
> > unsigned long flags)
> > {
> > struct shm_file_data *sfd = shm_file_data(file);
> >
> > return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len,
> > pgoff, flags);
> > }
> >
> > Notice that that doesn't check whether sfd->file->f_op->get_unmapped_area
> > is NULL.
>
> I see now, thanks.
>
> > So since you remove this from the f_ops, it causes a NULL pointer deref.
> ...
> > static const struct file_operations shm_file_operations = {
> > ..
> > .get_unmapped_area = shm_get_unmapped_area,
> > ...
> > };
> >
> > Then this get_area() is invoked, which calls shm_get_unmapped_area(), which
> > calls f_op->get_unmapped_area() on your hugetlbfs_file_operations object
> > which you just deleted and it's NULL.
> >
> > This is why you have to be super careful here, there's clearly stuff out
> > there that assumes that this can't happen, which you need to track down.
> >
> > A quick grep however _suggests_ this might be the one landmine place. But
> > you need to find a smart way to deal with this.
>
> Probably, the most straightforward way to fix this is to instead of
> setting .get_unmapped_area to NULL for hugetlbfs_file_operations, would
> be to have it re-defined like:
>
> .get_unmapped_area = mm_get_unmapped_area_vmflags
I prefer this at a glance.
>
> Which is what we call after this patchset.
> So no more things have to tweaked.
>
> On a more correct way, __maybe__ have something like:
>
>
> diff --git a/ipc/shm.c b/ipc/shm.c
> index 3e3071252dac..222dca8a3716 100644
> --- a/ipc/shm.c
> +++ b/ipc/shm.c
> @@ -648,8 +648,11 @@ static unsigned long shm_get_unmapped_area(struct file *file,
> {
> struct shm_file_data *sfd = shm_file_data(file);
>
> - return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len,
> + if (sfd->file->f_op->get_unmapped_area)
> + return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len,
> pgoff, flags);
> +
> + return mm_get_unmapped_area_vmflags(sfd->file, addr, len, pgoff, flags);
> }
>
> static const struct file_operations shm_file_operations = {
>
I hate this to be honest, it's another 'we just have to remember to call an
arbitrary function' situation (why here and not elsewhere?) and
perpetuating the horrible if (hugetlb) { ... } approach to things.
I mean the shm code is _hateful_ anyway, but yeah I really really don't
like this.
I'd quite like us to add a check here for that function being NULL though,
I was mistaken in my previous reply saying we can't do anything here,
actually you can return an error, and so I'd prefer for us to return an
error in that case.
>
> Still unsure about which approach looks more correct though.
I think I've made my point of view clear fwiw at least ;)
>
> --
> Oscar Salvador
> SUSE Labs
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags
2024-07-29 9:10 ` [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags Oscar Salvador
2024-07-31 11:02 ` Lorenzo Stoakes
@ 2024-08-05 21:03 ` kernel test robot
2024-08-11 13:23 ` kernel test robot
2 siblings, 0 replies; 22+ messages in thread
From: kernel test robot @ 2024-08-05 21:03 UTC (permalink / raw)
To: Oscar Salvador, Andrew Morton
Cc: oe-kbuild-all, Linux Memory Management List, linux-kernel,
Peter Xu, Muchun Song, David Hildenbrand, Donet Tom,
Matthew Wilcox, Vlastimil Babka, Michal Hocko, Oscar Salvador
Hi Oscar,
kernel test robot noticed the following build warnings:
[auto build test WARNING on s390/features]
[also build test WARNING on akpm-mm/mm-everything powerpc/next powerpc/fixes deller-parisc/for-next arnd-asm-generic/master linus/master v6.11-rc2 next-20240805]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Oscar-Salvador/mm-mmap-Teach-generic_get_unmapped_area-_topdown-to-handle-hugetlb-mappings/20240729-171449
base: https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git features
patch link: https://lore.kernel.org/r/20240729091018.2152-7-osalvador%40suse.de
patch subject: [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags
config: x86_64-randconfig-012-20240802 (https://download.01.org/0day-ci/archive/20240806/202408060456.yBmmX9hr-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240806/202408060456.yBmmX9hr-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408060456.yBmmX9hr-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> arch/x86/mm/hugetlbpage.c:84:1: warning: no previous prototype for 'hugetlb_get_unmapped_area' [-Wmissing-prototypes]
84 | hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
| ^~~~~~~~~~~~~~~~~~~~~~~~~
vim +/hugetlb_get_unmapped_area +84 arch/x86/mm/hugetlbpage.c
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 82
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 83 unsigned long
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 @84 hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 85 unsigned long len, unsigned long pgoff, unsigned long flags)
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 86 {
39c11e6c05b7fe arch/x86/mm/hugetlbpage.c Andi Kleen 2008-07-23 87 struct hstate *h = hstate_file(file);
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 88 struct mm_struct *mm = current->mm;
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 89 struct vm_area_struct *vma;
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 90
39c11e6c05b7fe arch/x86/mm/hugetlbpage.c Andi Kleen 2008-07-23 91 if (len & ~huge_page_mask(h))
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 92 return -EINVAL;
44b04912fa7248 arch/x86/mm/hugetlbpage.c Kirill A. Shutemov 2017-07-17 93
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 94 if (len > TASK_SIZE)
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 95 return -ENOMEM;
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 96
1e0f25dbf2464d arch/x86/mm/hugetlbpage.c Kirill A. Shutemov 2017-11-15 97 /* No address checking. See comment at mmap_address_hint_valid() */
5a8130f2b186ac arch/i386/mm/hugetlbpage.c Benjamin Herrenschmidt 2007-05-06 98 if (flags & MAP_FIXED) {
a5516438959d90 arch/x86/mm/hugetlbpage.c Andi Kleen 2008-07-23 99 if (prepare_hugepage_range(file, addr, len))
5a8130f2b186ac arch/i386/mm/hugetlbpage.c Benjamin Herrenschmidt 2007-05-06 100 return -EINVAL;
5a8130f2b186ac arch/i386/mm/hugetlbpage.c Benjamin Herrenschmidt 2007-05-06 101 return addr;
5a8130f2b186ac arch/i386/mm/hugetlbpage.c Benjamin Herrenschmidt 2007-05-06 102 }
5a8130f2b186ac arch/i386/mm/hugetlbpage.c Benjamin Herrenschmidt 2007-05-06 103
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 104 if (addr) {
1e0f25dbf2464d arch/x86/mm/hugetlbpage.c Kirill A. Shutemov 2017-11-15 105 addr &= huge_page_mask(h);
1e0f25dbf2464d arch/x86/mm/hugetlbpage.c Kirill A. Shutemov 2017-11-15 106 if (!mmap_address_hint_valid(addr, len))
1e0f25dbf2464d arch/x86/mm/hugetlbpage.c Kirill A. Shutemov 2017-11-15 107 goto get_unmapped_area;
1e0f25dbf2464d arch/x86/mm/hugetlbpage.c Kirill A. Shutemov 2017-11-15 108
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 109 vma = find_vma(mm, addr);
1e0f25dbf2464d arch/x86/mm/hugetlbpage.c Kirill A. Shutemov 2017-11-15 110 if (!vma || addr + len <= vm_start_gap(vma))
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 111 return addr;
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 112 }
1e0f25dbf2464d arch/x86/mm/hugetlbpage.c Kirill A. Shutemov 2017-11-15 113
1e0f25dbf2464d arch/x86/mm/hugetlbpage.c Kirill A. Shutemov 2017-11-15 114 get_unmapped_area:
529ce23a764f25 arch/x86/mm/hugetlbpage.c Rick Edgecombe 2024-03-25 115 if (!test_bit(MMF_TOPDOWN, &mm->flags))
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 116 return hugetlb_get_unmapped_area_bottomup(file, addr, len,
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 117 pgoff, flags);
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 118 else
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 119 return hugetlb_get_unmapped_area_topdown(file, addr, len,
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 120 pgoff, flags);
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 121 }
fd8526ad14c182 arch/x86/mm/hugetlbpage.c Kirill A. Shutemov 2013-11-19 122 #endif /* CONFIG_HUGETLB_PAGE */
^1da177e4c3f41 arch/i386/mm/hugetlbpage.c Linus Torvalds 2005-04-16 123
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags
2024-07-29 9:10 ` [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags Oscar Salvador
2024-07-31 11:02 ` Lorenzo Stoakes
2024-08-05 21:03 ` kernel test robot
@ 2024-08-11 13:23 ` kernel test robot
2 siblings, 0 replies; 22+ messages in thread
From: kernel test robot @ 2024-08-11 13:23 UTC (permalink / raw)
To: Oscar Salvador
Cc: oe-lkp, lkp, linux-mm, Andrew Morton, linux-kernel, Peter Xu,
Muchun Song, David Hildenbrand, Donet Tom, Matthew Wilcox,
Vlastimil Babka, Michal Hocko, Oscar Salvador, oliver.sang
Hello,
kernel test robot noticed "BUG:kernel_NULL_pointer_dereference,address" on:
commit: 535f03fb3da2b7b2fe5089ee5d1a291774a298e3 ("[PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags")
url: https://github.com/intel-lab-lkp/linux/commits/Oscar-Salvador/mm-mmap-Teach-generic_get_unmapped_area-_topdown-to-handle-hugetlb-mappings/20240729-171449
base: https://git.kernel.org/cgit/linux/kernel/git/s390/linux.git features
patch link: https://lore.kernel.org/all/20240729091018.2152-7-osalvador@suse.de/
patch subject: [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags
in testcase: trinity
version: trinity-static-x86_64-x86_64-1c734c75-1_2020-01-06
with following parameters:
runtime: 600s
compiler: gcc-12
test machine: qemu-system-x86_64 -enable-kvm -cpu SandyBridge -smp 2 -m 16G
(please refer to attached dmesg/kmsg for entire log/backtrace)
+---------------------------------------------+------------+------------+
| | ec3b0c2006 | 535f03fb3d |
+---------------------------------------------+------------+------------+
| boot_successes | 6 | 0 |
| boot_failures | 0 | 9 |
| BUG:kernel_NULL_pointer_dereference,address | 0 | 9 |
| Oops | 0 | 9 |
| Kernel_panic-not_syncing:Fatal_exception | 0 | 9 |
+---------------------------------------------+------------+------------+
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang@intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202408112137.e013a399-oliver.sang@intel.com
[ 38.976763][ T448] BUG: kernel NULL pointer dereference, address: 0000000000000000
[ 38.977518][ T448] #PF: supervisor instruction fetch in kernel mode
[ 38.977981][ T448] #PF: error_code(0x0010) - not-present page
[ 38.978411][ T448] PGD 800000012c3cc067 P4D 800000012c3cc067 PUD 12c3cd067 PMD 0
[ 38.978949][ T448] Oops: Oops: 0010 [#1] PREEMPT SMP PTI
[ 38.979343][ T448] CPU: 1 UID: 0 PID: 448 Comm: trinity Not tainted 6.10.0-12075-g535f03fb3da2 #1
[ 38.979990][ T448] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
[ 38.980725][ T448] RIP: 0010:0x0
[ 38.980993][ T448] Code: Unable to access opcode bytes at 0xffffffffffffffd6.
Code starting with the faulting instruction
===========================================
[ 38.981530][ T448] RSP: 0018:ffffc9000108fb58 EFLAGS: 00010246
[ 38.981977][ T448] RAX: 0000000000000000 RBX: 0000000000200000 RCX: 0000000000000000
[ 38.982550][ T448] RDX: 0000000000200000 RSI: 0000000000000000 RDI: ffff88812ce36600
[ 38.983124][ T448] RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000073
[ 38.983692][ T448] R10: fffffffffffffff4 R11: 0000000000000000 R12: ffff888319920000
[ 38.984258][ T448] R13: 0000000000000003 R14: ffff88831996fe00 R15: ffff888114c42000
[ 38.984826][ T448] FS: 000000000109a880(0000) GS:ffff88842fc00000(0000) knlGS:0000000000000000
[ 38.985465][ T448] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 38.985942][ T448] CR2: ffffffffffffffd6 CR3: 0000000114c52000 CR4: 00000000000406b0
[ 38.986515][ T448] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 38.988705][ T448] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[ 38.989257][ T448] Call Trace:
[ 38.989493][ T448] <TASK>
[ 38.989709][ T448] ? __die (arch/x86/kernel/dumpstack.c:421 arch/x86/kernel/dumpstack.c:434)
[ 38.990001][ T448] ? page_fault_oops (arch/x86/mm/fault.c:715)
[ 38.990343][ T448] ? exc_page_fault (arch/x86/include/asm/irqflags.h:26 arch/x86/include/asm/irqflags.h:87 arch/x86/include/asm/irqflags.h:147 arch/x86/mm/fault.c:1489 arch/x86/mm/fault.c:1539)
[ 38.990680][ T448] ? asm_exc_page_fault (arch/x86/include/asm/idtentry.h:623)
[ 38.991046][ T448] __get_unmapped_area (mm/mmap.c:1932)
[ 38.991458][ T448] ? find_held_lock (kernel/locking/lockdep.c:5249)
[ 38.991796][ T448] ? do_shmat (include/linux/mmap_lock.h:122 ipc/shm.c:1643)
[ 38.992098][ T448] do_mmap (mm/mmap.c:1325)
[ 38.992394][ T448] ? do_shmat (include/linux/mmap_lock.h:122 ipc/shm.c:1643)
[ 38.992712][ T448] do_shmat (ipc/shm.c:1658)
[ 38.993016][ T448] __x64_sys_shmat (ipc/shm.c:1694 ipc/shm.c:1688 ipc/shm.c:1688)
[ 38.993337][ T448] do_syscall_64 (arch/x86/entry/common.c:52 arch/x86/entry/common.c:83)
[ 38.993670][ T448] ? lock_acquire (kernel/locking/lockdep.c:466 kernel/locking/lockdep.c:5761 kernel/locking/lockdep.c:5724)
[ 38.994000][ T448] ? kvm_sched_clock_read (arch/x86/kernel/kvmclock.c:91)
[ 38.994366][ T448] ? local_clock_noinstr (kernel/sched/clock.c:301)
[ 38.994720][ T448] ? local_clock (arch/x86/include/asm/preempt.h:94 kernel/sched/clock.c:316)
[ 38.995061][ T448] ? __lock_release+0x11a/0x290
[ 38.995511][ T448] ? lock_release (kernel/locking/lockdep.c:466 kernel/locking/lockdep.c:5782)
[ 38.995833][ T448] ? syscall_exit_to_user_mode_prepare (kernel/entry/common.c:199 (discriminator 1))
[ 38.996289][ T448] ? lockdep_hardirqs_on_prepare (kernel/locking/lockdep.c:4299 kernel/locking/lockdep.c:4358)
[ 38.996715][ T448] ? syscall_exit_to_user_mode (arch/x86/include/asm/processor.h:702 arch/x86/include/asm/entry-common.h:91 include/linux/entry-common.h:364 kernel/entry/common.c:220)
[ 38.997105][ T448] ? do_syscall_64 (arch/x86/entry/common.c:102)
[ 38.997436][ T448] ? do_shmat (ipc/shm.c:1680)
[ 38.997749][ T448] ? syscall_exit_to_user_mode_prepare (kernel/entry/common.c:199 (discriminator 1))
[ 38.998189][ T448] ? lockdep_hardirqs_on_prepare (kernel/locking/lockdep.c:4299 kernel/locking/lockdep.c:4358)
[ 38.998606][ T448] ? syscall_exit_to_user_mode (arch/x86/include/asm/processor.h:702 arch/x86/include/asm/entry-common.h:91 include/linux/entry-common.h:364 kernel/entry/common.c:220)
[ 39.000911][ T448] ? do_syscall_64 (arch/x86/entry/common.c:102)
[ 39.001243][ T448] ? do_syscall_64 (arch/x86/entry/common.c:102)
[ 39.001574][ T448] ? syscall_exit_to_user_mode_prepare (kernel/entry/common.c:199 (discriminator 1))
[ 39.002016][ T448] ? lockdep_hardirqs_on_prepare (kernel/locking/lockdep.c:4299 kernel/locking/lockdep.c:4358)
[ 39.002445][ T448] ? syscall_exit_to_user_mode (arch/x86/include/asm/processor.h:702 arch/x86/include/asm/entry-common.h:91 include/linux/entry-common.h:364 kernel/entry/common.c:220)
[ 39.002840][ T448] ? do_syscall_64 (arch/x86/entry/common.c:102)
[ 39.003201][ T448] ? syscall_exit_to_user_mode_prepare (kernel/entry/common.c:199 (discriminator 1))
[ 39.003644][ T448] ? lockdep_hardirqs_on_prepare (kernel/locking/lockdep.c:4299 kernel/locking/lockdep.c:4358)
[ 39.004049][ T448] ? syscall_exit_to_user_mode (arch/x86/include/asm/processor.h:702 arch/x86/include/asm/entry-common.h:91 include/linux/entry-common.h:364 kernel/entry/common.c:220)
[ 39.004443][ T448] ? do_syscall_64 (arch/x86/entry/common.c:102)
[ 39.004767][ T448] ? do_syscall_64 (arch/x86/entry/common.c:102)
[ 39.005087][ T448] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
[ 39.005501][ T448] RIP: 0033:0x4648b7
[ 39.005775][ T448] Code: 00 66 90 b8 29 00 00 00 0f 05 48 3d 01 f0 ff ff 0f 83 5d 46 00 00 c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 b8 1e 00 00 00 0f 05 <48> 3d 01 f0 ff ff 0f 83 3d 46 00 00 c3 66 2e 0f 1f 84 00 00 00 00
All code
========
0: 00 66 90 add %ah,-0x70(%rsi)
3: b8 29 00 00 00 mov $0x29,%eax
8: 0f 05 syscall
a: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax
10: 0f 83 5d 46 00 00 jae 0x4673
16: c3 ret
17: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1)
1e: 00 00 00
21: 66 90 xchg %ax,%ax
23: b8 1e 00 00 00 mov $0x1e,%eax
28: 0f 05 syscall
2a:* 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax <-- trapping instruction
30: 0f 83 3d 46 00 00 jae 0x4673
36: c3 ret
37: 66 data16
38: 2e cs
39: 0f .byte 0xf
3a: 1f (bad)
3b: 84 00 test %al,(%rax)
3d: 00 00 add %al,(%rax)
...
Code starting with the faulting instruction
===========================================
0: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax
6: 0f 83 3d 46 00 00 jae 0x4649
c: c3 ret
d: 66 data16
e: 2e cs
f: 0f .byte 0xf
10: 1f (bad)
11: 84 00 test %al,(%rax)
13: 00 00 add %al,(%rax)
...
[ 39.007086][ T448] RSP: 002b:00007ffe45cb7dc8 EFLAGS: 00000246 ORIG_RAX: 000000000000001e
[ 39.007608][ T448] RAX: ffffffffffffffda RBX: 0000000000007000 RCX: 00000000004648b7
[ 39.008147][ T448] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000002
[ 39.008683][ T448] RBP: 00007ffe45cb7df0 R08: 00000000010975f0 R09: 000000000109a880
[ 39.009185][ T448] R10: ffffffffffffffff R11: 0000000000000246 R12: 0000000000001000
[ 39.009547][ T448] R13: 0000000000000002 R14: 00000000010b0e20 R15: 0000000054001fb0
[ 39.009912][ T448] </TASK>
[ 39.010094][ T448] Modules linked in: polyval_clmulni polyval_generic ghash_clmulni_intel intel_agp intel_gtt
[ 39.010801][ T448] CR2: 0000000000000000
[ 39.011091][ T448] ---[ end trace 0000000000000000 ]---
[ 39.011399][ T448] RIP: 0010:0x0
[ 39.011649][ T448] Code: Unable to access opcode bytes at 0xffffffffffffffd6.
Code starting with the faulting instruction
===========================================
The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20240811/202408112137.e013a399-oliver.sang@intel.com
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2024-08-11 13:24 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-07-29 9:10 [PATCH v2 0/9] Unify hugetlb into arch_get_unmapped_area functions Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 1/9] mm/mmap: Teach generic_get_unmapped_area{_topdown} to handle hugetlb mappings Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 2/9] arch/s390: Teach arch_get_unmapped_area{_topdown} " Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 3/9] arch/x86: Teach arch_get_unmapped_area_vmflags " Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 4/9] arch/sparc: Teach arch_get_unmapped_area{_topdown} " Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 5/9] arch/powerpc: Teach book3s64 " Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 6/9] mm: Make hugetlb mappings go through mm_get_unmapped_area_vmflags Oscar Salvador
2024-07-31 11:02 ` Lorenzo Stoakes
2024-07-31 15:08 ` Oscar Salvador
2024-07-31 15:11 ` Oscar Salvador
2024-07-31 20:03 ` Andrew Morton
2024-07-31 15:19 ` Lorenzo Stoakes
2024-07-31 16:04 ` Oscar Salvador
2024-07-31 16:15 ` Lorenzo Stoakes
2024-08-01 8:14 ` Oscar Salvador
2024-08-01 10:11 ` Lorenzo Stoakes
2024-08-05 21:03 ` kernel test robot
2024-08-11 13:23 ` kernel test robot
2024-07-29 9:10 ` [PATCH v2 7/9] mm: Drop hugetlb_get_unmapped_area{_*} functions Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 8/9] arch/s390: Clean up hugetlb definitions Oscar Salvador
2024-07-29 9:10 ` [PATCH v2 9/9] mm: Consolidate common checks in hugetlb_mmap_check_and_align Oscar Salvador
2024-07-30 9:59 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox