diff options
| author | Mark Brown <[email protected]> | 2015-10-12 18:09:27 +0100 | 
|---|---|---|
| committer | Mark Brown <[email protected]> | 2015-10-12 18:09:27 +0100 | 
| commit | 79828b4fa835f73cdaf4bffa48696abdcbea9d02 (patch) | |
| tree | 5e0fa7156acb75ba603022bc807df8f2fedb97a8 /fs/proc/page.c | |
| parent | 721b51fcf91898299d96f4b72cb9434cda29dce6 (diff) | |
| parent | 8c1a9d6323abf0fb1e5dad96cf3f1c783505ea5a (diff) | |
Merge remote-tracking branch 'asoc/fix/rt5645' into asoc-fix-rt5645
Diffstat (limited to 'fs/proc/page.c')
| -rw-r--r-- | fs/proc/page.c | 65 | 
1 files changed, 65 insertions, 0 deletions
diff --git a/fs/proc/page.c b/fs/proc/page.c index 7eee2d8b97d9..93484034a03d 100644 --- a/fs/proc/page.c +++ b/fs/proc/page.c @@ -9,12 +9,16 @@  #include <linux/proc_fs.h>  #include <linux/seq_file.h>  #include <linux/hugetlb.h> +#include <linux/memcontrol.h> +#include <linux/mmu_notifier.h> +#include <linux/page_idle.h>  #include <linux/kernel-page-flags.h>  #include <asm/uaccess.h>  #include "internal.h"  #define KPMSIZE sizeof(u64)  #define KPMMASK (KPMSIZE - 1) +#define KPMBITS (KPMSIZE * BITS_PER_BYTE)  /* /proc/kpagecount - an array exposing page counts   * @@ -54,6 +58,8 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf,  		pfn++;  		out++;  		count -= KPMSIZE; + +		cond_resched();  	}  	*ppos += (char __user *)out - buf; @@ -146,6 +152,9 @@ u64 stable_page_flags(struct page *page)  	if (PageBalloon(page))  		u |= 1 << KPF_BALLOON; +	if (page_is_idle(page)) +		u |= 1 << KPF_IDLE; +  	u |= kpf_copy_bit(k, KPF_LOCKED,	PG_locked);  	u |= kpf_copy_bit(k, KPF_SLAB,		PG_slab); @@ -212,6 +221,8 @@ static ssize_t kpageflags_read(struct file *file, char __user *buf,  		pfn++;  		out++;  		count -= KPMSIZE; + +		cond_resched();  	}  	*ppos += (char __user *)out - buf; @@ -225,10 +236,64 @@ static const struct file_operations proc_kpageflags_operations = {  	.read = kpageflags_read,  }; +#ifdef CONFIG_MEMCG +static ssize_t kpagecgroup_read(struct file *file, char __user *buf, +				size_t count, loff_t *ppos) +{ +	u64 __user *out = (u64 __user *)buf; +	struct page *ppage; +	unsigned long src = *ppos; +	unsigned long pfn; +	ssize_t ret = 0; +	u64 ino; + +	pfn = src / KPMSIZE; +	count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src); +	if (src & KPMMASK || count & KPMMASK) +		return -EINVAL; + +	while (count > 0) { +		if (pfn_valid(pfn)) +			ppage = pfn_to_page(pfn); +		else +			ppage = NULL; + +		if (ppage) +			ino = page_cgroup_ino(ppage); +		else +			ino = 0; + +		if (put_user(ino, out)) { +			ret = -EFAULT; +			break; +		} + +		pfn++; +		out++; +		count -= KPMSIZE; + +		cond_resched(); +	} + +	*ppos += (char __user *)out - buf; +	if (!ret) +		ret = (char __user *)out - buf; +	return ret; +} + +static const struct file_operations proc_kpagecgroup_operations = { +	.llseek = mem_lseek, +	.read = kpagecgroup_read, +}; +#endif /* CONFIG_MEMCG */ +  static int __init proc_page_init(void)  {  	proc_create("kpagecount", S_IRUSR, NULL, &proc_kpagecount_operations);  	proc_create("kpageflags", S_IRUSR, NULL, &proc_kpageflags_operations); +#ifdef CONFIG_MEMCG +	proc_create("kpagecgroup", S_IRUSR, NULL, &proc_kpagecgroup_operations); +#endif  	return 0;  }  fs_initcall(proc_page_init);  |