History

mm: memcg: fix test for child groups

When memcg code needs to know whether any given memcg has children, it uses the cgroup child iteration primitives and returns true/false depending on whether the iteration loop is executed at least once or not. Because a cgroup's list of children is RCU protected, these primitives require the RCU read-lock to be held, which is not the case for all memcg callers. This results in the following splat when e.g. enabling hierarchy mode: WARNING: CPU: 3 PID: 1 at kernel/cgroup.c:3043 css_next_child+0xa3/0x160() CPU: 3 PID: 1 Comm: systemd Not tainted 3.12.0-rc5-00117-g83f11a9-dirty #18 Hardware name: LENOVO 3680B56/3680B56, BIOS 6QET69WW (1.39 ) 04/26/2012 Call Trace: dump_stack+0x54/0x74 warn_slowpath_common+0x78/0xa0 warn_slowpath_null+0x1a/0x20 css_next_child+0xa3/0x160 mem_cgroup_hierarchy_write+0x5b/0xa0 cgroup_file_write+0x108/0x2a0 vfs_write+0xbd/0x1e0 SyS_write+0x4c/0xa0 system_call_fastpath+0x16/0x1b In the memcg case, we only care about children when we are attempting to modify inheritable attributes interactively. Racing with deletion could mean a spurious -EBUSY, no problem. Racing with addition is handled just fine as well through the memcg_create_mutex: if the child group is not on the list after the mutex is acquired, it won't be initialized from the parent's attributes until after the unlock.

Johannes Weiner committed 13 years ago

Commit 696ac171 parent 0056f4e1 file · +11 −24Browse files

Unified · Split

mm/memcontrol.c+11−24
@@ -4959,31 +4959,18 @@ static void mem_cgroup_reparent_charges(struct mem_cgroup *memcg) · 4958 unmodified lines
49594959 } while (usage > 0);
49604960 }
49614961
4962−/*
4963− * This mainly exists for tests during the setting of set of use_hierarchy.
4964− * Since this is the very setting we are changing, the current hierarchy value
4965− * is meaningless
4966− */
4967−static inline bool __memcg_has_children(struct mem_cgroup *memcg)
4968−{
4969− struct cgroup_subsys_state *pos;
4970−
4971− /* bounce at first found */
4972− css_for_each_child(pos, &memcg->css)
4973− return true;
4974− return false;
4975−}
4976−
4977−/*
4978− * Must be called with memcg_create_mutex held, unless the cgroup is guaranteed
4979− * to be already dead (as in mem_cgroup_force_empty, for instance). This is
4980− * from mem_cgroup_count_children(), in the sense that we don't really care how
4981− * many children we have; we only need to know if we have any. It also counts
4982− * any memcg without hierarchy as infertile.
4983− */
49844962 static inline bool memcg_has_children(struct mem_cgroup *memcg)
49854963 {
4986− return memcg->use_hierarchy && __memcg_has_children(memcg);
4964+ lockdep_assert_held(&memcg_create_mutex);
4965+ /*
4966+ * The lock does not prevent addition or deletion to the list
4967+ * of children, but it prevents a new child from being
4968+ * initialized based on this parent in css_online(), so it's
4969+ * enough to decide whether hierarchically inherited
4970+ * attributes can still be changed or not.
4971+ */
4972+ return memcg->use_hierarchy &&
4973+ !list_empty(&memcg->css.cgroup->children);
49874974 }
49884975
49894976 /*
@@ -5063,7 +5050,7 @@ static int mem_cgroup_hierarchy_write(struct cgroup_subsys_state *css, · 73 unmodified lines
50635050 */
50645051 if ((!parent_memcg || !parent_memcg->use_hierarchy) &&
50655052 (val == 1 || val == 0)) {
5066− if (!__memcg_has_children(memcg))
5053+ if (list_empty(&memcg->css.cgroup->children))
50675054 memcg->use_hierarchy = val;
50685055 else
50695056 retval = -EBUSY;