mirror of
https://github.com/lkl/linux.git
synced 2025-12-19 16:13:19 +09:00
mm/vmalloc: hugepage vmalloc mappings
Support huge page vmalloc mappings. Config option HAVE_ARCH_HUGE_VMALLOC enables support on architectures that define HAVE_ARCH_HUGE_VMAP and supports PMD sized vmap mappings. vmalloc will attempt to allocate PMD-sized pages if allocating PMD size or larger, and fall back to small pages if that was unsuccessful. Architectures must ensure that any arch specific vmalloc allocations that require PAGE_SIZE mappings (e.g., module allocations vs strict module rwx) use the VM_NOHUGE flag to inhibit larger mappings. This can result in more internal fragmentation and memory overhead for a given allocation, an option nohugevmalloc is added to disable at boot. [colin.king@canonical.com: fix read of uninitialized pointer area] Link: https://lkml.kernel.org/r/20210318155955.18220-1-colin.king@canonical.com Link: https://lkml.kernel.org/r/20210317062402.533919-14-npiggin@gmail.com Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Ding Tianhong <dingtianhong@huawei.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Miaohe Lin <linmiaohe@huawei.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Russell King <linux@armlinux.org.uk> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Uladzislau Rezki (Sony) <urezki@gmail.com> Cc: Will Deacon <will@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
committed by
Linus Torvalds
parent
5d87510de1
commit
121e6f3258
@@ -26,6 +26,7 @@ struct notifier_block; /* in notifier.h */
|
||||
#define VM_KASAN 0x00000080 /* has allocated kasan shadow memory */
|
||||
#define VM_FLUSH_RESET_PERMS 0x00000100 /* reset direct map and flush TLB on unmap, can't be freed in atomic context */
|
||||
#define VM_MAP_PUT_PAGES 0x00000200 /* put pages and free array in vfree */
|
||||
#define VM_NO_HUGE_VMAP 0x00000400 /* force PAGE_SIZE pte mapping */
|
||||
|
||||
/*
|
||||
* VM_KASAN is used slighly differently depending on CONFIG_KASAN_VMALLOC.
|
||||
@@ -54,6 +55,9 @@ struct vm_struct {
|
||||
unsigned long size;
|
||||
unsigned long flags;
|
||||
struct page **pages;
|
||||
#ifdef CONFIG_HAVE_ARCH_HUGE_VMALLOC
|
||||
unsigned int page_order;
|
||||
#endif
|
||||
unsigned int nr_pages;
|
||||
phys_addr_t phys_addr;
|
||||
const void *caller;
|
||||
@@ -188,6 +192,22 @@ void free_vm_area(struct vm_struct *area);
|
||||
extern struct vm_struct *remove_vm_area(const void *addr);
|
||||
extern struct vm_struct *find_vm_area(const void *addr);
|
||||
|
||||
static inline bool is_vm_area_hugepages(const void *addr)
|
||||
{
|
||||
/*
|
||||
* This may not 100% tell if the area is mapped with > PAGE_SIZE
|
||||
* page table entries, if for some reason the architecture indicates
|
||||
* larger sizes are available but decides not to use them, nothing
|
||||
* prevents that. This only indicates the size of the physical page
|
||||
* allocated in the vmalloc layer.
|
||||
*/
|
||||
#ifdef CONFIG_HAVE_ARCH_HUGE_VMALLOC
|
||||
return find_vm_area(addr)->page_order > 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
int vmap_range(unsigned long addr, unsigned long end,
|
||||
phys_addr_t phys_addr, pgprot_t prot,
|
||||
@@ -205,6 +225,7 @@ static inline void set_vm_flush_reset_perms(void *addr)
|
||||
if (vm)
|
||||
vm->flags |= VM_FLUSH_RESET_PERMS;
|
||||
}
|
||||
|
||||
#else
|
||||
static inline int
|
||||
map_kernel_range_noflush(unsigned long start, unsigned long size,
|
||||
|
||||
Reference in New Issue
Block a user