The patch titled Subject: mm: distinguish VMalloc pages has been added to the -mm tree. Its filename is mm-distinguish-vmalloc-pages.patch This patch should soon appear at http://ozlabs.org/~akpm/mmots/broken-out/mm-distinguish-vmalloc-pages.patch and later at http://ozlabs.org/~akpm/mmotm/broken-out/mm-distinguish-vmalloc-pages.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next and is updated there every 3-4 working days ------------------------------------------------------ From: Matthew Wilcox <mawilcox@xxxxxxxxxxxxx> Subject: mm: distinguish VMalloc pages For diagnosing various performance and memory-leak problems, it is helpful to be able to distinguish pages which are in use as VMalloc pages. Unfortunately, we cannot use the page_type field in struct page, as this is in use for mapcount by some drivers which map vmalloced pages to userspace. Use a special page->mapping value to distinguish VMalloc pages from other kinds of pages. Also record a pointer to the vm_struct and the offset within the area in struct page to help reconstruct exactly what this page is being used for. Link: http://lkml.kernel.org/r/20180518194519.3820-18-willy@xxxxxxxxxxxxx Signed-off-by: Matthew Wilcox <mawilcox@xxxxxxxxxxxxx> Cc: Christoph Lameter <cl@xxxxxxxxx> Cc: Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx> Cc: Jérôme Glisse <jglisse@xxxxxxxxxx> Cc: "Kirill A . Shutemov" <kirill.shutemov@xxxxxxxxxxxxxxx> Cc: Lai Jiangshan <jiangshanlai@xxxxxxxxx> Cc: Martin Schwidefsky <schwidefsky@xxxxxxxxxx> Cc: Pekka Enberg <penberg@xxxxxxxxxx> Cc: Randy Dunlap <rdunlap@xxxxxxxxxxxxx> Cc: Vlastimil Babka <vbabka@xxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- fs/proc/page.c | 2 + include/linux/mm_types.h | 5 ++++ include/linux/page-flags.h | 25 +++++++++++++++++++++++ include/uapi/linux/kernel-page-flags.h | 1 mm/vmalloc.c | 5 +++- tools/vm/page-types.c | 1 6 files changed, 38 insertions(+), 1 deletion(-) diff -puN fs/proc/page.c~mm-distinguish-vmalloc-pages fs/proc/page.c --- a/fs/proc/page.c~mm-distinguish-vmalloc-pages +++ a/fs/proc/page.c @@ -156,6 +156,8 @@ u64 stable_page_flags(struct page *page) u |= 1 << KPF_BALLOON; if (PageTable(page)) u |= 1 << KPF_PGTABLE; + if (PageVMalloc(page)) + u |= 1 << KPF_VMALLOC; if (page_is_idle(page)) u |= 1 << KPF_IDLE; diff -puN include/linux/mm_types.h~mm-distinguish-vmalloc-pages include/linux/mm_types.h --- a/include/linux/mm_types.h~mm-distinguish-vmalloc-pages +++ a/include/linux/mm_types.h @@ -146,6 +146,11 @@ struct page { spinlock_t ptl; #endif }; + struct { /* VMalloc pages */ + struct vm_struct *vm_area; + unsigned long vm_offset; + unsigned long _vm_id; /* MAPPING_VMalloc */ + }; struct { /* ZONE_DEVICE pages */ /** @pgmap: Points to the hosting device page map. */ struct dev_pagemap *pgmap; diff -puN include/linux/page-flags.h~mm-distinguish-vmalloc-pages include/linux/page-flags.h --- a/include/linux/page-flags.h~mm-distinguish-vmalloc-pages +++ a/include/linux/page-flags.h @@ -699,6 +699,31 @@ PAGE_TYPE_OPS(Kmemcg, kmemcg) */ PAGE_TYPE_OPS(Table, table) +/* + * vmalloc pages may be mapped to userspace, so we need some other way + * to distinguish them from other kinds of pages. Use page->mapping + * for this purpose. Values below 0x1000 cannot be real pointers. + */ +#define MAPPING_VMalloc (void *)0x440 + +#define PAGE_MAPPING_OPS(name) \ +static __always_inline int Page##name(struct page *page) \ +{ \ + return page->mapping == MAPPING_##name; \ +} \ +static __always_inline void __SetPage##name(struct page *page) \ +{ \ + VM_BUG_ON_PAGE(page->mapping != NULL, page); \ + page->mapping = MAPPING_##name; \ +} \ +static __always_inline void __ClearPage##name(struct page *page) \ +{ \ + VM_BUG_ON_PAGE(page->mapping != MAPPING_##name, page); \ + page->mapping = NULL; \ +} + +PAGE_MAPPING_OPS(VMalloc) + extern bool is_free_buddy_page(struct page *page); __PAGEFLAG(Isolated, isolated, PF_ANY); diff -puN include/uapi/linux/kernel-page-flags.h~mm-distinguish-vmalloc-pages include/uapi/linux/kernel-page-flags.h --- a/include/uapi/linux/kernel-page-flags.h~mm-distinguish-vmalloc-pages +++ a/include/uapi/linux/kernel-page-flags.h @@ -36,5 +36,6 @@ #define KPF_ZERO_PAGE 24 #define KPF_IDLE 25 #define KPF_PGTABLE 26 +#define KPF_VMALLOC 27 #endif /* _UAPILINUX_KERNEL_PAGE_FLAGS_H */ diff -puN mm/vmalloc.c~mm-distinguish-vmalloc-pages mm/vmalloc.c --- a/mm/vmalloc.c~mm-distinguish-vmalloc-pages +++ a/mm/vmalloc.c @@ -1522,7 +1522,7 @@ static void __vunmap(const void *addr, i for (i = 0; i < area->nr_pages; i++) { struct page *page = area->pages[i]; - BUG_ON(!page); + __ClearPageVMalloc(page); __free_pages(page, 0); } @@ -1692,6 +1692,9 @@ static void *__vmalloc_area_node(struct area->nr_pages = i; goto fail; } + __SetPageVMalloc(page); + page->vm_area = area; + page->vm_offset = i; area->pages[i] = page; if (gfpflags_allow_blocking(gfp_mask|highmem_mask)) cond_resched(); diff -puN tools/vm/page-types.c~mm-distinguish-vmalloc-pages tools/vm/page-types.c --- a/tools/vm/page-types.c~mm-distinguish-vmalloc-pages +++ a/tools/vm/page-types.c @@ -132,6 +132,7 @@ static const char * const page_flag_name [KPF_THP] = "t:thp", [KPF_BALLOON] = "o:balloon", [KPF_PGTABLE] = "g:pgtable", + [KPF_VMALLOC] = "V:vmalloc", [KPF_ZERO_PAGE] = "z:zero_page", [KPF_IDLE] = "i:idle_page", _ Patches currently in -mm which might be from mawilcox@xxxxxxxxxxxxx are lib-test_bitmapc-fix-bitmap-optimisation-tests-to-report-errors-correctly.patch slab-__gfp_zero-is-incompatible-with-a-constructor.patch s390-use-_refcount-for-pgtables.patch mm-split-page_type-out-from-_mapcount.patch mm-mark-pages-in-use-for-page-tables.patch mm-switch-s_mem-and-slab_cache-in-struct-page.patch mm-move-private-union-within-struct-page.patch mm-move-_refcount-out-of-struct-page-union.patch mm-combine-first-three-unions-in-struct-page.patch mm-use-page-deferred_list.patch mm-move-lru-union-within-struct-page.patch mm-combine-lru-and-main-union-in-struct-page.patch mm-improve-struct-page-documentation.patch mm-add-pt_mm-to-struct-page.patch mm-add-hmm_data-to-struct-page.patch slabslub-remove-rcu_head-size-checks.patch slub-remove-kmem_cache-reserved.patch slub-remove-reserved-file-from-sysfs.patch mm-distinguish-vmalloc-pages.patch ida-remove-simple_ida_lock.patch -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html