From: Matthew Wilcox <willy@infradead.org> To: linux-mm@kvack.org Cc: "Matthew Wilcox" <mawilcox@microsoft.com>, "Andrew Morton" <akpm@linux-foundation.org>, "Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>, "Christoph Lameter" <cl@linux.com>, "Lai Jiangshan" <jiangshanlai@gmail.com>, "Pekka Enberg" <penberg@kernel.org>, "Vlastimil Babka" <vbabka@suse.cz>, "Dave Hansen" <dave.hansen@linux.intel.com>, "Jérôme Glisse" <jglisse@redhat.com> Subject: [PATCH v5 17/17] mm: Distinguish VMalloc pages Date: Fri, 4 May 2018 11:33:18 -0700 [thread overview] Message-ID: <20180504183318.14415-18-willy@infradead.org> (raw) In-Reply-To: <20180504183318.14415-1-willy@infradead.org> From: Matthew Wilcox <mawilcox@microsoft.com> 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. Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com> --- 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 --git a/fs/proc/page.c b/fs/proc/page.c index 792c78a49174..fc83dae1af7b 100644 --- a/fs/proc/page.c +++ b/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 --git a/include/linux/mm_types.h b/include/linux/mm_types.h index fa05e6ca31ed..199f43b50cf4 100644 --- a/include/linux/mm_types.h +++ b/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 */ + }; /** @rcu_head: You can use this to free a page by RCU. */ struct rcu_head rcu_head; diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 901943e4754b..5232433175c1 100644 --- a/include/linux/page-flags.h +++ b/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 --git a/include/uapi/linux/kernel-page-flags.h b/include/uapi/linux/kernel-page-flags.h index 21b9113c69da..6800968b8f47 100644 --- a/include/uapi/linux/kernel-page-flags.h +++ b/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 --git a/mm/vmalloc.c b/mm/vmalloc.c index 5fbf27e7f956..98bc690d472d 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1535,7 +1535,7 @@ static void __vunmap(const void *addr, int deallocate_pages) for (i = 0; i < area->nr_pages; i++) { struct page *page = area->pages[i]; - BUG_ON(!page); + __ClearPageVMalloc(page); __free_pages(page, 0); } @@ -1704,6 +1704,9 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask, 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)) cond_resched(); diff --git a/tools/vm/page-types.c b/tools/vm/page-types.c index cce853dca691..25cc21855be4 100644 --- a/tools/vm/page-types.c +++ b/tools/vm/page-types.c @@ -132,6 +132,7 @@ static const char * const page_flag_names[] = { [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", -- 2.17.0
next prev parent reply other threads:[~2018-05-04 18:33 UTC|newest] Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-05-04 18:33 [PATCH v5 00/17] Rearrange struct page Matthew Wilcox 2018-05-04 18:33 ` [PATCH v5 01/17] s390: Use _refcount for pgtables Matthew Wilcox 2018-05-04 18:33 ` [PATCH v5 02/17] mm: Split page_type out from _mapcount Matthew Wilcox 2018-05-14 14:33 ` Vlastimil Babka 2018-05-04 18:33 ` [PATCH v5 03/17] mm: Mark pages in use for page tables Matthew Wilcox 2018-05-04 18:33 ` [PATCH v5 04/17] mm: Switch s_mem and slab_cache in struct page Matthew Wilcox 2018-05-07 14:58 ` Christopher Lameter 2018-05-14 14:37 ` Vlastimil Babka 2018-05-04 18:33 ` [PATCH v5 05/17] mm: Move 'private' union within " Matthew Wilcox 2018-05-04 18:33 ` [PATCH v5 06/17] mm: Move _refcount out of struct page union Matthew Wilcox 2018-05-04 18:33 ` [PATCH v5 07/17] mm: Combine first three unions in struct page Matthew Wilcox 2018-05-14 14:42 ` Vlastimil Babka 2018-05-04 18:33 ` [PATCH v5 08/17] mm: Use page->deferred_list Matthew Wilcox 2018-05-04 18:33 ` [PATCH v5 09/17] mm: Move lru union within struct page Matthew Wilcox 2018-05-04 18:33 ` [PATCH v5 10/17] mm: Combine LRU and main union in " Matthew Wilcox 2018-05-04 18:33 ` [PATCH v5 11/17] mm: Improve struct page documentation Matthew Wilcox 2018-05-15 9:22 ` Vlastimil Babka 2018-05-04 18:33 ` [PATCH v5 12/17] mm: Add pt_mm to struct page Matthew Wilcox 2018-05-15 9:27 ` Vlastimil Babka 2018-05-15 12:23 ` Matthew Wilcox 2018-05-04 18:33 ` [PATCH v5 13/17] mm: Add hmm_data " Matthew Wilcox 2018-05-15 9:32 ` Vlastimil Babka 2018-05-15 12:40 ` Vlastimil Babka 2018-05-04 18:33 ` [PATCH v5 14/17] slab,slub: Remove rcu_head size checks Matthew Wilcox 2018-05-15 11:30 ` Vlastimil Babka 2018-05-04 18:33 ` [PATCH v5 15/17] slub: Remove kmem_cache->reserved Matthew Wilcox 2018-05-04 18:33 ` [PATCH v5 16/17] slub: Remove 'reserved' file from sysfs Matthew Wilcox 2018-05-07 15:01 ` Christopher Lameter 2018-05-04 18:33 ` Matthew Wilcox [this message] 2018-05-04 20:52 ` [PATCH v5 00/17] Rearrange struct page Andrew Morton 2018-05-04 21:25 ` Matthew Wilcox
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20180504183318.14415-18-willy@infradead.org \ --to=willy@infradead.org \ --cc=akpm@linux-foundation.org \ --cc=cl@linux.com \ --cc=dave.hansen@linux.intel.com \ --cc=jglisse@redhat.com \ --cc=jiangshanlai@gmail.com \ --cc=kirill.shutemov@linux.intel.com \ --cc=linux-mm@kvack.org \ --cc=mawilcox@microsoft.com \ --cc=penberg@kernel.org \ --cc=vbabka@suse.cz \ --subject='Re: [PATCH v5 17/17] mm: Distinguish VMalloc pages' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.