linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/4] memcg: fix memcg resource limit overflow issues
@ 2013-08-02  3:25 Qiang Huang
  2013-08-02  3:25 ` [PATCH v2 1/4] memcg: correct RESOURCE_MAX to ULLONG_MAX Qiang Huang
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Qiang Huang @ 2013-08-02  3:25 UTC (permalink / raw)
  To: akpm
  Cc: mhocko, lizefan, handai.szj, handai.szj, jeff.liu, nishimura,
	cgroups, linux-mm

This issue is first discussed in:
http://marc.info/?l=linux-mm&m=136574878704295&w=2

Then a second version sent to:
http://marc.info/?l=linux-mm&m=136776855928310&w=2

We contacted Sha a month ago, she seems have no time to deal with it 
recently, but we quite need this patch. So I modified and resent it.

Changes from v1:
* Added From: Sha Zhengju <handai.szj@taobao.com>
  (Sorry for the omission in the first version)
* Added Acked-by and Reviewed-by from Michal

Sha Zhengju (4):
  memcg: correct RESOURCE_MAX to ULLONG_MAX
  memcg: rename RESOURCE_MAX to RES_COUNTER_MAX
  memcg: avoid overflow caused by PAGE_ALIGN
  memcg: reduce function dereference

 include/linux/res_counter.h |  2 +-
 kernel/res_counter.c        | 25 ++++++++++++++++---------
 mm/memcontrol.c             |  4 ++--
 net/ipv4/tcp_memcontrol.c   | 10 +++++-----
 4 files changed, 24 insertions(+), 17 deletions(-)

-- 
1.8.3


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/4] memcg: correct RESOURCE_MAX to ULLONG_MAX
  2013-08-02  3:25 [PATCH v2 0/4] memcg: fix memcg resource limit overflow issues Qiang Huang
@ 2013-08-02  3:25 ` Qiang Huang
  2013-08-02  3:25 ` [PATCH v2 2/4] memcg: rename RESOURCE_MAX to RES_COUNTER_MAX Qiang Huang
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Qiang Huang @ 2013-08-02  3:25 UTC (permalink / raw)
  To: akpm
  Cc: mhocko, lizefan, handai.szj, handai.szj, jeff.liu, nishimura,
	cgroups, linux-mm

From: Sha Zhengju <handai.szj@taobao.com>

Current RESOURCE_MAX is ULONG_MAX, but the value we used to set resource
limit is unsigned long long, so we can set bigger value than that which
is strange. The XXX_MAX should be reasonable max value, bigger than that
should be overflow.

Notice that this change will affect user output of default *.limit_in_bytes:
before change:
$ cat /cgroup/memory/memory.limit_in_bytes
9223372036854775807

after change:
$ cat /cgroup/memory/memory.limit_in_bytes
18446744073709551615

But it doesn't alter the API in term of input - we can still use
"echo -1 > *.limit_in_bytes" to reset the numbers to "unlimited".

Signed-off-by: Sha Zhengju <handai.szj@taobao.com>
Signed-off-by: Qiang Huang <h.huangqiang@huawei.com>
Acked-by: Michal Hocko <mhocko@suse.cz>
---
 include/linux/res_counter.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/res_counter.h b/include/linux/res_counter.h
index 96a509b..586bc7c 100644
--- a/include/linux/res_counter.h
+++ b/include/linux/res_counter.h
@@ -54,7 +54,7 @@ struct res_counter {
 	struct res_counter *parent;
 };
 
-#define RESOURCE_MAX (unsigned long long)LLONG_MAX
+#define RESOURCE_MAX ULLONG_MAX
 
 /**
  * Helpers to interact with userspace
-- 
1.8.3


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/4] memcg: rename RESOURCE_MAX to RES_COUNTER_MAX
  2013-08-02  3:25 [PATCH v2 0/4] memcg: fix memcg resource limit overflow issues Qiang Huang
  2013-08-02  3:25 ` [PATCH v2 1/4] memcg: correct RESOURCE_MAX to ULLONG_MAX Qiang Huang
