When debug_pagealloc is enabled, we currently allocate the page_ext array to mark guard pages with the PAGE_EXT_DEBUG_GUARD flag. Now that we have the page_type field in struct page, we can use that instead, as guard pages are neither PageSlab nor mapped to userspace. This reduces memory overhead when debug_pagealloc is enabled and there are no other features requiring the page_ext array.
Showing the changes to include/linux (3 of 7 files). Show all
Unified · Split
| @@ -2862,8 +2862,6 @@ extern long copy_huge_page_from_user(struct page *dst_page, · 2861 unmodified lines | |||
| 2862 | bool allow_pagefault); | 2862 | bool allow_pagefault); |
| 2863 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */ | 2863 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */ |
| 2864 | 2864 | ||
| 2865 | extern struct page_ext_operations debug_guardpage_ops; | ||
| 2866 | |||
| 2867 | #ifdef CONFIG_DEBUG_PAGEALLOC | 2865 | #ifdef CONFIG_DEBUG_PAGEALLOC |
| 2868 | extern unsigned int _debug_guardpage_minorder; | 2866 | extern unsigned int _debug_guardpage_minorder; |
| 2869 | DECLARE_STATIC_KEY_FALSE(_debug_guardpage_enabled); | 2867 | DECLARE_STATIC_KEY_FALSE(_debug_guardpage_enabled); |
| @@ -2880,16 +2878,10 @@ static inline bool debug_guardpage_enabled(void) · 10 unmodified lines | |||
| 2880 | 2878 | ||
| 2881 | static inline bool page_is_guard(struct page *page) | 2879 | static inline bool page_is_guard(struct page *page) |
| 2882 | { | 2880 | { |
| 2883 | struct page_ext *page_ext; | ||
| 2884 | |||
| 2885 | if (!debug_guardpage_enabled()) | 2881 | if (!debug_guardpage_enabled()) |
| 2886 | return false; | 2882 | return false; |
| 2887 | 2883 | ||
| 2888 | page_ext = lookup_page_ext(page); | 2884 | return PageGuard(page); |
| 2889 | if (unlikely(!page_ext)) | ||
| 2890 | return false; | ||
| 2891 | |||
| 2892 | return test_bit(PAGE_EXT_DEBUG_GUARD, &page_ext->flags); | ||
| 2893 | } | 2885 | } |
| 2894 | #else | 2886 | #else |
| 2895 | static inline unsigned int debug_guardpage_minorder(void) { return 0; } | 2887 | static inline unsigned int debug_guardpage_minorder(void) { return 0; } |
| @@ -703,6 +703,7 @@ PAGEFLAG_FALSE(DoubleMap) · 702 unmodified lines | |||
| 703 | #define PG_offline 0x00000100 | 703 | #define PG_offline 0x00000100 |
| 704 | #define PG_kmemcg 0x00000200 | 704 | #define PG_kmemcg 0x00000200 |
| 705 | #define PG_table 0x00000400 | 705 | #define PG_table 0x00000400 |
| 706 | #define PG_guard 0x00000800 | ||
| 706 | 707 | ||
| 707 | #define PageType(page, flag) \ | 708 | #define PageType(page, flag) \ |
| 708 | ((page->page_type & (PAGE_TYPE_BASE | flag)) == PAGE_TYPE_BASE) | 709 | ((page->page_type & (PAGE_TYPE_BASE | flag)) == PAGE_TYPE_BASE) |
| @@ -754,6 +755,11 @@ PAGE_TYPE_OPS(Kmemcg, kmemcg) · 45 unmodified lines | |||
| 754 | */ | 755 | */ |
| 755 | PAGE_TYPE_OPS(Table, table) | 756 | PAGE_TYPE_OPS(Table, table) |
| 756 | 757 | ||
| 758 | /* | ||
| 759 | * Marks guardpages used with debug_pagealloc. | ||
| 760 | */ | ||
| 761 | PAGE_TYPE_OPS(Guard, guard) | ||
| 762 | |||
| 757 | extern bool is_free_buddy_page(struct page *page); | 763 | extern bool is_free_buddy_page(struct page *page); |
| 758 | 764 | ||
| 759 | __PAGEFLAG(Isolated, isolated, PF_ANY); | 765 | __PAGEFLAG(Isolated, isolated, PF_ANY); |
| @@ -17,7 +17,6 @@ struct page_ext_operations { · 16 unmodified lines | |||
| 17 | #ifdef CONFIG_PAGE_EXTENSION | 17 | #ifdef CONFIG_PAGE_EXTENSION |
| 18 | 18 | ||
| 19 | enum page_ext_flags { | 19 | enum page_ext_flags { |
| 20 | PAGE_EXT_DEBUG_GUARD, | ||
| 21 | PAGE_EXT_OWNER, | 20 | PAGE_EXT_OWNER, |
| 22 | #if defined(CONFIG_IDLE_PAGE_TRACKING) && !defined(CONFIG_64BIT) | 21 | #if defined(CONFIG_IDLE_PAGE_TRACKING) && !defined(CONFIG_64BIT) |
| 23 | PAGE_EXT_YOUNG, | 22 | PAGE_EXT_YOUNG, |