diff options
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r-- | mm/memcontrol.c | 65 |
1 files changed, 31 insertions, 34 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 7d698df4a067..97a45b392f77 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -3879,14 +3879,21 @@ static inline u64 mem_cgroup_usage(struct mem_cgroup *memcg, bool swap) | |||
3879 | return val << PAGE_SHIFT; | 3879 | return val << PAGE_SHIFT; |
3880 | } | 3880 | } |
3881 | 3881 | ||
3882 | static u64 mem_cgroup_read(struct cgroup *cont, struct cftype *cft) | 3882 | static ssize_t mem_cgroup_read(struct cgroup *cont, struct cftype *cft, |
3883 | struct file *file, char __user *buf, | ||
3884 | size_t nbytes, loff_t *ppos) | ||
3883 | { | 3885 | { |
3884 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); | 3886 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); |
3887 | char str[64]; | ||
3885 | u64 val; | 3888 | u64 val; |
3886 | int type, name; | 3889 | int type, name, len; |
3887 | 3890 | ||
3888 | type = MEMFILE_TYPE(cft->private); | 3891 | type = MEMFILE_TYPE(cft->private); |
3889 | name = MEMFILE_ATTR(cft->private); | 3892 | name = MEMFILE_ATTR(cft->private); |
3893 | |||
3894 | if (!do_swap_account && type == _MEMSWAP) | ||
3895 | return -EOPNOTSUPP; | ||
3896 | |||
3890 | switch (type) { | 3897 | switch (type) { |
3891 | case _MEM: | 3898 | case _MEM: |
3892 | if (name == RES_USAGE) | 3899 | if (name == RES_USAGE) |
@@ -3903,7 +3910,9 @@ static u64 mem_cgroup_read(struct cgroup *cont, struct cftype *cft) | |||
3903 | default: | 3910 | default: |
3904 | BUG(); | 3911 | BUG(); |
3905 | } | 3912 | } |
3906 | return val; | 3913 | |
3914 | len = scnprintf(str, sizeof(str), "%llu\n", (unsigned long long)val); | ||
3915 | return simple_read_from_buffer(buf, nbytes, ppos, str, len); | ||
3907 | } | 3916 | } |
3908 | /* | 3917 | /* |
3909 | * The user of this function is... | 3918 | * The user of this function is... |
@@ -3919,6 +3928,10 @@ static int mem_cgroup_write(struct cgroup *cont, struct cftype *cft, | |||
3919 | 3928 | ||
3920 | type = MEMFILE_TYPE(cft->private); | 3929 | type = MEMFILE_TYPE(cft->private); |
3921 | name = MEMFILE_ATTR(cft->private); | 3930 | name = MEMFILE_ATTR(cft->private); |
3931 | |||
3932 | if (!do_swap_account && type == _MEMSWAP) | ||
3933 | return -EOPNOTSUPP; | ||
3934 | |||
3922 | switch (name) { | 3935 | switch (name) { |
3923 | case RES_LIMIT: | 3936 | case RES_LIMIT: |
3924 | if (mem_cgroup_is_root(memcg)) { /* Can't set limit on root */ | 3937 | if (mem_cgroup_is_root(memcg)) { /* Can't set limit on root */ |
@@ -3984,12 +3997,15 @@ out: | |||
3984 | 3997 | ||
3985 | static int mem_cgroup_reset(struct cgroup *cont, unsigned int event) | 3998 | static int mem_cgroup_reset(struct cgroup *cont, unsigned int event) |
3986 | { | 3999 | { |
3987 | struct mem_cgroup *memcg; | 4000 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); |
3988 | int type, name; | 4001 | int type, name; |
3989 | 4002 | ||
3990 | memcg = mem_cgroup_from_cont(cont); | ||
3991 | type = MEMFILE_TYPE(event); | 4003 | type = MEMFILE_TYPE(event); |
3992 | name = MEMFILE_ATTR(event); | 4004 | name = MEMFILE_ATTR(event); |
4005 | |||
4006 | if (!do_swap_account && type == _MEMSWAP) | ||
4007 | return -EOPNOTSUPP; | ||
4008 | |||
3993 | switch (name) { | 4009 | switch (name) { |
3994 | case RES_MAX_USAGE: | 4010 | case RES_MAX_USAGE: |
3995 | if (type == _MEM) | 4011 | if (type == _MEM) |
@@ -4655,7 +4671,7 @@ static struct cftype mem_cgroup_files[] = { | |||
4655 | { | 4671 | { |
4656 | .name = "usage_in_bytes", | 4672 | .name = "usage_in_bytes", |
4657 | .private = MEMFILE_PRIVATE(_MEM, RES_USAGE), | 4673 | .private = MEMFILE_PRIVATE(_MEM, RES_USAGE), |
4658 | .read_u64 = mem_cgroup_read, | 4674 | .read = mem_cgroup_read, |
4659 | .register_event = mem_cgroup_usage_register_event, | 4675 | .register_event = mem_cgroup_usage_register_event, |
4660 | .unregister_event = mem_cgroup_usage_unregister_event, | 4676 | .unregister_event = mem_cgroup_usage_unregister_event, |
4661 | }, | 4677 | }, |
@@ -4663,25 +4679,25 @@ static struct cftype mem_cgroup_files[] = { | |||
4663 | .name = "max_usage_in_bytes", | 4679 | .name = "max_usage_in_bytes", |
4664 | .private = MEMFILE_PRIVATE(_MEM, RES_MAX_USAGE), | 4680 | .private = MEMFILE_PRIVATE(_MEM, RES_MAX_USAGE), |
4665 | .trigger = mem_cgroup_reset, | 4681 | .trigger = mem_cgroup_reset, |
4666 | .read_u64 = mem_cgroup_read, | 4682 | .read = mem_cgroup_read, |
4667 | }, | 4683 | }, |
4668 | { | 4684 | { |
4669 | .name = "limit_in_bytes", | 4685 | .name = "limit_in_bytes", |
4670 | .private = MEMFILE_PRIVATE(_MEM, RES_LIMIT), | 4686 | .private = MEMFILE_PRIVATE(_MEM, RES_LIMIT), |
4671 | .write_string = mem_cgroup_write, | 4687 | .write_string = mem_cgroup_write, |
4672 | .read_u64 = mem_cgroup_read, | 4688 | .read = mem_cgroup_read, |
4673 | }, | 4689 | }, |
4674 | { | 4690 | { |
4675 | .name = "soft_limit_in_bytes", | 4691 | .name = "soft_limit_in_bytes", |
4676 | .private = MEMFILE_PRIVATE(_MEM, RES_SOFT_LIMIT), | 4692 | .private = MEMFILE_PRIVATE(_MEM, RES_SOFT_LIMIT), |
4677 | .write_string = mem_cgroup_write, | 4693 | .write_string = mem_cgroup_write, |
4678 | .read_u64 = mem_cgroup_read, | 4694 | .read = mem_cgroup_read, |
4679 | }, | 4695 | }, |
4680 | { | 4696 | { |
4681 | .name = "failcnt", | 4697 | .name = "failcnt", |
4682 | .private = MEMFILE_PRIVATE(_MEM, RES_FAILCNT), | 4698 | .private = MEMFILE_PRIVATE(_MEM, RES_FAILCNT), |
4683 | .trigger = mem_cgroup_reset, | 4699 | .trigger = mem_cgroup_reset, |
4684 | .read_u64 = mem_cgroup_read, | 4700 | .read = mem_cgroup_read, |
4685 | }, | 4701 | }, |
4686 | { | 4702 | { |
4687 | .name = "stat", | 4703 | .name = "stat", |
@@ -4721,14 +4737,11 @@ static struct cftype mem_cgroup_files[] = { | |||
4721 | .mode = S_IRUGO, | 4737 | .mode = S_IRUGO, |
4722 | }, | 4738 | }, |
4723 | #endif | 4739 | #endif |
4724 | }; | ||
4725 | |||
4726 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP | 4740 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP |
4727 | static struct cftype memsw_cgroup_files[] = { | ||
4728 | { | 4741 | { |
4729 | .name = "memsw.usage_in_bytes", | 4742 | .name = "memsw.usage_in_bytes", |
4730 | .private = MEMFILE_PRIVATE(_MEMSWAP, RES_USAGE), | 4743 | .private = MEMFILE_PRIVATE(_MEMSWAP, RES_USAGE), |
4731 | .read_u64 = mem_cgroup_read, | 4744 | .read = mem_cgroup_read, |
4732 | .register_event = mem_cgroup_usage_register_event, | 4745 | .register_event = mem_cgroup_usage_register_event, |
4733 | .unregister_event = mem_cgroup_usage_unregister_event, | 4746 | .unregister_event = mem_cgroup_usage_unregister_event, |
4734 | }, | 4747 | }, |
@@ -4736,35 +4749,22 @@ static struct cftype memsw_cgroup_files[] = { | |||
4736 | .name = "memsw.max_usage_in_bytes", | 4749 | .name = "memsw.max_usage_in_bytes", |
4737 | .private = MEMFILE_PRIVATE(_MEMSWAP, RES_MAX_USAGE), | 4750 | .private = MEMFILE_PRIVATE(_MEMSWAP, RES_MAX_USAGE), |
4738 | .trigger = mem_cgroup_reset, | 4751 | .trigger = mem_cgroup_reset, |
4739 | .read_u64 = mem_cgroup_read, | 4752 | .read = mem_cgroup_read, |
4740 | }, | 4753 | }, |
4741 | { | 4754 | { |
4742 | .name = "memsw.limit_in_bytes", | 4755 | .name = "memsw.limit_in_bytes", |
4743 | .private = MEMFILE_PRIVATE(_MEMSWAP, RES_LIMIT), | 4756 | .private = MEMFILE_PRIVATE(_MEMSWAP, RES_LIMIT), |
4744 | .write_string = mem_cgroup_write, | 4757 | .write_string = mem_cgroup_write, |
4745 | .read_u64 = mem_cgroup_read, | 4758 | .read = mem_cgroup_read, |
4746 | }, | 4759 | }, |
4747 | { | 4760 | { |
4748 | .name = "memsw.failcnt", | 4761 | .name = "memsw.failcnt", |
4749 | .private = MEMFILE_PRIVATE(_MEMSWAP, RES_FAILCNT), | 4762 | .private = MEMFILE_PRIVATE(_MEMSWAP, RES_FAILCNT), |
4750 | .trigger = mem_cgroup_reset, | 4763 | .trigger = mem_cgroup_reset, |
4751 | .read_u64 = mem_cgroup_read, | 4764 | .read = mem_cgroup_read, |
4752 | }, | 4765 | }, |
4753 | }; | ||
4754 | |||
4755 | static int register_memsw_files(struct cgroup *cont, struct cgroup_subsys *ss) | ||
4756 | { | ||
4757 | if (!do_swap_account) | ||
4758 | return 0; | ||
4759 | return cgroup_add_files(cont, ss, memsw_cgroup_files, | ||
4760 | ARRAY_SIZE(memsw_cgroup_files)); | ||
4761 | }; | ||
4762 | #else | ||
4763 | static int register_memsw_files(struct cgroup *cont, struct cgroup_subsys *ss) | ||
4764 | { | ||
4765 | return 0; | ||
4766 | } | ||
4767 | #endif | 4766 | #endif |
4767 | }; | ||
4768 | 4768 | ||
4769 | static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node) | 4769 | static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node) |
4770 | { | 4770 | { |
@@ -5047,9 +5047,6 @@ static int mem_cgroup_populate(struct cgroup_subsys *ss, | |||
5047 | ARRAY_SIZE(mem_cgroup_files)); | 5047 | ARRAY_SIZE(mem_cgroup_files)); |
5048 | 5048 | ||
5049 | if (!ret) | 5049 | if (!ret) |
5050 | ret = register_memsw_files(cont, ss); | ||
5051 | |||
5052 | if (!ret) | ||
5053 | ret = register_kmem_files(cont, ss); | 5050 | ret = register_kmem_files(cont, ss); |
5054 | 5051 | ||
5055 | return ret; | 5052 | return ret; |