@ 2013-08-02  3:25 ` Qiang Huang
  2013-08-02  3:25 ` [PATCH v2 3/4] memcg: avoid overflow caused by PAGE_ALIGN Qiang Huang
  2013-08-02  3:25 ` [PATCH v2 4/4] memcg: reduce function dereference Qiang Huang
  3 siblings, 0 replies; 5+ messages in thread
From: Qiang Huang @ 2013-08-02  3:25 UTC (permalink / raw)
  To: akpm
  Cc: mhocko, lizefan, handai.szj, handai.szj, jeff.liu, nishimura,
	cgroups, linux-mm

From: Sha Zhengju <handai.szj@taobao.com>

RESOURCE_MAX is far too general name, change it to RES_COUNTER_MAX.

Signed-off-by: Sha Zhengju <handai.szj@taobao.com>
Signed-off-by: Qiang Huang <h.huangqiang@huawei.com>
Acked-by: Michal Hocko <mhocko@suse.cz>
---
 include/linux/res_counter.h |  2 +-
 kernel/res_counter.c        |  8 ++++----
 mm/memcontrol.c             |  4 ++--
 net/ipv4/tcp_memcontrol.c   | 10 +++++-----
 4 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/linux/res_counter.h b/include/linux/res_counter.h
index 586bc7c..201a697 100644
--- a/include/linux/res_counter.h
+++ b/include/linux/res_counter.h
@@ -54,7 +54,7 @@ struct res_counter {
 	struct res_counter *parent;
 };
 
-#define RESOURCE_MAX ULLONG_MAX
+#define RES_COUNTER_MAX ULLONG_MAX
 
 /**
  * Helpers to interact with userspace
diff --git a/kernel/res_counter.c b/kernel/res_counter.c
index ff55247..3f0417f 100644
--- a/kernel/res_counter.c
+++ b/kernel/res_counter.c
@@ -17,8 +17,8 @@
 void res_counter_init(struct res_counter *counter, struct res_counter *parent)
 {
 	spin_lock_init(&counter->lock);
-	counter->limit = RESOURCE_MAX;
-	counter->soft_limit = RESOURCE_MAX;
+	counter->limit = RES_COUNTER_MAX;
+	counter->soft_limit = RES_COUNTER_MAX;
 	counter->parent = parent;
 }
 
@@ -182,12 +182,12 @@ int res_counter_memparse_write_strategy(const char *buf,
 {
 	char *end;
 
-	/* return RESOURCE_MAX(unlimited) if "-1" is specified */
+	/* return RES_COUNTER_MAX(unlimited) if "-1" is specified */
 	if (*buf == '-') {
 		*res = simple_strtoull(buf + 1, &end, 10);
 		if (*res != 1 || *end != '\0')
 			return -EINVAL;
-		*res = RESOURCE_MAX;
+		*res = RES_COUNTER_MAX;
 		return 0;
 	}
 
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 1947218..f621cf5 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -5117,7 +5117,7 @@ static int memcg_update_kmem_limit(struct cgroup *cont, u64 val)
 	 */
 	mutex_lock(&memcg_create_mutex);
 	mutex_lock(&set_limit_mutex);
-	if (!memcg->kmem_account_flags && val != RESOURCE_MAX) {
+	if (!memcg->kmem_account_flags && val != RES_COUNTER_MAX) {
 		if (cgroup_task_count(cont) || memcg_has_children(memcg)) {
 			ret = -EBUSY;
 			goto out;
@@ -5127,7 +5127,7 @@ static int memcg_update_kmem_limit(struct cgroup *cont, u64 val)
 
 		ret = memcg_update_cache_sizes(memcg);
 		if (ret) {
-			res_counter_set_limit(&memcg->kmem, RESOURCE_MAX);
+			res_counter_set_limit(&memcg->kmem, RES_COUNTER_MAX);
 			goto out;
 		}
 		static_key_slow_inc(&memcg_kmem_enabled_key);
diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c
index da14436..90550f4 100644
--- a/net/ipv4/tcp_memcontrol.c
+++ b/net/ipv4/tcp_memcontrol.c
@@ -87,8 +87,8 @@ static int tcp_update_limit(struct mem_cgroup *memcg, u64 val)
 	if (!cg_proto)
 		return -EINVAL;
 
-	if (val > RESOURCE_MAX)
-		val = RESOURCE_MAX;
+	if (val > RES_COUNTER_MAX)
+		val = RES_COUNTER_MAX;
 
 	tcp = tcp_from_cgproto(cg_proto);
 
@@ -101,9 +101,9 @@ static int tcp_update_limit(struct mem_cgroup *memcg, u64 val)
 		tcp->tcp_prot_mem[i] = min_t(long, val >> PAGE_SHIFT,
 					     net->ipv4.sysctl_tcp_mem[i]);
 
-	if (val == RESOURCE_MAX)
+	if (val == RES_COUNTER_MAX)
 		clear_bit(MEMCG_SOCK_ACTIVE, &cg_proto->flags);
-	else if (val != RESOURCE_MAX) {
+	else if (val != RES_COUNTER_MAX) {
 		/*
 		 * The active bit needs to be written after the static_key
 		 * update. This is what guarantees that the socket activation
@@ -187,7 +187,7 @@ static u64 tcp_cgroup_read(struct cgroup *cont, struct cftype *cft)
 
 	switch (cft->private) {
 	case RES_LIMIT:
-		val = tcp_read_stat(memcg, RES_LIMIT, RESOURCE_MAX);
+		val = tcp_read_stat(memcg, RES_LIMIT, RES_COUNTER_MAX);
 		break;
 	case RES_USAGE:
 		val = tcp_read_usage(memcg);
-- 
1.8.3


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 3/4] memcg: avoid overflow caused by PAGE_ALIGN
  2013-08-02  3:25 [PATCH v2 0/4] memcg: fix memcg resource limit overflow issues Qiang Huang
  2013-08-02  3:25 ` [PATCH v2 1/4] memcg: correct RESOURCE_MAX to ULLONG_MAX Qiang Huang
  2013-08-02  3:25 ` [PATCH v2 2/4] memcg: rename RESOURCE_MAX to RES_COUNTER_MAX Qiang Huang
@ 2013-08-02  3:25 ` Qiang Huang
  2013-08-02  3:25 ` [PATCH v2 4/4] memcg: reduce function dereference Qiang Huang
  3 siblings, 0 replies; 5+ messages in thread
From: Qiang Huang @ 2013-08-02  3:25 UTC (permalink / raw)
  To: akpm
  Cc: mhocko, lizefan, handai.szj, handai.szj, jeff.liu, nishimura,
	cgroups, linux-mm

From: Sha Zhengju <handai.szj@taobao.com>

Since PAGE_ALIGN is aligning up(the next page boundary), so after PAGE_ALIGN,
the value might be overflow, such as write the MAX value to *.limit_in_bytes.

$ cat /cgroup/memory/memory.limit_in_bytes
18446744073709551615

# echo 18446744073709551615 > /cgroup/memory/memory.limit_in_bytes
bash: echo: write error: Invalid argument

Some user programs might depend on such behaviours(like libcg, we read the
value in snapshot, then use the value to reset cgroup later), and that
will cause confusion. So we need to fix it.

Signed-off-by: Sha Zhengju <handai.szj@taobao.com>
Signed-off-by: Qiang Huang <h.huangqiang@huawei.com>
Reviewed-by: Michal Hocko <mhocko@suse.cz>
---
 kernel/res_counter.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/kernel/res_counter.c b/kernel/res_counter.c
index 3f0417f..085d3ae 100644
--- a/kernel/res_counter.c
+++ b/kernel/res_counter.c
@@ -195,6 +195,10 @@ int res_counter_memparse_write_strategy(const char *buf,
 	if (*end != '\0')
 		return -EINVAL;
 
-	*res = PAGE_ALIGN(*res);
+	if (PAGE_ALIGN(*res) >= *res)
+		*res = PAGE_ALIGN(*res);
+	else
+		*res = RES_COUNTER_MAX;
+
 	return 0;
 }
-- 
1.8.3


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 4/4] memcg: reduce function dereference
  2013-08-02  3:25 [PATCH v2 0/4] memcg: fix memcg resource limit overflow issues Qiang Huang
                   ` (2 preceding siblings ...)
  2013-08-02  3:25 ` [PATCH v2 3/4] memcg: avoid overflow caused by PAGE_ALIGN Qiang Huang
@ 2013-08-02  3:25 ` Qiang Huang
  3 siblings, 0 replies; 5+ messages in thread
