diff options
author | Vladimir Davydov <vdavydov@parallels.com> | 2015-09-09 18:35:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-09-10 16:29:01 -0400 |
commit | 80ae2fdceba8313b0433f899bdd9c6c463291a17 (patch) | |
tree | c8e6d0d5edcd0306ee939d3362028511e33bf97b /fs/proc | |
parent | e993d905c81e2c0f669f2f8e8327df86738baebe (diff) |
proc: add kpagecgroup file
/proc/kpagecgroup contains a 64-bit inode number of the memory cgroup each
page is charged to, indexed by PFN. Having this information is useful for
estimating a cgroup working set size.
The file is present if CONFIG_PROC_PAGE_MONITOR && CONFIG_MEMCG.
Signed-off-by: Vladimir Davydov <vdavydov@parallels.com>
Reviewed-by: Andres Lagar-Cavilla <andreslc@google.com>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Raghavendra K T <raghavendra.kt@linux.vnet.ibm.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Greg Thelen <gthelen@google.com>
Cc: Michel Lespinasse <walken@google.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Pavel Emelyanov <xemul@parallels.com>
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/page.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/fs/proc/page.c b/fs/proc/page.c index 7eee2d8b97d9..70d23245dd43 100644 --- a/fs/proc/page.c +++ b/fs/proc/page.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/proc_fs.h> | 9 | #include <linux/proc_fs.h> |
10 | #include <linux/seq_file.h> | 10 | #include <linux/seq_file.h> |
11 | #include <linux/hugetlb.h> | 11 | #include <linux/hugetlb.h> |
12 | #include <linux/memcontrol.h> | ||
12 | #include <linux/kernel-page-flags.h> | 13 | #include <linux/kernel-page-flags.h> |
13 | #include <asm/uaccess.h> | 14 | #include <asm/uaccess.h> |
14 | #include "internal.h" | 15 | #include "internal.h" |
@@ -225,10 +226,62 @@ static const struct file_operations proc_kpageflags_operations = { | |||
225 | .read = kpageflags_read, | 226 | .read = kpageflags_read, |
226 | }; | 227 | }; |
227 | 228 | ||
229 | #ifdef CONFIG_MEMCG | ||
230 | static ssize_t kpagecgroup_read(struct file *file, char __user *buf, | ||
231 | size_t count, loff_t *ppos) | ||
232 | { | ||
233 | u64 __user *out = (u64 __user *)buf; | ||
234 | struct page *ppage; | ||
235 | unsigned long src = *ppos; | ||
236 | unsigned long pfn; | ||
237 | ssize_t ret = 0; | ||
238 | u64 ino; | ||
239 | |||
240 | pfn = src / KPMSIZE; | ||
241 | count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src); | ||
242 | if (src & KPMMASK || count & KPMMASK) | ||
243 | return -EINVAL; | ||
244 | |||
245 | while (count > 0) { | ||
246 | if (pfn_valid(pfn)) | ||
247 | ppage = pfn_to_page(pfn); | ||
248 | else | ||
249 | ppage = NULL; | ||
250 | |||
251 | if (ppage) | ||
252 | ino = page_cgroup_ino(ppage); | ||
253 | else | ||
254 | ino = 0; | ||
255 | |||
256 | if (put_user(ino, out)) { | ||
257 | ret = -EFAULT; | ||
258 | break; | ||
259 | } | ||
260 | |||
261 | pfn++; | ||
262 | out++; | ||
263 | count -= KPMSIZE; | ||
264 | } | ||
265 | |||
266 | *ppos += (char __user *)out - buf; | ||
267 | if (!ret) | ||
268 | ret = (char __user *)out - buf; | ||
269 | return ret; | ||
270 | } | ||
271 | |||
272 | static const struct file_operations proc_kpagecgroup_operations = { | ||
273 | .llseek = mem_lseek, | ||
274 | .read = kpagecgroup_read, | ||
275 | }; | ||
276 | #endif /* CONFIG_MEMCG */ | ||
277 | |||
228 | static int __init proc_page_init(void) | 278 | static int __init proc_page_init(void) |
229 | { | 279 | { |
230 | proc_create("kpagecount", S_IRUSR, NULL, &proc_kpagecount_operations); | 280 | proc_create("kpagecount", S_IRUSR, NULL, &proc_kpagecount_operations); |
231 | proc_create("kpageflags", S_IRUSR, NULL, &proc_kpageflags_operations); | 281 | proc_create("kpageflags", S_IRUSR, NULL, &proc_kpageflags_operations); |
282 | #ifdef CONFIG_MEMCG | ||
283 | proc_create("kpagecgroup", S_IRUSR, NULL, &proc_kpagecgroup_operations); | ||
284 | #endif | ||
232 | return 0; | 285 | return 0; |
233 | } | 286 | } |
234 | fs_initcall(proc_page_init); | 287 | fs_initcall(proc_page_init); |