Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mm: mark pages in use for page tables

Define a new PageTable bit in the page_type and use it to mark pages in
use as page tables. This can be helpful when debugging crashdumps or
analysing memory fragmentation. Add a KPF flag to report these pages to
userspace and update page-types.c to interpret that flag.

Note that only pages currently accounted as NR_PAGETABLES are tracked as
PageTable; this does not include pgd/p4d/pud/pmd pages. Those will be the
subject of a later patch.

Link: http://lkml.kernel.org/r/20180518194519.3820-4-willy@infradead.org
Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Christoph Lameter <cl@linux.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Jérôme Glisse <jglisse@redhat.com>
Cc: Lai Jiangshan <jiangshanlai@gmail.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Matthew Wilcox and committed by
Linus Torvalds
1d40a5ea 6e292b9b

+12 -1
+2
fs/proc/page.c
··· 154 154 155 155 if (PageBalloon(page)) 156 156 u |= 1 << KPF_BALLOON; 157 + if (PageTable(page)) 158 + u |= 1 << KPF_PGTABLE; 157 159 158 160 if (page_is_idle(page)) 159 161 u |= 1 << KPF_IDLE;
+2
include/linux/mm.h
··· 1851 1851 { 1852 1852 if (!ptlock_init(page)) 1853 1853 return false; 1854 + __SetPageTable(page); 1854 1855 inc_zone_page_state(page, NR_PAGETABLE); 1855 1856 return true; 1856 1857 } ··· 1859 1858 static inline void pgtable_page_dtor(struct page *page) 1860 1859 { 1861 1860 pte_lock_deinit(page); 1861 + __ClearPageTable(page); 1862 1862 dec_zone_page_state(page, NR_PAGETABLE); 1863 1863 } 1864 1864
+6
include/linux/page-flags.h
··· 655 655 #define PG_buddy 0x00000080 656 656 #define PG_balloon 0x00000100 657 657 #define PG_kmemcg 0x00000200 658 + #define PG_table 0x00000400 658 659 659 660 #define PageType(page, flag) \ 660 661 ((page->page_type & (PAGE_TYPE_BASE | flag)) == PAGE_TYPE_BASE) ··· 693 692 * pages allocated with __GFP_ACCOUNT. It gets cleared on page free. 694 693 */ 695 694 PAGE_TYPE_OPS(Kmemcg, kmemcg) 695 + 696 + /* 697 + * Marks pages in use as page tables. 698 + */ 699 + PAGE_TYPE_OPS(Table, table) 696 700 697 701 extern bool is_free_buddy_page(struct page *page); 698 702
+1 -1
include/uapi/linux/kernel-page-flags.h
··· 35 35 #define KPF_BALLOON 23 36 36 #define KPF_ZERO_PAGE 24 37 37 #define KPF_IDLE 25 38 - 38 + #define KPF_PGTABLE 26 39 39 40 40 #endif /* _UAPILINUX_KERNEL_PAGE_FLAGS_H */
+1
tools/vm/page-types.c
··· 131 131 [KPF_KSM] = "x:ksm", 132 132 [KPF_THP] = "t:thp", 133 133 [KPF_BALLOON] = "o:balloon", 134 + [KPF_PGTABLE] = "g:pgtable", 134 135 [KPF_ZERO_PAGE] = "z:zero_page", 135 136 [KPF_IDLE] = "i:idle_page", 136 137