From: Qiang Huang @ 2013-08-02  3:25 UTC (permalink / raw)
  To: akpm
  Cc: mhocko, lizefan, handai.szj, handai.szj, jeff.liu, nishimura,
	cgroups, linux-mm

From: Sha Zhengju <handai.szj@taobao.com>

This function dereferences res far too often, so optimize it.

Signed-off-by: Sha Zhengju <handai.szj@taobao.com>
Signed-off-by: Qiang Huang <h.huangqiang@huawei.com>
Reviewed-by: Michal Hocko <mhocko@suse.cz>
---
 kernel/res_counter.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/kernel/res_counter.c b/kernel/res_counter.c
index 085d3ae..4aa8a30 100644
--- a/kernel/res_counter.c
+++ b/kernel/res_counter.c
@@ -178,27 +178,30 @@ u64 res_counter_read_u64(struct res_counter *counter, int member)
 #endif
 
 int res_counter_memparse_write_strategy(const char *buf,
-					unsigned long long *res)
+					unsigned long long *resp)
 {
 	char *end;
+	unsigned long long res;
 
 	/* return RES_COUNTER_MAX(unlimited) if "-1" is specified */
 	if (*buf == '-') {
-		*res = simple_strtoull(buf + 1, &end, 10);
-		if (*res != 1 || *end != '\0')
+		res = simple_strtoull(buf + 1, &end, 10);
+		if (res != 1 || *end != '\0')
 			return -EINVAL;
-		*res = RES_COUNTER_MAX;
+		*resp = RES_COUNTER_MAX;
 		return 0;
 	}
 
-	*res = memparse(buf, &end);
+	res = memparse(buf, &end);
 	if (*end != '\0')
 		return -EINVAL;
 
-	if (PAGE_ALIGN(*res) >= *res)
-		*res = PAGE_ALIGN(*res);
+	if (PAGE_ALIGN(res) >= res)
+		res = PAGE_ALIGN(res);
 	else
-		*res = RES_COUNTER_MAX;
+		res = RES_COUNTER_MAX;
+
+	*resp = res;
 
 	return 0;
 }
-- 
1.8.3


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-08-02  3:26 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-02  3:25 [PATCH v2 0/4] memcg: fix memcg resource limit overflow issues Qiang Huang
2013-08-02  3:25 ` [PATCH v2 1/4] memcg: correct RESOURCE_MAX to ULLONG_MAX Qiang Huang
2013-08-02  3:25 ` [PATCH v2 2/4] memcg: rename RESOURCE_MAX to RES_COUNTER_MAX Qiang Huang
2013-08-02  3:25 ` [PATCH v2 3/4] memcg: avoid overflow caused by PAGE_ALIGN Qiang Huang
2013-08-02  3:25 ` [PATCH v2 4/4] memcg: reduce function dereference Qiang Huang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).