diff options
author | Wang, Yalin <Yalin.Wang@sonymobile.com> | 2015-02-11 18:24:51 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-11 20:06:00 -0500 |
commit | 56873f43abdcd574b25105867a990f067747b2f4 (patch) | |
tree | be55c69ee61da7b4e10e46c89e62a2ca68adaf81 | |
parent | 1d148e218a0d0566b1c06f2f45f1436d53b049b2 (diff) |
mm:add KPF_ZERO_PAGE flag for /proc/kpageflags
Add KPF_ZERO_PAGE flag for zero_page, so that userspace processes can
detect zero_page in /proc/kpageflags, and then do memory analysis more
accurately.
Signed-off-by: Yalin Wang <yalin.wang@sonymobile.com>
Acked-by: Kirill A. Shutemov <kirill@shutemov.name>
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-- | Documentation/vm/pagemap.txt | 8 | ||||
-rw-r--r-- | fs/proc/page.c | 16 | ||||
-rw-r--r-- | include/linux/huge_mm.h | 12 | ||||
-rw-r--r-- | include/uapi/linux/kernel-page-flags.h | 1 | ||||
-rw-r--r-- | mm/huge_memory.c | 7 | ||||
-rw-r--r-- | tools/vm/page-types.c | 1 |
6 files changed, 36 insertions, 9 deletions
diff --git a/Documentation/vm/pagemap.txt b/Documentation/vm/pagemap.txt index 5948e455c4d2..6fbd55ef6b45 100644 --- a/Documentation/vm/pagemap.txt +++ b/Documentation/vm/pagemap.txt | |||
@@ -62,6 +62,8 @@ There are three components to pagemap: | |||
62 | 20. NOPAGE | 62 | 20. NOPAGE |
63 | 21. KSM | 63 | 21. KSM |
64 | 22. THP | 64 | 22. THP |
65 | 23. BALLOON | ||
66 | 24. ZERO_PAGE | ||
65 | 67 | ||
66 | Short descriptions to the page flags: | 68 | Short descriptions to the page flags: |
67 | 69 | ||
@@ -102,6 +104,12 @@ Short descriptions to the page flags: | |||
102 | 22. THP | 104 | 22. THP |
103 | contiguous pages which construct transparent hugepages | 105 | contiguous pages which construct transparent hugepages |
104 | 106 | ||
107 | 23. BALLOON | ||
108 | balloon compaction page | ||
109 | |||
110 | 24. ZERO_PAGE | ||
111 | zero page for pfn_zero or huge_zero page | ||
112 | |||
105 | [IO related page flags] | 113 | [IO related page flags] |
106 | 1. ERROR IO error occurred | 114 | 1. ERROR IO error occurred |
107 | 3. UPTODATE page has up-to-date data | 115 | 3. UPTODATE page has up-to-date data |
diff --git a/fs/proc/page.c b/fs/proc/page.c index 1e3187da1fed..7eee2d8b97d9 100644 --- a/fs/proc/page.c +++ b/fs/proc/page.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/ksm.h> | 5 | #include <linux/ksm.h> |
6 | #include <linux/mm.h> | 6 | #include <linux/mm.h> |
7 | #include <linux/mmzone.h> | 7 | #include <linux/mmzone.h> |
8 | #include <linux/huge_mm.h> | ||
8 | #include <linux/proc_fs.h> | 9 | #include <linux/proc_fs.h> |
9 | #include <linux/seq_file.h> | 10 | #include <linux/seq_file.h> |
10 | #include <linux/hugetlb.h> | 11 | #include <linux/hugetlb.h> |
@@ -121,9 +122,18 @@ u64 stable_page_flags(struct page *page) | |||
121 | * just checks PG_head/PG_tail, so we need to check PageLRU/PageAnon | 122 | * just checks PG_head/PG_tail, so we need to check PageLRU/PageAnon |
122 | * to make sure a given page is a thp, not a non-huge compound page. | 123 | * to make sure a given page is a thp, not a non-huge compound page. |
123 | */ | 124 | */ |
124 | else if (PageTransCompound(page) && (PageLRU(compound_head(page)) || | 125 | else if (PageTransCompound(page)) { |
125 | PageAnon(compound_head(page)))) | 126 | struct page *head = compound_head(page); |
126 | u |= 1 << KPF_THP; | 127 | |
128 | if (PageLRU(head) || PageAnon(head)) | ||
129 | u |= 1 << KPF_THP; | ||
130 | else if (is_huge_zero_page(head)) { | ||
131 | u |= 1 << KPF_ZERO_PAGE; | ||
132 | u |= 1 << KPF_THP; | ||
133 | } | ||
134 | } else if (is_zero_pfn(page_to_pfn(page))) | ||
135 | u |= 1 << KPF_ZERO_PAGE; | ||
136 | |||
127 | 137 | ||
128 | /* | 138 | /* |
129 | * Caveats on high order pages: page->_count will only be set | 139 | * Caveats on high order pages: page->_count will only be set |
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index ad9051bab267..f10b20f05159 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h | |||
@@ -157,6 +157,13 @@ static inline int hpage_nr_pages(struct page *page) | |||
157 | extern int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, | 157 | extern int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, |
158 | unsigned long addr, pmd_t pmd, pmd_t *pmdp); | 158 | unsigned long addr, pmd_t pmd, pmd_t *pmdp); |
159 | 159 | ||
160 | extern struct page *huge_zero_page; | ||
161 | |||
162 | static inline bool is_huge_zero_page(struct page *page) | ||
163 | { | ||
164 | return ACCESS_ONCE(huge_zero_page) == page; | ||
165 | } | ||
166 | |||
160 | #else /* CONFIG_TRANSPARENT_HUGEPAGE */ | 167 | #else /* CONFIG_TRANSPARENT_HUGEPAGE */ |
161 | #define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; }) | 168 | #define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; }) |
162 | #define HPAGE_PMD_MASK ({ BUILD_BUG(); 0; }) | 169 | #define HPAGE_PMD_MASK ({ BUILD_BUG(); 0; }) |
@@ -206,6 +213,11 @@ static inline int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_str | |||
206 | return 0; | 213 | return 0; |
207 | } | 214 | } |
208 | 215 | ||
216 | static inline bool is_huge_zero_page(struct page *page) | ||
217 | { | ||
218 | return false; | ||
219 | } | ||
220 | |||
209 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ | 221 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ |
210 | 222 | ||
211 | #endif /* _LINUX_HUGE_MM_H */ | 223 | #endif /* _LINUX_HUGE_MM_H */ |
diff --git a/include/uapi/linux/kernel-page-flags.h b/include/uapi/linux/kernel-page-flags.h index 2f96d233c980..a6c4962e5d46 100644 --- a/include/uapi/linux/kernel-page-flags.h +++ b/include/uapi/linux/kernel-page-flags.h | |||
@@ -32,6 +32,7 @@ | |||
32 | #define KPF_KSM 21 | 32 | #define KPF_KSM 21 |
33 | #define KPF_THP 22 | 33 | #define KPF_THP 22 |
34 | #define KPF_BALLOON 23 | 34 | #define KPF_BALLOON 23 |
35 | #define KPF_ZERO_PAGE 24 | ||
35 | 36 | ||
36 | 37 | ||
37 | #endif /* _UAPILINUX_KERNEL_PAGE_FLAGS_H */ | 38 | #endif /* _UAPILINUX_KERNEL_PAGE_FLAGS_H */ |
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 817a875f2b8c..889713180980 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
@@ -171,12 +171,7 @@ static int start_khugepaged(void) | |||
171 | } | 171 | } |
172 | 172 | ||
173 | static atomic_t huge_zero_refcount; | 173 | static atomic_t huge_zero_refcount; |
174 | static struct page *huge_zero_page __read_mostly; | 174 | struct page *huge_zero_page __read_mostly; |
175 | |||
176 | static inline bool is_huge_zero_page(struct page *page) | ||
177 | { | ||
178 | return ACCESS_ONCE(huge_zero_page) == page; | ||
179 | } | ||
180 | 175 | ||
181 | static inline bool is_huge_zero_pmd(pmd_t pmd) | 176 | static inline bool is_huge_zero_pmd(pmd_t pmd) |
182 | { | 177 | { |
diff --git a/tools/vm/page-types.c b/tools/vm/page-types.c index 264fbc297e0b..8bdf16b8ba60 100644 --- a/tools/vm/page-types.c +++ b/tools/vm/page-types.c | |||
@@ -133,6 +133,7 @@ static const char * const page_flag_names[] = { | |||
133 | [KPF_KSM] = "x:ksm", | 133 | [KPF_KSM] = "x:ksm", |
134 | [KPF_THP] = "t:thp", | 134 | [KPF_THP] = "t:thp", |
135 | [KPF_BALLOON] = "o:balloon", | 135 | [KPF_BALLOON] = "o:balloon", |
136 | [KPF_ZERO_PAGE] = "z:zero_page", | ||
136 | 137 | ||
137 | [KPF_RESERVED] = "r:reserved", | 138 | [KPF_RESERVED] = "r:reserved", |
138 | [KPF_MLOCKED] = "m:mlocked", | 139 | [KPF_MLOCKED] = "m:mlocked", |