diff options
author | Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> | 2016-03-17 17:17:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-17 18:09:34 -0400 |
commit | 832fc1de01aea28255cb11d270679b7f1273f0d7 (patch) | |
tree | ef020cb2a44d1fee4df1359fbb3fc11a08de733b | |
parent | 12580e4b54ba8a1b22ec977c200be0174ca42348 (diff) |
/proc/kpageflags: return KPF_BUDDY for "tail" buddy pages
Currently /proc/kpageflags returns nothing for "tail" buddy pages, which
is inconvenient when grasping how free pages are distributed. This
patch sets KPF_BUDDY for such pages.
With this patch:
$ grep MemFree /proc/meminfo ; tools/vm/page-types -b buddy
MemFree: 3134992 kB
flags page-count MB symbolic-flags long-symbolic-flags
0x0000000000000400 779272 3044 __________B_______________________________ buddy
0x0000000000000c00 4385 17 __________BM______________________________ buddy,mmap
total 783657 3061
783657 pages is 3134628 kB (roughly consistent with the global counter,)
so it's OK.
[akpm@linux-foundation.org: update comment, per Naoya]
Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Reviewed-by: Vladimir Davydov <vdavydov@virtuozzo.com>>
Cc: Konstantin Khlebnikov <koct9i@gmail.com>
Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/proc/page.c | 6 | ||||
-rw-r--r-- | include/linux/page-flags.h | 2 | ||||
-rw-r--r-- | mm/internal.h | 3 | ||||
-rw-r--r-- | mm/page_alloc.c | 2 |
4 files changed, 6 insertions, 7 deletions
diff --git a/fs/proc/page.c b/fs/proc/page.c index b2855eea5405..0be626d85331 100644 --- a/fs/proc/page.c +++ b/fs/proc/page.c | |||
@@ -103,9 +103,9 @@ u64 stable_page_flags(struct page *page) | |||
103 | * pseudo flags for the well known (anonymous) memory mapped pages | 103 | * pseudo flags for the well known (anonymous) memory mapped pages |
104 | * | 104 | * |
105 | * Note that page->_mapcount is overloaded in SLOB/SLUB/SLQB, so the | 105 | * Note that page->_mapcount is overloaded in SLOB/SLUB/SLQB, so the |
106 | * simple test in page_mapcount() is not enough. | 106 | * simple test in page_mapped() is not enough. |
107 | */ | 107 | */ |
108 | if (!PageSlab(page) && page_mapcount(page)) | 108 | if (!PageSlab(page) && page_mapped(page)) |
109 | u |= 1 << KPF_MMAP; | 109 | u |= 1 << KPF_MMAP; |
110 | if (PageAnon(page)) | 110 | if (PageAnon(page)) |
111 | u |= 1 << KPF_ANON; | 111 | u |= 1 << KPF_ANON; |
@@ -148,6 +148,8 @@ u64 stable_page_flags(struct page *page) | |||
148 | */ | 148 | */ |
149 | if (PageBuddy(page)) | 149 | if (PageBuddy(page)) |
150 | u |= 1 << KPF_BUDDY; | 150 | u |= 1 << KPF_BUDDY; |
151 | else if (page_count(page) == 0 && is_free_buddy_page(page)) | ||
152 | u |= 1 << KPF_BUDDY; | ||
151 | 153 | ||
152 | if (PageBalloon(page)) | 154 | if (PageBalloon(page)) |
153 | u |= 1 << KPF_BALLOON; | 155 | u |= 1 << KPF_BALLOON; |
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 19724e6ebd26..597695523679 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h | |||
@@ -593,6 +593,8 @@ static inline void __ClearPageBuddy(struct page *page) | |||
593 | atomic_set(&page->_mapcount, -1); | 593 | atomic_set(&page->_mapcount, -1); |
594 | } | 594 | } |
595 | 595 | ||
596 | extern bool is_free_buddy_page(struct page *page); | ||
597 | |||
596 | #define PAGE_BALLOON_MAPCOUNT_VALUE (-256) | 598 | #define PAGE_BALLOON_MAPCOUNT_VALUE (-256) |
597 | 599 | ||
598 | static inline int PageBalloon(struct page *page) | 600 | static inline int PageBalloon(struct page *page) |
diff --git a/mm/internal.h b/mm/internal.h index ad9400d759c8..b95952c2faec 100644 --- a/mm/internal.h +++ b/mm/internal.h | |||
@@ -148,9 +148,6 @@ extern int __isolate_free_page(struct page *page, unsigned int order); | |||
148 | extern void __free_pages_bootmem(struct page *page, unsigned long pfn, | 148 | extern void __free_pages_bootmem(struct page *page, unsigned long pfn, |
149 | unsigned int order); | 149 | unsigned int order); |
150 | extern void prep_compound_page(struct page *page, unsigned int order); | 150 | extern void prep_compound_page(struct page *page, unsigned int order); |
151 | #ifdef CONFIG_MEMORY_FAILURE | ||
152 | extern bool is_free_buddy_page(struct page *page); | ||
153 | #endif | ||
154 | extern int user_min_free_kbytes; | 151 | extern int user_min_free_kbytes; |
155 | 152 | ||
156 | #if defined CONFIG_COMPACTION || defined CONFIG_CMA | 153 | #if defined CONFIG_COMPACTION || defined CONFIG_CMA |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index c46b75d14b6f..c7332a4bc8db 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -7152,7 +7152,6 @@ __offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn) | |||
7152 | } | 7152 | } |
7153 | #endif | 7153 | #endif |
7154 | 7154 | ||
7155 | #ifdef CONFIG_MEMORY_FAILURE | ||
7156 | bool is_free_buddy_page(struct page *page) | 7155 | bool is_free_buddy_page(struct page *page) |
7157 | { | 7156 | { |
7158 | struct zone *zone = page_zone(page); | 7157 | struct zone *zone = page_zone(page); |
@@ -7171,4 +7170,3 @@ bool is_free_buddy_page(struct page *page) | |||
7171 | 7170 | ||
7172 | return order < MAX_ORDER; | 7171 | return order < MAX_ORDER; |
7173 | } | 7172 | } |
7174 | #endif | ||