Skip to contentSkip to conversation

cgroup: a bunch of cleanups

PATCH In review Li Zefan 2 participants 12 messages Mar 12, 2013 – Mar 13, 2013

Subsystems (2)
lore
Share & tools
lore

Li Zefan

author
#0 lore raw

cover cgroup: a bunch of cleanups

Hi Tejun,

If you're busy with other stuff, just take your time to go through those patches.

0001-cgroup-remove-cgroup_is_descentant.patch 0002-cgroup-remove-unused-variables-in-cgroup_destroy_loc.patch 0003-cgroup-hold-cgroup_mutex-before-calling-css_offline.patch 0004-cgroup-don-t-bother-to-resize-pid-array.patch 0005-cgroup-remove-useless-code-in-cgroup_write_event_con.patch 0006-cgroup-remove-unneeded-includes-from-cgroup.h.patch 0007-cgroup-fix-an-almost-harmless-off-by-one-bug.patch 0008-cgroup-consolidate-cgroup_attach_task-and-cgroup_att.patch

---
 Documentation/cgroups/cgroups.txt |   1 +
 include/linux/cgroup.h            |  10 +--
 kernel/cgroup.c                   | 239 +++++++++++-----------------------------------------
 kernel/cpuset.c                   |   2 +-
 4 files changed, 52 insertions(+), 200 deletions(-)
author
#1 lore raw

PATCH 1/8 cgroup: remove cgroup_is_descentant()

It was used by ns cgroup, and ns cgroup was removed long ago.

---
 include/linux/cgroup.h |  3 ---
 kernel/cgroup.c        | 28 ----------------------------
 2 files changed, 31 deletions(-)
include/linux/cgroup.h +0 -3
index 5f76829..7e818a3 100644
@@ -448,9 +448,6 @@ int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen);
 
 int cgroup_task_count(const struct cgroup *cgrp);
 
-/* Return true if cgrp is a descendant of the task's cgroup */
-int cgroup_is_descendant(const struct cgroup *cgrp, struct task_struct *task);
-
 /*
  * Control Group taskset, used to pass around set of tasks to cgroup_subsys
  * methods.
kernel/cgroup.c +0 -28
index e72c44e..02b02ca 100644
@@ -5036,34 +5036,6 @@ void cgroup_exit(struct task_struct *tsk, int run_callbacks)
 	put_css_set_taskexit(cg);
 }
 
-/**
- * cgroup_is_descendant - see if @cgrp is a descendant of @task's cgrp
- * @cgrp: the cgroup in question
- * @task: the task in question
- *
- * See if @cgrp is a descendant of @task's cgroup in the appropriate
- * hierarchy.
- *
- * If we are sending in dummytop, then presumably we are creating
- * the top cgroup in the subsystem.
- *
- * Called only by the ns (nsproxy) cgroup.
- */
-int cgroup_is_descendant(const struct cgroup *cgrp, struct task_struct *task)
-{
-	int ret;
-	struct cgroup *target;
-
-	if (cgrp == dummytop)
-		return 1;
-
-	target = task_cgroup_from_root(task, cgrp->root);
-	while (cgrp != target && cgrp!= cgrp->top_cgroup)
-		cgrp = cgrp->parent;
-	ret = (cgrp == target);
-	return ret;
-}
-
 static void check_for_release(struct cgroup *cgrp)
 {
 	/* All of these checks rely on RCU to keep the cgroup
Signature · 1 line
1.8.0.2
author
#2 lore raw

PATCH 2/8 cgroup: remove unused variables in cgroup_destroy_locked()

In reply to Li Zefan
---
 kernel/cgroup.c | 2 --
 1 file changed, 2 deletions(-)
kernel/cgroup.c +0 -2
index 02b02ca..71bc33d 100644
@@ -4347,10 +4347,8 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
 {
 	struct dentry *d = cgrp->dentry;
 	struct cgroup *parent = cgrp->parent;
-	DEFINE_WAIT(wait);
 	struct cgroup_event *event, *tmp;
 	struct cgroup_subsys *ss;
-	LIST_HEAD(tmp_list);
 
 	lockdep_assert_held(&d->d_inode->i_mutex);
 	lockdep_assert_held(&cgroup_mutex);
Signature · 1 line
1.8.0.2
author
#3 lore raw

PATCH 3/8 cgroup: hold cgroup_mutex before calling css_offline()

In reply to Li Zefan

cpuset no longer nests cgroup_mutex inside cpu_hotplug lock, so we don't have to release cgroup_mutex before calling css_offline().

---
 Documentation/cgroups/cgroups.txt |  1 +
 kernel/cgroup.c                   | 11 +----------
 2 files changed, 2 insertions(+), 10 deletions(-)
Documentation/cgroups/cgroups.txt +1 -0
index bcf1a00..0028e88 100644
@@ -580,6 +580,7 @@ propagation along the hierarchy. See the comment on
 cgroup_for_each_descendant_pre() for details.
 
 void css_offline(struct cgroup *cgrp);
+(cgroup_mutex held by caller)
 
 This is the counterpart of css_online() and called iff css_online()
 has succeeded on @cgrp. This signifies the beginning of the end of
kernel/cgroup.c +1 -10
index 71bc33d..be524ac 100644
@@ -4170,17 +4170,8 @@ static void offline_css(struct cgroup_subsys *ss, struct cgroup *cgrp)
 	if (!(css->flags & CSS_ONLINE))
 		return;
 
-	/*
-	 * css_offline() should be called with cgroup_mutex unlocked.  See
-	 * 3fa59dfbc3 ("cgroup: fix potential deadlock in pre_destroy") for
-	 * details.  This temporary unlocking should go away once
-	 * cgroup_mutex is unexported from controllers.
-	 */
-	if (ss->css_offline) {
-		mutex_unlock(&cgroup_mutex);
+	if (ss->css_offline)
 		ss->css_offline(cgrp);
-		mutex_lock(&cgroup_mutex);
-	}
 
 	cgrp->subsys[ss->subsys_id]->flags &= ~CSS_ONLINE;
 }
