diff for duplicates of <4FE19102.6030704@parallels.com> diff --git a/a/2.txt b/N1/2.txt index 2580a00..8b13789 100644 --- a/a/2.txt +++ b/N1/2.txt @@ -1,167 +1 @@ -From e78b084162cb638129ae491167af14c29c57d52d Mon Sep 17 00:00:00 2001 -From: Glauber Costa <glommer@parallels.com> -Date: Mon, 21 May 2012 15:18:42 +0400 -Subject: [PATCH] memcg: propagate kmem limiting information to children -The current memcg slab cache management fails to present satisfatory hierarchical -behavior in the following scenario: - --> /cgroups/memory/A/B/C - -* kmem limit set at A -* A and B empty taskwise -* bash in C does find / - -Because kmem_accounted is a boolean that was not set for C, no accounting -would be done. This is, however, not what we expect. - -The basic idea, is that when a cgroup is limited, we walk the tree -upwards (something Kame and I already thought about doing for other purposes), -and make sure that we store the information about the parent being limited in -kmem_accounted (that is turned into a bitmap: two booleans would not be space -efficient). The code for that is taken from sched/core.c. My reasons for not -putting it into a common place is to dodge the type issues that would arise -from a common implementation between memcg and the scheduler - but I think -that it should ultimately happen, so if you want me to do it now, let me -know. - -We do the reverse operation when a formerly limited cgroup becomes unlimited. - -Signed-off-by: Glauber Costa <glommer@parallels.com> -CC: Christoph Lameter <cl@linux.com> -CC: Pekka Enberg <penberg@cs.helsinki.fi> -CC: Michal Hocko <mhocko@suse.cz> -CC: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> -CC: Johannes Weiner <hannes@cmpxchg.org> -CC: Suleiman Souhlal <suleiman@google.com> ---- - mm/memcontrol.c | 86 +++++++++++++++++++++++++++++++++++++++++++++---------- - 1 file changed, 71 insertions(+), 15 deletions(-) - -diff --git a/mm/memcontrol.c b/mm/memcontrol.c -index 22eaf15..5f02899 100644 ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -274,7 +274,11 @@ struct mem_cgroup { - * Should the accounting and control be hierarchical, per subtree? - */ - bool use_hierarchy; -- bool kmem_accounted; -+ /* -+ * bit0: accounted by this cgroup -+ * bit1: accounted by a parent. -+ */ -+ volatile unsigned long kmem_accounted; - - bool oom_lock; - atomic_t under_oom; -@@ -332,6 +336,9 @@ struct mem_cgroup { - #endif - }; - -+#define KMEM_ACCOUNTED_THIS 0 -+#define KMEM_ACCOUNTED_PARENT 1 -+ - int memcg_css_id(struct mem_cgroup *memcg) - { - return css_id(&memcg->css); -@@ -474,7 +481,7 @@ void sock_release_memcg(struct sock *sk) - - static void disarm_static_keys(struct mem_cgroup *memcg) - { -- if (memcg->kmem_accounted) -+ if (test_bit(KMEM_ACCOUNTED_THIS, &memcg->kmem_accounted)) - static_key_slow_dec(&mem_cgroup_kmem_enabled_key); - /* - * This check can't live in kmem destruction function, -@@ -4418,6 +4425,66 @@ static ssize_t mem_cgroup_read(struct cgroup *cont, struct cftype *cft, - len = scnprintf(str, sizeof(str), "%llu\n", (unsigned long long)val); - return simple_read_from_buffer(buf, nbytes, ppos, str, len); - } -+ -+#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM -+static void mem_cgroup_update_kmem_limit(struct mem_cgroup *memcg, u64 val) -+{ -+ struct mem_cgroup *iter; -+ -+ mutex_lock(&set_limit_mutex); -+ if (!test_and_set_bit(KMEM_ACCOUNTED_THIS, &memcg->kmem_accounted) && -+ val != RESOURCE_MAX) { -+ -+ /* -+ * Once enabled, can't be disabled. We could in theory -+ * disable it if we haven't yet created any caches, or -+ * if we can shrink them all to death. -+ * -+ * But it is not worth the trouble -+ */ -+ static_key_slow_inc(&mem_cgroup_kmem_enabled_key); -+ -+ if (!memcg->use_hierarchy) -+ goto out; -+ -+ for_each_mem_cgroup_tree(iter, memcg) { -+ if (iter == memcg) -+ continue; -+ set_bit(KMEM_ACCOUNTED_PARENT, &iter->kmem_accounted); -+ } -+ -+ } else if (test_and_clear_bit(KMEM_ACCOUNTED_THIS, &memcg->kmem_accounted) -+ && val == RESOURCE_MAX) { -+ -+ if (!memcg->use_hierarchy) -+ goto out; -+ -+ for_each_mem_cgroup_tree(iter, memcg) { -+ struct mem_cgroup *parent; -+ if (iter == memcg) -+ continue; -+ /* -+ * We should only have our parent bit cleared if none of -+ * ouri parents are accounted. The transversal order of -+ * our iter function forces us to always look at the -+ * parents. -+ */ -+ parent = parent_mem_cgroup(iter); -+ while (parent && (parent != memcg)) { -+ if (test_bit(KMEM_ACCOUNTED_THIS, &parent->kmem_accounted)) -+ goto noclear; -+ -+ parent = parent_mem_cgroup(parent); -+ } -+ clear_bit(KMEM_ACCOUNTED_PARENT, &iter->kmem_accounted); -+noclear: -+ continue; -+ } -+ } -+out: -+ mutex_unlock(&set_limit_mutex); -+} -+#endif - /* - * The user of this function is... - * RES_LIMIT. -@@ -4455,19 +4522,8 @@ static int mem_cgroup_write(struct cgroup *cont, struct cftype *cft, - ret = res_counter_set_limit(&memcg->kmem, val); - if (ret) - break; -- /* -- * Once enabled, can't be disabled. We could in theory -- * disable it if we haven't yet created any caches, or -- * if we can shrink them all to death. -- * -- * But it is not worth the trouble -- */ -- mutex_lock(&set_limit_mutex); -- if (!memcg->kmem_accounted && val != RESOURCE_MAX) { -- static_key_slow_inc(&mem_cgroup_kmem_enabled_key); -- memcg->kmem_accounted = true; -- } -- mutex_unlock(&set_limit_mutex); -+ mem_cgroup_update_kmem_limit(memcg, val); -+ break; - } - #endif - else --- -1.7.10.2 diff --git a/a/content_digest b/N1/content_digest index 76f0463..00e46e2 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -121,172 +121,5 @@ "\01:2\0" "fn\00001-memcg-propagate-kmem-limiting-information-to-childre.patch\0" "b\0" - "From e78b084162cb638129ae491167af14c29c57d52d Mon Sep 17 00:00:00 2001\n" - "From: Glauber Costa <glommer@parallels.com>\n" - "Date: Mon, 21 May 2012 15:18:42 +0400\n" - "Subject: [PATCH] memcg: propagate kmem limiting information to children\n" - "\n" - "The current memcg slab cache management fails to present satisfatory hierarchical\n" - "behavior in the following scenario:\n" - "\n" - "-> /cgroups/memory/A/B/C\n" - "\n" - "* kmem limit set at A\n" - "* A and B empty taskwise\n" - "* bash in C does find /\n" - "\n" - "Because kmem_accounted is a boolean that was not set for C, no accounting\n" - "would be done. This is, however, not what we expect.\n" - "\n" - "The basic idea, is that when a cgroup is limited, we walk the tree\n" - "upwards (something Kame and I already thought about doing for other purposes),\n" - "and make sure that we store the information about the parent being limited in\n" - "kmem_accounted (that is turned into a bitmap: two booleans would not be space\n" - "efficient). The code for that is taken from sched/core.c. My reasons for not\n" - "putting it into a common place is to dodge the type issues that would arise\n" - "from a common implementation between memcg and the scheduler - but I think\n" - "that it should ultimately happen, so if you want me to do it now, let me\n" - "know.\n" - "\n" - "We do the reverse operation when a formerly limited cgroup becomes unlimited.\n" - "\n" - "Signed-off-by: Glauber Costa <glommer@parallels.com>\n" - "CC: Christoph Lameter <cl@linux.com>\n" - "CC: Pekka Enberg <penberg@cs.helsinki.fi>\n" - "CC: Michal Hocko <mhocko@suse.cz>\n" - "CC: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>\n" - "CC: Johannes Weiner <hannes@cmpxchg.org>\n" - "CC: Suleiman Souhlal <suleiman@google.com>\n" - "---\n" - " mm/memcontrol.c | 86 +++++++++++++++++++++++++++++++++++++++++++++----------\n" - " 1 file changed, 71 insertions(+), 15 deletions(-)\n" - "\n" - "diff --git a/mm/memcontrol.c b/mm/memcontrol.c\n" - "index 22eaf15..5f02899 100644\n" - "--- a/mm/memcontrol.c\n" - "+++ b/mm/memcontrol.c\n" - "@@ -274,7 +274,11 @@ struct mem_cgroup {\n" - " \t * Should the accounting and control be hierarchical, per subtree?\n" - " \t */\n" - " \tbool use_hierarchy;\n" - "-\tbool kmem_accounted;\n" - "+\t/*\n" - "+\t * bit0: accounted by this cgroup\n" - "+\t * bit1: accounted by a parent.\n" - "+\t */\n" - "+\tvolatile unsigned long kmem_accounted;\n" - " \n" - " \tbool\t\toom_lock;\n" - " \tatomic_t\tunder_oom;\n" - "@@ -332,6 +336,9 @@ struct mem_cgroup {\n" - " #endif\n" - " };\n" - " \n" - "+#define KMEM_ACCOUNTED_THIS\t0\n" - "+#define KMEM_ACCOUNTED_PARENT\t1\n" - "+\n" - " int memcg_css_id(struct mem_cgroup *memcg)\n" - " {\n" - " \treturn css_id(&memcg->css);\n" - "@@ -474,7 +481,7 @@ void sock_release_memcg(struct sock *sk)\n" - " \n" - " static void disarm_static_keys(struct mem_cgroup *memcg)\n" - " {\n" - "-\tif (memcg->kmem_accounted)\n" - "+\tif (test_bit(KMEM_ACCOUNTED_THIS, &memcg->kmem_accounted))\n" - " \t\tstatic_key_slow_dec(&mem_cgroup_kmem_enabled_key);\n" - " \t/*\n" - " \t * This check can't live in kmem destruction function,\n" - "@@ -4418,6 +4425,66 @@ static ssize_t mem_cgroup_read(struct cgroup *cont, struct cftype *cft,\n" - " \tlen = scnprintf(str, sizeof(str), \"%llu\\n\", (unsigned long long)val);\n" - " \treturn simple_read_from_buffer(buf, nbytes, ppos, str, len);\n" - " }\n" - "+\n" - "+#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM\n" - "+static void mem_cgroup_update_kmem_limit(struct mem_cgroup *memcg, u64 val)\n" - "+{\n" - "+\tstruct mem_cgroup *iter;\n" - "+\n" - "+\tmutex_lock(&set_limit_mutex);\n" - "+\tif (!test_and_set_bit(KMEM_ACCOUNTED_THIS, &memcg->kmem_accounted) &&\n" - "+\t\tval != RESOURCE_MAX) {\n" - "+\n" - "+\t\t/*\n" - "+\t\t * Once enabled, can't be disabled. We could in theory\n" - "+\t\t * disable it if we haven't yet created any caches, or\n" - "+\t\t * if we can shrink them all to death.\n" - "+\t\t *\n" - "+\t\t * But it is not worth the trouble\n" - "+\t\t */\n" - "+\t\tstatic_key_slow_inc(&mem_cgroup_kmem_enabled_key);\n" - "+\n" - "+\t\tif (!memcg->use_hierarchy)\n" - "+\t\t\tgoto out;\n" - "+\n" - "+\t\tfor_each_mem_cgroup_tree(iter, memcg) {\n" - "+\t\t\tif (iter == memcg)\n" - "+\t\t\t\tcontinue;\n" - "+\t\t\tset_bit(KMEM_ACCOUNTED_PARENT, &iter->kmem_accounted);\n" - "+\t\t}\n" - "+\n" - "+\t} else if (test_and_clear_bit(KMEM_ACCOUNTED_THIS, &memcg->kmem_accounted)\n" - "+\t\t&& val == RESOURCE_MAX) {\n" - "+\n" - "+\t\tif (!memcg->use_hierarchy)\n" - "+\t\t\tgoto out;\n" - "+\n" - "+\t\tfor_each_mem_cgroup_tree(iter, memcg) {\n" - "+\t\t\tstruct mem_cgroup *parent;\n" - "+\t\t\tif (iter == memcg)\n" - "+\t\t\t\tcontinue;\n" - "+\t\t\t/*\n" - "+\t\t\t * We should only have our parent bit cleared if none of\n" - "+\t\t\t * ouri parents are accounted. The transversal order of\n" - "+\t\t\t * our iter function forces us to always look at the\n" - "+\t\t\t * parents.\n" - "+\t\t\t */\n" - "+\t\t\tparent = parent_mem_cgroup(iter);\n" - "+\t\t\twhile (parent && (parent != memcg)) {\n" - "+\t\t\t\tif (test_bit(KMEM_ACCOUNTED_THIS, &parent->kmem_accounted))\n" - "+\t\t\t\t\tgoto noclear;\n" - "+\t\t\t\t\t\n" - "+\t\t\t\tparent = parent_mem_cgroup(parent);\n" - "+\t\t\t}\n" - "+\t\t\tclear_bit(KMEM_ACCOUNTED_PARENT, &iter->kmem_accounted);\n" - "+noclear:\n" - "+\t\t\tcontinue;\n" - "+\t\t}\n" - "+\t}\n" - "+out:\n" - "+\tmutex_unlock(&set_limit_mutex);\n" - "+}\n" - "+#endif\n" - " /*\n" - " * The user of this function is...\n" - " * RES_LIMIT.\n" - "@@ -4455,19 +4522,8 @@ static int mem_cgroup_write(struct cgroup *cont, struct cftype *cft,\n" - " \t\t\tret = res_counter_set_limit(&memcg->kmem, val);\n" - " \t\t\tif (ret)\n" - " \t\t\t\tbreak;\n" - "-\t\t\t/*\n" - "-\t\t\t * Once enabled, can't be disabled. We could in theory\n" - "-\t\t\t * disable it if we haven't yet created any caches, or\n" - "-\t\t\t * if we can shrink them all to death.\n" - "-\t\t\t *\n" - "-\t\t\t * But it is not worth the trouble\n" - "-\t\t\t */\n" - "-\t\t\tmutex_lock(&set_limit_mutex);\n" - "-\t\t\tif (!memcg->kmem_accounted && val != RESOURCE_MAX) {\n" - "-\t\t\t\tstatic_key_slow_inc(&mem_cgroup_kmem_enabled_key);\n" - "-\t\t\t\tmemcg->kmem_accounted = true;\n" - "-\t\t\t}\n" - "-\t\t\tmutex_unlock(&set_limit_mutex);\n" - "+\t\t\tmem_cgroup_update_kmem_limit(memcg, val);\n" - "+\t\t\tbreak;\n" - " \t\t}\n" - " #endif\n" - " \t\telse\n" - "-- \n" - 1.7.10.2 -22d5b72f380408134448396b4bf038348918a9d01185a94804d3b54276e790e0 +4f09010e54b96d8523b06e511585934fbb28c0176929ddd2da0ce7b3df411eee
diff --git a/a/2.txt b/N2/2.txt index 2580a00..63f9bc6 100644 --- a/a/2.txt +++ b/N2/2.txt @@ -1,4 +1,4 @@ -From e78b084162cb638129ae491167af14c29c57d52d Mon Sep 17 00:00:00 2001 +>From e78b084162cb638129ae491167af14c29c57d52d Mon Sep 17 00:00:00 2001 From: Glauber Costa <glommer@parallels.com> Date: Mon, 21 May 2012 15:18:42 +0400 Subject: [PATCH] memcg: propagate kmem limiting information to children diff --git a/a/content_digest b/N2/content_digest index 76f0463..3225f1d 100644 --- a/a/content_digest +++ b/N2/content_digest @@ -9,13 +9,13 @@ "Subject\0Re: [PATCH v4 23/25] memcg: propagate kmem limiting information to children\0" "Date\0Wed, 20 Jun 2012 12:59:46 +0400\0" "To\0Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>\0" - "Cc\0linux-mm@kvack.org" + "Cc\0<linux-mm@kvack.org>" Pekka Enberg <penberg@kernel.org> Cristoph Lameter <cl@linux.com> David Rientjes <rientjes@google.com> - cgroups@vger.kernel.org - devel@openvz.org - linux-kernel@vger.kernel.org + <cgroups@vger.kernel.org> + <devel@openvz.org> + <linux-kernel@vger.kernel.org> Frederic Weisbecker <fweisbec@gmail.com> Suleiman Souhlal <suleiman@google.com> Pekka Enberg <penberg@cs.helsinki.fi> @@ -121,7 +121,7 @@ "\01:2\0" "fn\00001-memcg-propagate-kmem-limiting-information-to-childre.patch\0" "b\0" - "From e78b084162cb638129ae491167af14c29c57d52d Mon Sep 17 00:00:00 2001\n" + ">From e78b084162cb638129ae491167af14c29c57d52d Mon Sep 17 00:00:00 2001\n" "From: Glauber Costa <glommer@parallels.com>\n" "Date: Mon, 21 May 2012 15:18:42 +0400\n" "Subject: [PATCH] memcg: propagate kmem limiting information to children\n" @@ -289,4 +289,4 @@ "-- \n" 1.7.10.2 -22d5b72f380408134448396b4bf038348918a9d01185a94804d3b54276e790e0 +a94eba02eb59ed4ab8fd50efe87283153f7a4edfa9863b9ae3649a0a2ca9e88d
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.