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
805 tracking down these problems.805 tracking down these problems.
806 806
807 debug_pagealloc=807 debug_pagealloc=
808 [KNL] When CONFIG_DEBUG_PAGEALLOC is set, this808 [KNL] When CONFIG_DEBUG_PAGEALLOC is set, this parameter
809 parameter enables the feature at boot time. In809 enables the feature at boot time. By default, it is
810 default, it is disabled. We can avoid allocating huge810 disabled and the system will work mostly the same as a
811 chunk of memory for debug pagealloc if we don't enable811 kernel built without CONFIG_DEBUG_PAGEALLOC.
812 it at boot time and the system will work mostly same
813 with the kernel built without CONFIG_DEBUG_PAGEALLOC.
814 on: enable the feature812 on: enable the feature
815 813
816 debugpat [X86] Enable PAT debugging814 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
2862 bool allow_pagefault);2862 bool allow_pagefault);
2863#endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */2863#endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */
2864 2864
2865extern struct page_ext_operations debug_guardpage_ops;
2866
2867#ifdef CONFIG_DEBUG_PAGEALLOC2865#ifdef CONFIG_DEBUG_PAGEALLOC
2868extern unsigned int _debug_guardpage_minorder;2866extern unsigned int _debug_guardpage_minorder;
2869DECLARE_STATIC_KEY_FALSE(_debug_guardpage_enabled);2867DECLARE_STATIC_KEY_FALSE(_debug_guardpage_enabled);
@@ -2880,16 +2878,10 @@ static inline bool debug_guardpage_enabled(void) · 10 unmodified lines
2880 2878
2881static inline bool page_is_guard(struct page *page)2879static 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#else2886#else
2895static inline unsigned int debug_guardpage_minorder(void) { return 0; }2887static 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
703#define PG_offline 0x00000100703#define PG_offline 0x00000100
704#define PG_kmemcg 0x00000200704#define PG_kmemcg 0x00000200
705#define PG_table 0x00000400705#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 */
755PAGE_TYPE_OPS(Table, table)756PAGE_TYPE_OPS(Table, table)
756 757
758/*
759 * Marks guardpages used with debug_pagealloc.
760 */
761PAGE_TYPE_OPS(Guard, guard)
762
757extern bool is_free_buddy_page(struct page *page);763extern bool is_free_buddy_page(struct page *page);
758 764
759__PAGEFLAG(Isolated, isolated, PF_ANY);765__PAGEFLAG(Isolated, isolated, PF_ANY);
include/linux/page_ext.h+0−1
@@ -17,7 +17,6 @@ struct page_ext_operations { · 16 unmodified lines
17#ifdef CONFIG_PAGE_EXTENSION17#ifdef CONFIG_PAGE_EXTENSION
18 18
19enum page_ext_flags {19enum 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,
mm/Kconfig.debug+0−1
@@ -12,7 +12,6 @@ config DEBUG_PAGEALLOC · 11 unmodified lines
12 bool "Debug page memory allocations"12 bool "Debug page memory allocations"
13 depends on DEBUG_KERNEL13 depends on DEBUG_KERNEL
14 depends on !HIBERNATION || ARCH_SUPPORTS_DEBUG_PAGEALLOC && !PPC && !SPARC14 depends on !HIBERNATION || ARCH_SUPPORTS_DEBUG_PAGEALLOC && !PPC && !SPARC
15 select PAGE_EXTENSION
16 select PAGE_POISONING if !ARCH_SUPPORTS_DEBUG_PAGEALLOC15 select PAGE_POISONING if !ARCH_SUPPORTS_DEBUG_PAGEALLOC
17 ---help---16 ---help---
18 Unmap pages from the kernel linear mapping after free_pages().17 Unmap pages from the kernel linear mapping after free_pages().
mm/page_alloc.c+6−34
@@ -50,7 +50,6 @@ · 49 unmodified lines
50#include <linux/backing-dev.h>50#include <linux/backing-dev.h>
51#include <linux/fault-inject.h>51#include <linux/fault-inject.h>
52#include <linux/page-isolation.h>52#include <linux/page-isolation.h>
53#include <linux/page_ext.h>
54#include <linux/debugobjects.h>53#include <linux/debugobjects.h>
55#include <linux/kmemleak.h>54#include <linux/kmemleak.h>
56#include <linux/compaction.h>55#include <linux/compaction.h>
@@ -668,18 +667,6 @@ static int __init early_debug_pagealloc(char *buf) · 611 unmodified lines
668}667}
669early_param("debug_pagealloc", early_debug_pagealloc);668early_param("debug_pagealloc", early_debug_pagealloc);
670 669
671static 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
683static void init_debug_guardpage(void)670static void init_debug_guardpage(void)
684{671{
685 if (!debug_pagealloc_enabled())672 if (!debug_pagealloc_enabled())
@@ -691,11 +678,6 @@ static void init_debug_guardpage(void) · 5 unmodified lines
691 static_branch_enable(&_debug_guardpage_enabled);678 static_branch_enable(&_debug_guardpage_enabled);
692}679}
693 680
694struct page_ext_operations debug_guardpage_ops = {
695 .need = need_debug_guardpage,
696 .init = init_debug_guardpage,
697};
698
699static int __init debug_guardpage_minorder_setup(char *buf)681static int __init debug_guardpage_minorder_setup(char *buf)
700{682{
701 unsigned long res;683 unsigned long res;
@@ -713,20 +695,13 @@ early_param("debug_guardpage_minorder", debug_guardpage_minorder_setup); · 11 unmodified lines
713static inline bool set_page_guard(struct zone *zone, struct page *page,695static inline bool set_page_guard(struct zone *zone, struct page *page,
714 unsigned int order, int migratetype)696 unsigned int order, int migratetype)
715{697{
716 struct page_ext *page_ext;
717
718 if (!debug_guardpage_enabled())698 if (!debug_guardpage_enabled())
719 return false;699 return false;
720 700
721 if (order >= debug_guardpage_minorder())701 if (order >= debug_guardpage_minorder())
722 return false;702 return false;
723 703
724 page_ext = lookup_page_ext(page);704 __SetPageGuard(page);
725 if (unlikely(!page_ext))
726 return false;
727
728 __set_bit(PAGE_EXT_DEBUG_GUARD, &page_ext->flags);
729
730 INIT_LIST_HEAD(&page->lru);705 INIT_LIST_HEAD(&page->lru);
731 set_page_private(page, order);706 set_page_private(page, order);
732 /* Guard pages are not available for any usage */707 /* 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
738static inline void clear_page_guard(struct zone *zone, struct page *page,713static inline void clear_page_guard(struct zone *zone, struct page *page,
739 unsigned int order, int migratetype)714 unsigned int order, int migratetype)
740{715{
741 struct page_ext *page_ext;
742
743 if (!debug_guardpage_enabled())716 if (!debug_guardpage_enabled())
744 return;717 return;
745 718
746 page_ext = lookup_page_ext(page);719 __ClearPageGuard(page);
747 if (unlikely(!page_ext))
748 return;
749
750 __clear_bit(PAGE_EXT_DEBUG_GUARD, &page_ext->flags);
751 720
752 set_page_private(page, 0);721 set_page_private(page, 0);
753 if (!is_migrate_isolate(migratetype))722 if (!is_migrate_isolate(migratetype))
754 __mod_zone_freepage_state(zone, (1 << order), migratetype);723 __mod_zone_freepage_state(zone, (1 << order), migratetype);
755}724}
756#else725#else
757struct page_ext_operations debug_guardpage_ops;
758static inline bool set_page_guard(struct zone *zone, struct page *page,726static inline bool set_page_guard(struct zone *zone, struct page *page,
759 unsigned int order, int migratetype) { return false; }727 unsigned int order, int migratetype) { return false; }
760static inline void clear_page_guard(struct zone *zone, struct page *page,728static 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
1930 1898
1931 for_each_populated_zone(zone)1899 for_each_populated_zone(zone)
1932 set_zone_contiguous(zone);1900 set_zone_contiguous(zone);
1901
1902#ifdef CONFIG_DEBUG_PAGEALLOC
1903 init_debug_guardpage();
1904#endif
1933}1905}
1934 1906
1935#ifdef CONFIG_CMA1907#ifdef CONFIG_CMA
mm/page_ext.c+0−3
@@ -59,9 +59,6 @@ · 58 unmodified lines
59 */59 */
60 60
61static struct page_ext_operations *page_ext_ops[] = {61static struct page_ext_operations *page_ext_ops[] = {
62#ifdef CONFIG_DEBUG_PAGEALLOC
63 &debug_guardpage_ops,
64#endif
65#ifdef CONFIG_PAGE_OWNER62#ifdef CONFIG_PAGE_OWNER
66 &page_owner_ops,63 &page_owner_ops,
67#endif64#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