Signature · 1 line
1.8.0.2
author
#4 lore raw

PATCH 4/8 cgroup: don't bother to resize pid array

In reply to Li Zefan

When we open cgroup.procs, we'll allocate an buffer and store all tasks' tgid in it, and then duplicate entries will be stripped. If that results in a much smaller pid list, we'll re-allocate a smaller buffer.

But we've already sucessfully allocated memory and reading the procs file is a short period and the memory will be freed very soon, so why bother to re-allocate memory.

---
 kernel/cgroup.c | 37 +++----------------------------------
 1 file changed, 3 insertions(+), 34 deletions(-)
kernel/cgroup.c +3 -34
index be524ac..58ae040 100644
@@ -3400,35 +3400,14 @@ static void pidlist_free(void *p)
 	else
 		kfree(p);
 }
-static void *pidlist_resize(void *p, int newcount)
-{
-	void *newlist;
-	/* note: if new alloc fails, old p will still be valid either way */
-	if (is_vmalloc_addr(p)) {
-		newlist = vmalloc(newcount * sizeof(pid_t));
-		if (!newlist)
-			return NULL;
-		memcpy(newlist, p, newcount * sizeof(pid_t));
-		vfree(p);
-	} else {
-		newlist = krealloc(p, newcount * sizeof(pid_t), GFP_KERNEL);
-	}
-	return newlist;
-}
 
 /*
  * pidlist_uniq - given a kmalloc()ed list, strip out all duplicate entries
- * If the new stripped list is sufficiently smaller and there's enough memory
- * to allocate a new buffer, will let go of the unneeded memory. Returns the
- * number of unique elements.
+ * Returns the number of unique elements.
  */
-/* is the size difference enough that we should re-allocate the array? */
-#define PIDLIST_REALLOC_DIFFERENCE(old, new) ((old) - PAGE_SIZE >= (new))
-static int pidlist_uniq(pid_t **p, int length)
+static int pidlist_uniq(pid_t *list, int length)
 {
 	int src, dest = 1;
-	pid_t *list = *p;
-	pid_t *newlist;
 
 	/*
 	 * we presume the 0th element is unique, so i starts at 1. trivial
@@ -3449,16 +3428,6 @@ static int pidlist_uniq(pid_t **p, int length)
 		dest++;
 	}
 after:
-	/*
-	 * if the length difference is large enough, we want to allocate a
-	 * smaller buffer to save memory. if this fails due to out of memory,
-	 * we'll just stay with what we've got.
-	 */
-	if (PIDLIST_REALLOC_DIFFERENCE(length, dest)) {
-		newlist = pidlist_resize(list, dest);
-		if (newlist)
-			*p = newlist;
-	}
 	return dest;
 }
 
