mm: move vma_(kernel|mmu)_pagesize() out of hugetlb.c
Subsystems (7)
David Hildenbrand (Arm)
maintainerv2 cover mm: move vma_(kernel|mmu)_pagesize() out of hugetlb.c
Looking into vma_(kernel|mmu)_pagesize(), I realized that there is one scenario where DAX would not do the right thing when the kernel is not compiled with hugetlb support.
Without hugetlb support, vma_(kernel|mmu)_pagesize() will always return PAGE_SIZE instead of using the ->pagesize() result provided by dax-device code.
Fix that by moving vma_kernel_pagesize() to core MM code, where it belongs. I don't think this is stable material, but am not 100% sure.
Also, move vma_mmu_pagesize() while at it. Remove the unnecessary hugetlb.h inclusion from KVM code.
Cross-compiled heavily.
v1 -> v2:
* Fixup VMA test in patch #2
* Actually CC all people listed below on all patches.
David Hildenbrand (Arm) (4):
mm: move vma_kernel_pagesize() from hugetlb to mm.h
mm: move vma_mmu_pagesize() from hugetlb to vma.c
KVM: remove hugetlb.h inclusion
KVM: PPC: remove hugetlb.h inclusion
arch/powerpc/kvm/book3s_hv.c | 1 - include/linux/hugetlb.h | 14 -------------- include/linux/mm.h | 22 ++++++++++++++++++++++ mm/hugetlb.c | 28 ---------------------------- mm/vma.c | 21 +++++++++++++++++++++ tools/testing/vma/include/custom.h | 5 +++++ virt/kvm/kvm_main.c | 1 - 7 files changed, 48 insertions(+), 44 deletions(-)
base-commit: f75825cdfc4c5477cffcfd2cafa4e5ce5aa67f13
Signature · 1 line
2.43.0
David Hildenbrand (Arm)
maintainerPATCH v2 1/4 mm: move vma_kernel_pagesize() from hugetlb to mm.h
In the past, only hugetlb had special "vma_kernel_pagesize()" requirements, so it provided its own implementation.
In commit 05ea88608d4e ("mm, hugetlbfs: introduce ->pagesize() to vm_operations_struct") we generalized that approach by providing a vm_ops->pagesize() callback to be used by device-dax.
Once device-dax started using that callback in commit c1d53b92b95c ("device-dax: implement ->pagesize() for smaps to report MMUPageSize") it was missed that CONFIG_DEV_DAX does not depend on hugetlb support.
So building a kernel with CONFIG_DEV_DAX but without CONFIG_HUGETLBFS would not pick up that value.
Fix it by moving vma_kernel_pagesize() to mm.h, providing only a single implementation. While at it, improve the kerneldoc a bit.
Ideally, we'd move vma_mmu_pagesize() as well to the header. However, its __weak symbol might be overwritten by a PPC variant in hugetlb code. So let's leave it in there for now, as it really only matters for some hugetlb oddities.
This was found by code inspection.
--- include/linux/hugetlb.h | 7 ------- include/linux/mm.h | 20 ++++++++++++++++++++ mm/hugetlb.c | 17 ----------------- 3 files changed, 20 insertions(+), 24 deletions(-)
include/linux/hugetlb.h +0 -7
@@ -777,8 +777,6 @@ static inline unsigned long huge_page_size(const struct hstate *h)return (unsigned long )PAGE_SIZE << h->order; } -extern unsigned long vma_kernel_pagesize (struct vm_area_struct *vma); -extern unsigned long vma_mmu_pagesize (struct vm_area_struct *vma);static inline unsigned long huge_page_mask (struct hstate *h)
@@ -1177,11 +1175,6 @@ static inline unsigned long huge_page_mask(struct hstate *h)return PAGE_MASK ; } -static inline unsigned long vma_kernel_pagesize (struct vm_area_struct *vma) -{ -return PAGE_SIZE ; -} -static inline unsigned long vma_mmu_pagesize (struct vm_area_struct *vma) {return PAGE_SIZE ;
include/linux/mm.h +20 -0
@@ -1307,6 +1307,26 @@ static inline bool vma_is_shared_maywrite(const struct vm_area_struct *vma)return is_shared_maywrite (&vma->flags); } +/** +* vma_kernel_pagesize - Default page size granularity for this VMA. +* @vma: The user mapping. +* +* The kernel page size specifies in which granularity VMA modifications +* can be performed. Folios in this VMA will be aligned to, and at least +* the size of the number of bytes returned by this function. +* +* The default kernel page size is not affected by Transparent Huge Pages +* being in effect. +* +* Return: The default page size granularity for this VMA. +*/ +static inline unsigned long vma_kernel_pagesize (struct vm_area_struct *vma) +{ +if (unlikely (vma->vm_ops && vma->vm_ops->pagesize)) +return vma->vm_ops->pagesize (vma); +return PAGE_SIZE ; +} +static inline struct vm_area_struct *vma_find (struct vma_iterator *vmi,unsigned long max) {
mm/hugetlb.c +0 -17
@@ -1017,23 +1017,6 @@ static pgoff_t vma_hugecache_offset(struct hstate *h, (vma->vm_pgoff >>huge_page_order (h)); } -/** -* vma_kernel_pagesize - Page size granularity for this VMA. -* @vma: The user mapping. -* -* Folios in this VMA will be aligned to, and at least the size of the -* number of bytes returned by this function. -* -* Return: The default size of the folios allocated when backing a VMA. -*/ -unsigned long vma_kernel_pagesize (struct vm_area_struct *vma) -{ -if (vma->vm_ops && vma->vm_ops->pagesize) -return vma->vm_ops->pagesize (vma); -return PAGE_SIZE ; -} -EXPORT_SYMBOL_GPL (vma_kernel_pagesize); -/* * Return the page size being used by the MMU to back a VMA. In the majority * of cases, the page size used by the kernel matches the MMU size. On
Signature · 1 line
2.43.0
David Hildenbrand (Arm)
maintainerPATCH v2 2/4 mm: move vma_mmu_pagesize() from hugetlb to vma.c
In reply to David Hildenbrand (Arm)vma_mmu_pagesize() is also queried on non-hugetlb VMAs and does not really belong into hugetlb.c.
PPC64 provides a custom overwrite with CONFIG_HUGETLB_PAGE, see arch/powerpc/mm/book3s64/slice.c, so we cannot easily make this a static inline function.
So let's move it to vma.c and add some proper kerneldoc.
To make vma tests happy, add a simple vma_kernel_pagesize() stub in tools/testing/vma/include/custom.h.
--- include/linux/hugetlb.h | 7 ------- include/linux/mm.h | 2 ++ mm/hugetlb.c | 11 ----------- mm/vma.c | 21 +++++++++++++++++++++ tools/testing/vma/include/custom.h | 5 +++++ 5 files changed, 28 insertions(+), 18 deletions(-)
include/linux/hugetlb.h +0 -7
@@ -777,8 +777,6 @@ static inline unsigned long huge_page_size(const struct hstate *h)return (unsigned long )PAGE_SIZE << h->order; } -extern unsigned long vma_mmu_pagesize (struct vm_area_struct *vma); -static inline unsigned long huge_page_mask (struct hstate *h) {return h->mask;
@@ -1175,11 +1173,6 @@ static inline unsigned long huge_page_mask(struct hstate *h)return PAGE_MASK ; } -static inline unsigned long vma_mmu_pagesize (struct vm_area_struct *vma) -{ -return PAGE_SIZE ; -} -static inline unsigned int huge_page_order (struct hstate *h) {return 0 ;
include/linux/mm.h +2 -0
@@ -1327,6 +1327,8 @@ static inline unsigned long vma_kernel_pagesize(struct vm_area_struct *vma)return PAGE_SIZE ; } +unsigned long vma_mmu_pagesize (struct vm_area_struct *vma); +static inline struct vm_area_struct *vma_find (struct vma_iterator *vmi,unsigned long max) {
mm/hugetlb.c +0 -11
@@ -1017,17 +1017,6 @@ static pgoff_t vma_hugecache_offset(struct hstate *h, (vma->vm_pgoff >>huge_page_order (h)); } -/* -* Return the page size being used by the MMU to back a VMA. In the majority -* of cases, the page size used by the kernel matches the MMU size. On -* architectures where it differs, an architecture-specific 'strong' -* version of this symbol is required. -*/ -__weak unsigned long vma_mmu_pagesize (struct vm_area_struct *vma) -{ -return vma_kernel_pagesize (vma); -} -/* * Flags for MAP_PRIVATE reservations. These are stored in the bottom * bits of the reservation map pointer, which are always clear due to
mm/vma.c +21 -0
@@ -3300,3 +3300,24 @@ int insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma)return 0 ; } + +/** +* vma_mmu_pagesize - Default MMU page size granularity for this VMA. +* @vma: The user mapping. +* +* In the common case, the default page size used by the MMU matches the +* default page size used by the kernel (see vma_kernel_pagesize()). On +* architectures where it differs, an architecture-specific 'strong' version +* of this symbol is required. +* +* The default MMU page size is not affected by Transparent Huge Pages +* being in effect, or any usage of larger MMU page sizes (either through +* architectural huge-page mappings or other explicit/implicit coalescing of +* virtual ranges performed by the MMU). +* +* Return: The default MMU page size granularity for this VMA. +*/ +__weak unsigned long vma_mmu_pagesize (struct vm_area_struct *vma) +{ +return vma_kernel_pagesize (vma); +}
tools/testing/vma/include/custom.h +5 -0
@@ -117,3 +117,8 @@ static inline vma_flags_t __mk_vma_flags(size_t count, const vma_flag_t *bits)vma_flag_set (&flags, bits[i]);return flags; } + +static inline unsigned long vma_kernel_pagesize (struct vm_area_struct *vma) +{ +return PAGE_SIZE ; +}
Signature · 1 line
2.43.0
David Hildenbrand (Arm)
maintainerPATCH v2 3/4 KVM: remove hugetlb.h inclusion
In reply to David Hildenbrand (Arm)hugetlb.h is no longer required now that we moved vma_kernel_pagesize() to mm.h.
--- virt/kvm/kvm_main.c | 1 - 1 file changed, 1 deletion(-)
virt/kvm/kvm_main.c +0 -1
@@ -41,7 +41,6 @@#include <linux/spinlock.h> #include <linux/compat.h> #include <linux/srcu.h> -#include <linux/hugetlb.h> #include <linux/slab.h> #include <linux/sort.h> #include <linux/bsearch.h>
Signature · 1 line
2.43.0
David Hildenbrand (Arm)
maintainerPATCH v2 4/4 KVM: PPC: remove hugetlb.h inclusion
In reply to David Hildenbrand (Arm)hugetlb.h is no longer required now that we moved vma_kernel_pagesize() to mm.h.
--- arch/powerpc/kvm/book3s_hv.c | 1 - 1 file changed, 1 deletion(-)
arch/powerpc/kvm/book3s_hv.c +0 -1
@@ -36,7 +36,6 @@#include <linux/gfp.h> #include <linux/vmalloc.h> #include <linux/highmem.h> -#include <linux/hugetlb.h> #include <linux/kvm_irqfd.h> #include <linux/irqbypass.h> #include <linux/module.h>
Signature · 1 line
2.43.0
Re: [PATCH v2 4/4] KVM: PPC: remove hugetlb.h inclusion
Quoted 8 lines · David Hildenbrand (Arm)
hugetlb.his no longer required now that we movedvma_kernel_pagesize()tomm.h.Reviewed-by Lorenzo Stoakes (Oracle) <[email protected]>Signed-off-by David Hildenbrand (Arm) <[email protected]>--- arch/powerpc/kvm/book3s_hv.c | 1 -
Make sense to me. Please feel free to add:
Quoted 16 lines
1 file changed, 1 deletion(-)arch/powerpc/kvm/book3s_hv.c +0
-1@@ -36,7 +36,6 @@#include <linux/gfp.h> #include <linux/vmalloc.h> #include <linux/highmem.h> -#include <linux/hugetlb.h> #include <linux/kvm_irqfd.h> #include <linux/irqbypass.h> #include <linux/module.h> Signature · 1 line
2.43.0