History

mm, debug_pagealloc: use a page type instead of page_ext flag

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.

Vlastimil Babka committed 7 years ago

Commit 3972f6b1 parent 4462b327 files · +17 −54Browse files

Unified · Split

7 files
  1. Documentation/admin-guide/kernel-parameters.txt +4 −6
  2. include/linux/mm.h +1 −9
  3. include/linux/page-flags.h +6 −0
  4. include/linux/page_ext.h +0 −1
  5. mm/Kconfig.debug +0 −1
  6. mm/page_alloc.c +6 −34
  7. mm/page_ext.c +0 −3
Documentation/admin-guide/kernel-parameters.txt+4−6
@@ -805,12 +805,10 @@ · 804 unmodified lines
805805 tracking down these problems.
806806
807807 debug_pagealloc=
808− [KNL] When CONFIG_DEBUG_PAGEALLOC is set, this
809− parameter enables the feature at boot time. In
810− default, it is disabled. We can avoid allocating huge
811− chunk of memory for debug pagealloc if we don't enable
812− it at boot time and the system will work mostly same
813− with the kernel built without CONFIG_DEBUG_PAGEALLOC.
808+ [KNL] When CONFIG_DEBUG_PAGEALLOC is set, this parameter
809+ enables the feature at boot time. By default, it is
810+ disabled and the system will work mostly the same as a
811+ kernel built without CONFIG_DEBUG_PAGEALLOC.
814812 on: enable the feature
815813
816814 debugpat [X86] Enable PAT debugging
include/linux/mm.h+1−9
@@ -2862,8 +2862,6 @@ extern long copy_huge_page_from_user(struct page *dst_page, · 2861 unmodified lines
28622862 bool allow_pagefault);
28632863 #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */
28642864
2865−extern struct page_ext_operations debug_guardpage_ops;
2866−
28672865 #ifdef CONFIG_DEBUG_PAGEALLOC
28682866 extern unsigned int _debug_guardpage_minorder;
28692867 DECLARE_STATIC_KEY_FALSE(_debug_guardpage_enabled);
@@ -2880,16 +2878,10 @@ static inline bool debug_guardpage_enabled(void) · 10 unmodified lines
28802878
28812879 static inline bool page_is_guard(struct page *page)
28822880 {
2883− struct page_ext *page_ext;
2884−
28852881 if (!debug_guardpage_enabled())
28862882 return false;
28872883
2888− page_ext = lookup_page_ext(page);
2889− if (unlikely(!page_ext))
2890− return false;
2891−
2892− return test_bit(PAGE_EXT_DEBUG_GUARD, &page_ext->flags);
2884+ return PageGuard(page);
28932885 }
28942886 #else
28952887 static inline unsigned int debug_guardpage_minorder(void) { return 0; }
include/linux/page-flags.h+6−0
@@ -703,6 +703,7 @@ PAGEFLAG_FALSE(DoubleMap) · 702 unmodified lines
703703 #define PG_offline 0x00000100
704704 #define PG_kmemcg 0x00000200
705705 #define PG_table 0x00000400
706+#define PG_guard 0x00000800
706707
707708 #define PageType(page, flag) \
708709 ((page->page_type & (PAGE_TYPE_BASE | flag)) == PAGE_TYPE_BASE)
@@ -754,6 +755,11 @@ PAGE_TYPE_OPS(Kmemcg, kmemcg) · 45 unmodified lines
754755 */
755756 PAGE_TYPE_OPS(Table, table)
756757
758+/*
759+ * Marks guardpages used with debug_pagealloc.
760+ */
761+PAGE_TYPE_OPS(Guard, guard)
762+
757763 extern bool is_free_buddy_page(struct page *page);
758764
759765 __PAGEFLAG(Isolated, isolated, PF_ANY);
include/linux/page_ext.h+0−1
@@ -17,7 +17,6 @@ struct page_ext_operations { · 16 unmodified lines
1717 #ifdef CONFIG_PAGE_EXTENSION
1818
1919 enum page_ext_flags {
20− PAGE_EXT_DEBUG_GUARD,
2120 PAGE_EXT_OWNER,
2221 #if defined(CONFIG_IDLE_PAGE_TRACKING) && !defined(CONFIG_64BIT)
2322 PAGE_EXT_YOUNG,
mm/Kconfig.debug+0−1
@@ -12,7 +12,6 @@ config DEBUG_PAGEALLOC · 11 unmodified lines
1212 bool "Debug page memory allocations"
1313 depends on DEBUG_KERNEL
1414 depends on !HIBERNATION || ARCH_SUPPORTS_DEBUG_PAGEALLOC && !PPC && !SPARC
15− select PAGE_EXTENSION
1615 select PAGE_POISONING if !ARCH_SUPPORTS_DEBUG_PAGEALLOC
1716 ---help---
1817 Unmap pages from the kernel linear mapping after free_pages().
mm/page_alloc.c+6−34
@@ -50,7 +50,6 @@ · 49 unmodified lines
5050 #include <linux/backing-dev.h>
5151 #include <linux/fault-inject.h>
5252 #include <linux/page-isolation.h>
53−#include <linux/page_ext.h>
5453 #include <linux/debugobjects.h>
5554 #include <linux/kmemleak.h>
5655 #include <linux/compaction.h>
@@ -668,18 +667,6 @@ static int __init early_debug_pagealloc(char *buf) · 611 unmodified lines
668667 }
669668 early_param("debug_pagealloc", early_debug_pagealloc);
670669
671−static bool need_debug_guardpage(void)
672−{
673− /* If we don't use debug_pagealloc, we don't need guard page */
674− if (!debug_pagealloc_enabled())
675− return false;
676−
677− if (!debug_guardpage_minorder())
678− return false;
679−
680− return true;
681−}
682−
683670 static void init_debug_guardpage(void)
684671 {
685672 if (!debug_pagealloc_enabled())
@@ -691,11 +678,6 @@ static void init_debug_guardpage(void) · 5 unmodified lines
691678 static_branch_enable(&_debug_guardpage_enabled);
692679 }
693680
694−struct page_ext_operations debug_guardpage_ops = {
695− .need = need_debug_guardpage,
696− .init = init_debug_guardpage,
697−};
698−
699681 static int __init debug_guardpage_minorder_setup(char *buf)
700682 {
701683 unsigned long res;
@@ -713,20 +695,13 @@ early_param("debug_guardpage_minorder", debug_guardpage_minorder_setup); · 11 unmodified lines
713695 static inline bool set_page_guard(struct zone *zone, struct page *page,
714696 unsigned int order, int migratetype)
715697 {
716− struct page_ext *page_ext;
717−
718698 if (!debug_guardpage_enabled())
719699 return false;
720700
721701 if (order >= debug_guardpage_minorder())
722702 return false;
723703
724− page_ext = lookup_page_ext(page);
725− if (unlikely(!page_ext))
726− return false;
727−
728− __set_bit(PAGE_EXT_DEBUG_GUARD, &page_ext->flags);
729−
704+ __SetPageGuard(page);
730705 INIT_LIST_HEAD(&page->lru);
731706 set_page_private(page, order);
732707 /* Guard pages are not available for any usage */
@@ -738,23 +713,16 @@ static inline bool set_page_guard(struct zone *zone, struct page *page, · 5 unmodified lines
738713 static inline void clear_page_guard(struct zone *zone, struct page *page,
739714 unsigned int order, int migratetype)
740715 {
741− struct page_ext *page_ext;
742−
743716 if (!debug_guardpage_enabled())
744717 return;
745718
746− page_ext = lookup_page_ext(page);
747− if (unlikely(!page_ext))
748− return;
749−
750− __clear_bit(PAGE_EXT_DEBUG_GUARD, &page_ext->flags);
719+ __ClearPageGuard(page);
751720
752721 set_page_private(page, 0);
753722 if (!is_migrate_isolate(migratetype))
754723 __mod_zone_freepage_state(zone, (1 << order), migratetype);
755724 }
756725 #else
757−struct page_ext_operations debug_guardpage_ops;
758726 static inline bool set_page_guard(struct zone *zone, struct page *page,
759727 unsigned int order, int migratetype) { return false; }
760728 static inline void clear_page_guard(struct zone *zone, struct page *page,
@@ -1930,6 +1898,10 @@ void __init page_alloc_init_late(void) · 1169 unmodified lines
19301898
19311899 for_each_populated_zone(zone)
19321900 set_zone_contiguous(zone);
1901+
1902+#ifdef CONFIG_DEBUG_PAGEALLOC
1903+ init_debug_guardpage();
1904+#endif
19331905 }
19341906
19351907 #ifdef CONFIG_CMA
mm/page_ext.c+0−3
@@ -59,9 +59,6 @@ · 58 unmodified lines
5959 */
6060
6161 static struct page_ext_operations *page_ext_ops[] = {
62−#ifdef CONFIG_DEBUG_PAGEALLOC
63− &debug_guardpage_ops,
64−#endif
6562 #ifdef CONFIG_PAGE_OWNER
6663 &page_owner_ops,
6764 #endif

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t