@@ -3554,7 +3523,7 @@ static int pidlist_array_load(struct cgroup *cgrp, enum cgroup_filetype type,
 	/* now sort & (if procs) strip out duplicates */
 	sort(array, length, sizeof(pid_t), cmppid, NULL);
 	if (type == CGROUP_FILE_PROCS)
-		length = pidlist_uniq(&array, length);
+		length = pidlist_uniq(array, length);
 	l = cgroup_pidlist_find(cgrp, type);
 	if (!l) {
 		pidlist_free(array);
Signature · 1 line
1.8.0.2
author
#5 lore raw

PATCH 5/8 cgroup: remove useless code in cgroup_write_event_control()

In reply to Li Zefan

eventfd_poll() never returns POLLHUP.

---
 kernel/cgroup.c | 6 ------
 1 file changed, 6 deletions(-)
kernel/cgroup.c +0 -6
index 58ae040..3206137 100644
@@ -3938,12 +3938,6 @@ static int cgroup_write_event_control(struct cgroup *cgrp, struct cftype *cft,
 	if (ret)
 		goto fail;
 
-	if (efile->f_op->poll(efile, &event->pt) & POLLHUP) {
-		event->cft->unregister_event(cgrp, event->cft, event->eventfd);
-		ret = 0;
-		goto fail;
-	}
-
 	/*
 	 * Events should be removed after rmdir of cgroup directory, but before
 	 * destroying subsystem state objects. Let's take reference to cgroup
Signature · 1 line
1.8.0.2
author
#6 lore raw
In reply to Li Zefan

[PATCH 6/8] cgroup: remove unneeded includes from cgroup.h

---
 include/linux/cgroup.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
include/linux/cgroup.h +1 -3
index 7e818a3..1f75a59 100644
@@ -9,11 +9,8 @@
  */
 
 #include <linux/sched.h>
-#include <linux/cpumask.h>
-#include <linux/nodemask.h>
 #include <linux/rcupdate.h>
 #include <linux/rculist.h>
-#include <linux/cgroupstats.h>
 #include <linux/prio_heap.h>
 #include <linux/rwsem.h>
 #include <linux/idr.h>
@@ -22,6 +19,7 @@
 
 #ifdef CONFIG_CGROUPS
 
+struct cgroupstats;
 struct cgroupfs_root;
 struct cgroup_subsys;
 struct inode;
Signature · 1 line
1.8.0.2
author
#7 lore raw

PATCH 6/8 cgroup: remove unneeded includes from cgroup.h

In reply to Li Zefan
---
 include/linux/cgroup.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
include/linux/cgroup.h +1 -3
index 7e818a3..1f75a59 100644
@@ -9,11 +9,8 @@
  */
 
 #include <linux/sched.h>
-#include <linux/cpumask.h>
-#include <linux/nodemask.h>
 #include <linux/rcupdate.h>
 #include <linux/rculist.h>
-#include <linux/cgroupstats.h>
 #include <linux/prio_heap.h>
 #include <linux/rwsem.h>
 #include <linux/idr.h>
@@ -22,6 +19,7 @@
 
 #ifdef CONFIG_CGROUPS
 
+struct cgroupstats;
 struct cgroupfs_root;
 struct cgroup_subsys;
 struct inode;

-- 1.8.0.2

author
#8 lore raw

PATCH 7/8 cgroup: fix an almost harmless off-by-one bug

In reply to Li Zefan

The 3rd parameter of flex_array_prealloc() is the number of elements, not the index of the last element.

The effect of the bug is, when opening cgroup.procs, a flex array will be allocated and all elements of the array is allocated with GFP_KERNEL flag, but the last one is GFP_ATOMIC, , and if we fail to allocate memory for it, it'll trigger a BUG_ON().

---
 kernel/cgroup.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/cgroup.c +1 -1
index 3206137..4b92b9a 100644
@@ -2076,7 +2076,7 @@ static int cgroup_attach_proc(struct cgroup *cgrp, struct task_struct *leader)
 	if (!group)
 		return -ENOMEM;
 	/* pre-allocate to guarantee space while iterating in rcu read-side. */
-	retval = flex_array_prealloc(group, 0, group_size - 1, GFP_KERNEL);
+	retval = flex_array_prealloc(group, 0, group_size, GFP_KERNEL);
 	if (retval)
 		goto out_free_group_list;
 
Signature · 1 line
1.8.0.2
author
#9 lore raw

PATCH 8/8 cgroup: consolidate cgroup_attach_task() and cgroup_attach_proc()

In reply to Li Zefan

These two functions share most of the code.

---
 include/linux/cgroup.h |   3 +-
 kernel/cgroup.c        | 153 ++++++++++++++-----------------------------------
 kernel/cpuset.c        |   2 +-
 3 files changed, 45 insertions(+), 113 deletions(-)
include/linux/cgroup.h +2 -1
index 1f75a59..013c6ce 100644
@@ -691,7 +691,8 @@ struct task_struct *cgroup_iter_next(struct cgroup *cgrp,
 					struct cgroup_iter *it);
 void cgroup_iter_end(struct cgroup *cgrp, struct cgroup_iter *it);
 int cgroup_scan_tasks(struct cgroup_scanner *scan);
-int cgroup_attach_task(struct cgroup *, struct task_struct *);
+int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk,
+		       bool threadgroup);
 int cgroup_attach_task_all(struct task_struct *from, struct task_struct *);
 
 /*
kernel/cgroup.c +42 -111

205 lines not on this page · raw message

kernel/cpuset.c +1 -1
index ace5bfc..c55763b 100644
@@ -2008,7 +2008,7 @@ static void cpuset_do_move_task(struct task_struct *tsk,
 	struct cgroup *new_cgroup = scan->data;
 
 	cgroup_lock();
-	cgroup_attach_task(new_cgroup, tsk);
+	cgroup_attach_task(new_cgroup, tsk, false);
 	cgroup_unlock();
 }
 
Signature · 1 line
1.8.0.2
maintainer
#10 lore raw
In reply to Li Zefan
Quoted 5 lines · Li Zefan

Hi Tejun,

If you're busy with other stuff, just take your time to go through those patches.

Quoted 8 lines

0001-cgroup-remove-cgroup_is_descentant.patch 0002-cgroup-remove-unused-variables-in-cgroup_destroy_loc.patch 0003-cgroup-hold-cgroup_mutex-before-calling-css_offline.patch 0004-cgroup-don-t-bother-to-resize-pid-array.patch 0005-cgroup-remove-useless-code-in-cgroup_write_event_con.patch 0006-cgroup-remove-unneeded-includes-from-cgroup.h.patch 0007-cgroup-fix-an-almost-harmless-off-by-one-bug.patch 0008-cgroup-consolidate-cgroup_attach_task-and-cgroup_att.patch

0001-0007 applied to cgroup/for-3.10. 0008 looks fine but in the diff cgroup_attach_task_all() is removed completely and added back in slightly different form. If you wanna keep the functions ordered like you posted, please put a separate patch to move cgroup_attach_task_all() before the consolidation.

Thanks.

Signature · 1 line
tejun
author
#11 lore raw
Quoted 15 lines · Tejun Heo
Quoted 5 lines · Li Zefan

Hi Tejun,

If you're busy with other stuff, just take your time to go through those patches.

Quoted 8 lines

0001-cgroup-remove-cgroup_is_descentant.patch 0002-cgroup-remove-unused-variables-in-cgroup_destroy_loc.patch 0003-cgroup-hold-cgroup_mutex-before-calling-css_offline.patch 0004-cgroup-don-t-bother-to-resize-pid-array.patch 0005-cgroup-remove-useless-code-in-cgroup_write_event_con.patch 0006-cgroup-remove-unneeded-includes-from-cgroup.h.patch 0007-cgroup-fix-an-almost-harmless-off-by-one-bug.patch 0008-cgroup-consolidate-cgroup_attach_task-and-cgroup_att.patch

Quoted 3 lines

0001-0007 applied to cgroup/for-3.10. 0008 looks fine but in the diff cgroup_attach_task_all() is removed completely and added back in slightly different form.

At first I thought cgroup_attach_task() was static, so I thought I had to either move cgroup_attach_task_all() after cgroup_attach_task(), or add a forward declaration of cgroup_attach_task() in order to pass compile.

Then I found it was extern, but I forgot to revert this diff.

Will send a v2.

Quoted 4 lines

If you wanna keep the functions ordered like you posted, please put a separate patch to move cgroup_attach_task_all() before the consolidation.