All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/8] memcg, cgroup: kill css_id
@ 2013-07-24  9:58 ` Li Zefan
  0 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24  9:58 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm

This patchset converts memcg to use cgroup->id, and then we can remove
cgroup css_id.

As we've removed memcg's own refcnt, converting memcg to use cgroup->id
is very straight-forward.

The patchset is based on Tejun's cgroup tree.

Li Zefan (8):
      cgroup: convert cgroup_ida to cgroup_idr
      cgroup: document how cgroup IDs are assigned
      cgroup: implement cgroup_from_id()
      memcg: convert to use cgroup_is_descendant()
      memcg: convert to use cgroup id
      memcg: fail to create cgroup if the cgroup id is too big
      memcg: stop using css id
      cgroup: kill css_id
--
 include/linux/cgroup.h |  49 ++-------
 kernel/cgroup.c        | 308 ++++++++-----------------------------------------------
 mm/memcontrol.c        |  59 ++++++-----
 3 files changed, 90 insertions(+), 326 deletions(-)

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

* [PATCH v2 0/8] memcg, cgroup: kill css_id
@ 2013-07-24  9:58 ` Li Zefan
  0 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24  9:58 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm-Bw31MaZKKs3YtjvyW6yDsg

This patchset converts memcg to use cgroup->id, and then we can remove
cgroup css_id.

As we've removed memcg's own refcnt, converting memcg to use cgroup->id
is very straight-forward.

The patchset is based on Tejun's cgroup tree.

Li Zefan (8):
      cgroup: convert cgroup_ida to cgroup_idr
      cgroup: document how cgroup IDs are assigned
      cgroup: implement cgroup_from_id()
      memcg: convert to use cgroup_is_descendant()
      memcg: convert to use cgroup id
      memcg: fail to create cgroup if the cgroup id is too big
      memcg: stop using css id
      cgroup: kill css_id
--
 include/linux/cgroup.h |  49 ++-------
 kernel/cgroup.c        | 308 ++++++++-----------------------------------------------
 mm/memcontrol.c        |  59 ++++++-----
 3 files changed, 90 insertions(+), 326 deletions(-)

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

* [PATCH v2 1/8] cgroup: convert cgroup_ida to cgroup_idr
  2013-07-24  9:58 ` Li Zefan
  (?)
@ 2013-07-24  9:59   ` Li Zefan
  -1 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24  9:59 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm

This enables us to lookup a cgroup by its id.

Signed-off-by: Li Zefan <lizefan@huawei.com>
---
 include/linux/cgroup.h |  4 ++--
 kernel/cgroup.c        | 40 ++++++++++++++++++++++++++++------------
 2 files changed, 30 insertions(+), 14 deletions(-)

diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 297462b..2bd052d 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -161,7 +161,7 @@ struct cgroup_name {
 struct cgroup {
 	unsigned long flags;		/* "unsigned long" so bitops work */
 
-	int id;				/* ida allocated in-hierarchy ID */
+	int id;				/* idr allocated in-hierarchy ID */
 
 	/*
 	 * We link our 'sibling' struct into our parent's 'children'.
@@ -322,7 +322,7 @@ struct cgroupfs_root {
 	unsigned long flags;
 
 	/* IDs for cgroups in this hierarchy */
-	struct ida cgroup_ida;
+	struct idr cgroup_idr;
 
 	/* The path to use for release notifications. */
 	char release_agent_path[PATH_MAX];
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 345fac8..ee3c02e 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -866,8 +866,6 @@ static void cgroup_free_fn(struct work_struct *work)
 	 */
 	dput(cgrp->parent->dentry);
 
-	ida_simple_remove(&cgrp->root->cgroup_ida, cgrp->id);
-
 	/*
 	 * Drop the active superblock reference that we took when we
 	 * created the cgroup. This will free cgrp->root, if we are
@@ -1379,6 +1377,7 @@ static void init_cgroup_root(struct cgroupfs_root *root)
 	cgrp->root = root;
 	RCU_INIT_POINTER(cgrp->name, &root_cgroup_name);
 	init_cgroup_housekeeping(cgrp);
+	idr_init(&root->cgroup_idr);
 }
 
 static int cgroup_init_root_id(struct cgroupfs_root *root, int start, int end)
@@ -1451,7 +1450,6 @@ static struct cgroupfs_root *cgroup_root_from_opts(struct cgroup_sb_opts *opts)
 	 */
 	root->subsys_mask = opts->subsys_mask;
 	root->flags = opts->flags;
-	ida_init(&root->cgroup_ida);
 	if (opts->release_agent)
 		strcpy(root->release_agent_path, opts->release_agent);
 	if (opts->name)
@@ -1467,7 +1465,7 @@ static void cgroup_free_root(struct cgroupfs_root *root)
 		/* hierarhcy ID shoulid already have been released */
 		WARN_ON_ONCE(root->hierarchy_id);
 
-		ida_destroy(&root->cgroup_ida);
+		idr_destroy(&root->cgroup_idr);
 		kfree(root);
 	}
 }
@@ -1582,6 +1580,11 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
 		mutex_lock(&cgroup_mutex);
 		mutex_lock(&cgroup_root_mutex);
 
+		root_cgrp->id = idr_alloc(&root->cgroup_idr, root_cgrp,
+					   0, 1, GFP_KERNEL);
+		if (root_cgrp->id < 0)
+			goto unlock_drop;
+
 		/* Check for name clashes with existing mounts */
 		ret = -EBUSY;
 		if (strlen(root->name))
@@ -4268,15 +4271,19 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
 	if (!cgrp)
 		return -ENOMEM;
 
+	/*
+	 * Temporarily set the pointer to NULL, so idr_find() won't return
+	 * a half-baked cgroup.
+	 */
+	cgrp->id = idr_alloc(&root->cgroup_idr, NULL, 1, 0, GFP_KERNEL);
+	if (cgrp->id < 0)
+		goto err_free_cgrp;
+
 	name = cgroup_alloc_name(dentry);
 	if (!name)
-		goto err_free_cgrp;
+		goto err_free_id;
 	rcu_assign_pointer(cgrp->name, name);
 
-	cgrp->id = ida_simple_get(&root->cgroup_ida, 1, 0, GFP_KERNEL);
-	if (cgrp->id < 0)
-		goto err_free_name;
-
 	/*
 	 * Only live parents can have children.  Note that the liveliness
 	 * check isn't strictly necessary because cgroup_mkdir() and
@@ -4286,7 +4293,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
 	 */
 	if (!cgroup_lock_live_group(parent)) {
 		err = -ENODEV;
-		goto err_free_id;
+		goto err_free_name;
 	}
 
 	/* Grab a reference on the superblock so the hierarchy doesn't
@@ -4371,6 +4378,8 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
 		}
 	}
 
+	idr_replace(&root->cgroup_idr, cgrp, cgrp->id);
+
 	err = cgroup_addrm_files(cgrp, NULL, cgroup_base_files, true);
 	if (err)
 		goto err_destroy;
@@ -4396,10 +4405,10 @@ err_free_all:
 	mutex_unlock(&cgroup_mutex);
 	/* Release the reference count that we took on the superblock */
 	deactivate_super(sb);
-err_free_id:
-	ida_simple_remove(&root->cgroup_ida, cgrp->id);
 err_free_name:
 	kfree(rcu_dereference_raw(cgrp->name));
+err_free_id:
+	idr_remove(&root->cgroup_idr, cgrp->id);
 err_free_cgrp:
 	kfree(cgrp);
 	return err;
@@ -4590,6 +4599,9 @@ static void cgroup_offline_fn(struct work_struct *work)
 	/* delete this cgroup from parent->children */
 	list_del_rcu(&cgrp->sibling);
 
+	if (cgrp->id)
+		idr_remove(&cgrp->root->cgroup_idr, cgrp->id);
+
 	dput(d);
 
 	set_bit(CGRP_RELEASABLE, &parent->flags);
@@ -4915,6 +4927,10 @@ int __init cgroup_init(void)
 
 	BUG_ON(cgroup_init_root_id(&cgroup_dummy_root, 0, 1));
 
+	err = idr_alloc(&cgroup_dummy_root.cgroup_idr, cgroup_dummy_top,
+			1, 0, GFP_KERNEL);
+	BUG_ON(err);
+
 	mutex_unlock(&cgroup_root_mutex);
 	mutex_unlock(&cgroup_mutex);
 
-- 
1.8.0.2

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

* [PATCH v2 1/8] cgroup: convert cgroup_ida to cgroup_idr
@ 2013-07-24  9:59   ` Li Zefan
  0 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24  9:59 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm

This enables us to lookup a cgroup by its id.

Signed-off-by: Li Zefan <lizefan@huawei.com>
---
 include/linux/cgroup.h |  4 ++--
 kernel/cgroup.c        | 40 ++++++++++++++++++++++++++++------------
 2 files changed, 30 insertions(+), 14 deletions(-)

diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 297462b..2bd052d 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -161,7 +161,7 @@ struct cgroup_name {
 struct cgroup {
 	unsigned long flags;		/* "unsigned long" so bitops work */
 
-	int id;				/* ida allocated in-hierarchy ID */
+	int id;				/* idr allocated in-hierarchy ID */
 
 	/*
 	 * We link our 'sibling' struct into our parent's 'children'.
@@ -322,7 +322,7 @@ struct cgroupfs_root {
 	unsigned long flags;
 
 	/* IDs for cgroups in this hierarchy */
-	struct ida cgroup_ida;
+	struct idr cgroup_idr;
 
 	/* The path to use for release notifications. */
 	char release_agent_path[PATH_MAX];
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 345fac8..ee3c02e 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -866,8 +866,6 @@ static void cgroup_free_fn(struct work_struct *work)
 	 */
 	dput(cgrp->parent->dentry);
 
-	ida_simple_remove(&cgrp->root->cgroup_ida, cgrp->id);
-
 	/*
 	 * Drop the active superblock reference that we took when we
 	 * created the cgroup. This will free cgrp->root, if we are
@@ -1379,6 +1377,7 @@ static void init_cgroup_root(struct cgroupfs_root *root)
 	cgrp->root = root;
 	RCU_INIT_POINTER(cgrp->name, &root_cgroup_name);
 	init_cgroup_housekeeping(cgrp);
+	idr_init(&root->cgroup_idr);
 }
 
 static int cgroup_init_root_id(struct cgroupfs_root *root, int start, int end)
@@ -1451,7 +1450,6 @@ static struct cgroupfs_root *cgroup_root_from_opts(struct cgroup_sb_opts *opts)
 	 */
 	root->subsys_mask = opts->subsys_mask;
 	root->flags = opts->flags;
-	ida_init(&root->cgroup_ida);
 	if (opts->release_agent)
 		strcpy(root->release_agent_path, opts->release_agent);
 	if (opts->name)
@@ -1467,7 +1465,7 @@ static void cgroup_free_root(struct cgroupfs_root *root)
 		/* hierarhcy ID shoulid already have been released */
 		WARN_ON_ONCE(root->hierarchy_id);
 
-		ida_destroy(&root->cgroup_ida);
+		idr_destroy(&root->cgroup_idr);
 		kfree(root);
 	}
 }
@@ -1582,6 +1580,11 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
 		mutex_lock(&cgroup_mutex);
 		mutex_lock(&cgroup_root_mutex);
 
+		root_cgrp->id = idr_alloc(&root->cgroup_idr, root_cgrp,
+					   0, 1, GFP_KERNEL);
+		if (root_cgrp->id < 0)
+			goto unlock_drop;
+
 		/* Check for name clashes with existing mounts */
 		ret = -EBUSY;
 		if (strlen(root->name))
@@ -4268,15 +4271,19 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
 	if (!cgrp)
 		return -ENOMEM;
 
+	/*
+	 * Temporarily set the pointer to NULL, so idr_find() won't return
+	 * a half-baked cgroup.
+	 */
+	cgrp->id = idr_alloc(&root->cgroup_idr, NULL, 1, 0, GFP_KERNEL);
+	if (cgrp->id < 0)
+		goto err_free_cgrp;
+
 	name = cgroup_alloc_name(dentry);
 	if (!name)
-		goto err_free_cgrp;
+		goto err_free_id;
 	rcu_assign_pointer(cgrp->name, name);
 
-	cgrp->id = ida_simple_get(&root->cgroup_ida, 1, 0, GFP_KERNEL);
-	if (cgrp->id < 0)
-		goto err_free_name;
-
 	/*
 	 * Only live parents can have children.  Note that the liveliness
 	 * check isn't strictly necessary because cgroup_mkdir() and
@@ -4286,7 +4293,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
 	 */
 	if (!cgroup_lock_live_group(parent)) {
 		err = -ENODEV;
-		goto err_free_id;
+		goto err_free_name;
 	}
 
 	/* Grab a reference on the superblock so the hierarchy doesn't
@@ -4371,6 +4378,8 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
 		}
 	}
 
+	idr_replace(&root->cgroup_idr, cgrp, cgrp->id);
+
 	err = cgroup_addrm_files(cgrp, NULL, cgroup_base_files, true);
 	if (err)
 		goto err_destroy;
@@ -4396,10 +4405,10 @@ err_free_all:
 	mutex_unlock(&cgroup_mutex);
 	/* Release the reference count that we took on the superblock */
 	deactivate_super(sb);
-err_free_id:
-	ida_simple_remove(&root->cgroup_ida, cgrp->id);
 err_free_name:
 	kfree(rcu_dereference_raw(cgrp->name));
+err_free_id:
+	idr_remove(&root->cgroup_idr, cgrp->id);
 err_free_cgrp:
 	kfree(cgrp);
 	return err;
@@ -4590,6 +4599,9 @@ static void cgroup_offline_fn(struct work_struct *work)
 	/* delete this cgroup from parent->children */
 	list_del_rcu(&cgrp->sibling);
 
+	if (cgrp->id)
+		idr_remove(&cgrp->root->cgroup_idr, cgrp->id);
+
 	dput(d);
 
 	set_bit(CGRP_RELEASABLE, &parent->flags);
@@ -4915,6 +4927,10 @@ int __init cgroup_init(void)
 
 	BUG_ON(cgroup_init_root_id(&cgroup_dummy_root, 0, 1));
 
+	err = idr_alloc(&cgroup_dummy_root.cgroup_idr, cgroup_dummy_top,
+			1, 0, GFP_KERNEL);
+	BUG_ON(err);
+
 	mutex_unlock(&cgroup_root_mutex);
 	mutex_unlock(&cgroup_mutex);
 
-- 
1.8.0.2

--
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] 52+ messages in thread

* [PATCH v2 1/8] cgroup: convert cgroup_ida to cgroup_idr
@ 2013-07-24  9:59   ` Li Zefan
  0 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24  9:59 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm-Bw31MaZKKs3YtjvyW6yDsg

This enables us to lookup a cgroup by its id.

Signed-off-by: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
---
 include/linux/cgroup.h |  4 ++--
 kernel/cgroup.c        | 40 ++++++++++++++++++++++++++++------------
 2 files changed, 30 insertions(+), 14 deletions(-)

diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 297462b..2bd052d 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -161,7 +161,7 @@ struct cgroup_name {
 struct cgroup {
 	unsigned long flags;		/* "unsigned long" so bitops work */
 
-	int id;				/* ida allocated in-hierarchy ID */
+	int id;				/* idr allocated in-hierarchy ID */
 
 	/*
 	 * We link our 'sibling' struct into our parent's 'children'.
@@ -322,7 +322,7 @@ struct cgroupfs_root {
 	unsigned long flags;
 
 	/* IDs for cgroups in this hierarchy */
-	struct ida cgroup_ida;
+	struct idr cgroup_idr;
 
 	/* The path to use for release notifications. */
 	char release_agent_path[PATH_MAX];
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 345fac8..ee3c02e 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -866,8 +866,6 @@ static void cgroup_free_fn(struct work_struct *work)
 	 */
 	dput(cgrp->parent->dentry);
 
-	ida_simple_remove(&cgrp->root->cgroup_ida, cgrp->id);
-
 	/*
 	 * Drop the active superblock reference that we took when we
 	 * created the cgroup. This will free cgrp->root, if we are
@@ -1379,6 +1377,7 @@ static void init_cgroup_root(struct cgroupfs_root *root)
 	cgrp->root = root;
 	RCU_INIT_POINTER(cgrp->name, &root_cgroup_name);
 	init_cgroup_housekeeping(cgrp);
+	idr_init(&root->cgroup_idr);
 }
 
 static int cgroup_init_root_id(struct cgroupfs_root *root, int start, int end)
@@ -1451,7 +1450,6 @@ static struct cgroupfs_root *cgroup_root_from_opts(struct cgroup_sb_opts *opts)
 	 */
 	root->subsys_mask = opts->subsys_mask;
 	root->flags = opts->flags;
-	ida_init(&root->cgroup_ida);
 	if (opts->release_agent)
 		strcpy(root->release_agent_path, opts->release_agent);
 	if (opts->name)
@@ -1467,7 +1465,7 @@ static void cgroup_free_root(struct cgroupfs_root *root)
 		/* hierarhcy ID shoulid already have been released */
 		WARN_ON_ONCE(root->hierarchy_id);
 
-		ida_destroy(&root->cgroup_ida);
+		idr_destroy(&root->cgroup_idr);
 		kfree(root);
 	}
 }
@@ -1582,6 +1580,11 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
 		mutex_lock(&cgroup_mutex);
 		mutex_lock(&cgroup_root_mutex);
 
+		root_cgrp->id = idr_alloc(&root->cgroup_idr, root_cgrp,
+					   0, 1, GFP_KERNEL);
+		if (root_cgrp->id < 0)
+			goto unlock_drop;
+
 		/* Check for name clashes with existing mounts */
 		ret = -EBUSY;
 		if (strlen(root->name))
@@ -4268,15 +4271,19 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
 	if (!cgrp)
 		return -ENOMEM;
 
+	/*
+	 * Temporarily set the pointer to NULL, so idr_find() won't return
+	 * a half-baked cgroup.
+	 */
+	cgrp->id = idr_alloc(&root->cgroup_idr, NULL, 1, 0, GFP_KERNEL);
+	if (cgrp->id < 0)
+		goto err_free_cgrp;
+
 	name = cgroup_alloc_name(dentry);
 	if (!name)
-		goto err_free_cgrp;
+		goto err_free_id;
 	rcu_assign_pointer(cgrp->name, name);
 
-	cgrp->id = ida_simple_get(&root->cgroup_ida, 1, 0, GFP_KERNEL);
-	if (cgrp->id < 0)
-		goto err_free_name;
-
 	/*
 	 * Only live parents can have children.  Note that the liveliness
 	 * check isn't strictly necessary because cgroup_mkdir() and
@@ -4286,7 +4293,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
 	 */
 	if (!cgroup_lock_live_group(parent)) {
 		err = -ENODEV;
-		goto err_free_id;
+		goto err_free_name;
 	}
 
 	/* Grab a reference on the superblock so the hierarchy doesn't
@@ -4371,6 +4378,8 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
 		}
 	}
 
+	idr_replace(&root->cgroup_idr, cgrp, cgrp->id);
+
 	err = cgroup_addrm_files(cgrp, NULL, cgroup_base_files, true);
 	if (err)
 		goto err_destroy;
@@ -4396,10 +4405,10 @@ err_free_all:
 	mutex_unlock(&cgroup_mutex);
 	/* Release the reference count that we took on the superblock */
 	deactivate_super(sb);
-err_free_id:
-	ida_simple_remove(&root->cgroup_ida, cgrp->id);
 err_free_name:
 	kfree(rcu_dereference_raw(cgrp->name));
+err_free_id:
+	idr_remove(&root->cgroup_idr, cgrp->id);
 err_free_cgrp:
 	kfree(cgrp);
 	return err;
@@ -4590,6 +4599,9 @@ static void cgroup_offline_fn(struct work_struct *work)
 	/* delete this cgroup from parent->children */
 	list_del_rcu(&cgrp->sibling);
 
+	if (cgrp->id)
+		idr_remove(&cgrp->root->cgroup_idr, cgrp->id);
+
 	dput(d);
 
 	set_bit(CGRP_RELEASABLE, &parent->flags);
@@ -4915,6 +4927,10 @@ int __init cgroup_init(void)
 
 	BUG_ON(cgroup_init_root_id(&cgroup_dummy_root, 0, 1));
 
+	err = idr_alloc(&cgroup_dummy_root.cgroup_idr, cgroup_dummy_top,
+			1, 0, GFP_KERNEL);
+	BUG_ON(err);
+
 	mutex_unlock(&cgroup_root_mutex);
 	mutex_unlock(&cgroup_mutex);
 
-- 
1.8.0.2

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

* [PATCH v2 2/8] cgroup: document how cgroup IDs are assigned
  2013-07-24  9:58 ` Li Zefan
  (?)
@ 2013-07-24  9:59   ` Li Zefan
  -1 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24  9:59 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm

As cgroup id has been used in netprio cgroup and will be used in memcg,
it's important to make it clear how a cgroup id is allocated.

For example, in netprio cgroup, the id is used as index of an array.

Signed-off-by: Li Zefan <lizefan@huwei.com>
---
 include/linux/cgroup.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 2bd052d..8c107e9 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -161,7 +161,13 @@ struct cgroup_name {
 struct cgroup {
 	unsigned long flags;		/* "unsigned long" so bitops work */
 
-	int id;				/* idr allocated in-hierarchy ID */
+	/*
+	 * idr allocated in-hierarchy ID.
+	 *
+	 * The ID of the root cgroup is always 0, and a new cgroup
+	 * will be assigned with a smallest available ID.
+	 */
+	int id;
 
 	/*
 	 * We link our 'sibling' struct into our parent's 'children'.
-- 
1.8.0.2


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

* [PATCH v2 2/8] cgroup: document how cgroup IDs are assigned
@ 2013-07-24  9:59   ` Li Zefan
  0 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24  9:59 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm

As cgroup id has been used in netprio cgroup and will be used in memcg,
it's important to make it clear how a cgroup id is allocated.

For example, in netprio cgroup, the id is used as index of an array.

Signed-off-by: Li Zefan <lizefan@huwei.com>
---
 include/linux/cgroup.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 2bd052d..8c107e9 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -161,7 +161,13 @@ struct cgroup_name {
 struct cgroup {
 	unsigned long flags;		/* "unsigned long" so bitops work */
 
-	int id;				/* idr allocated in-hierarchy ID */
+	/*
+	 * idr allocated in-hierarchy ID.
+	 *
+	 * The ID of the root cgroup is always 0, and a new cgroup
+	 * will be assigned with a smallest available ID.
+	 */
+	int id;
 
 	/*
 	 * We link our 'sibling' struct into our parent's 'children'.
-- 
1.8.0.2

--
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] 52+ messages in thread

* [PATCH v2 2/8] cgroup: document how cgroup IDs are assigned
@ 2013-07-24  9:59   ` Li Zefan
  0 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24  9:59 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm-Bw31MaZKKs3YtjvyW6yDsg

As cgroup id has been used in netprio cgroup and will be used in memcg,
it's important to make it clear how a cgroup id is allocated.

For example, in netprio cgroup, the id is used as index of an array.

Signed-off-by: Li Zefan <lizefan-Z5rXVj2qdvIAvxtiuMwx3w@public.gmane.org>
---
 include/linux/cgroup.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 2bd052d..8c107e9 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -161,7 +161,13 @@ struct cgroup_name {
 struct cgroup {
 	unsigned long flags;		/* "unsigned long" so bitops work */
 
-	int id;				/* idr allocated in-hierarchy ID */
+	/*
+	 * idr allocated in-hierarchy ID.
+	 *
+	 * The ID of the root cgroup is always 0, and a new cgroup
+	 * will be assigned with a smallest available ID.
+	 */
+	int id;
 
 	/*
 	 * We link our 'sibling' struct into our parent's 'children'.
-- 
1.8.0.2

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

* [PATCH v2 3/8] cgroup: implement cgroup_from_id()
  2013-07-24  9:58 ` Li Zefan
@ 2013-07-24 10:00   ` Li Zefan
  -1 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24 10:00 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm

This will be used as a replacement for css_lookup().

There's a difference with cgroup id and css id. cgroup id starts with 0,
while css id starts with 1.

Signed-off-by: Li Zefan <lizefan@huawei.com>
---
 include/linux/cgroup.h |  2 ++
 kernel/cgroup.c        | 16 ++++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 8c107e9..e8eb361 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -553,6 +553,8 @@ int task_cgroup_path_from_hierarchy(struct task_struct *task, int hierarchy_id,
 
 int cgroup_task_count(const struct cgroup *cgrp);
 
+struct cgroup *cgroup_from_id(struct cgroup_subsys *ss, int id);
+
 /*
  * Control Group taskset, used to pass around set of tasks to cgroup_subsys
  * methods.
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index ee3c02e..9b27775 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -5536,6 +5536,22 @@ struct cgroup_subsys_state *cgroup_css_from_dir(struct file *f, int id)
 	return css ? css : ERR_PTR(-ENOENT);
 }
 
+/**
+ * cgroup_from_id - lookup cgroup by id
+ * @ss: cgroup subsys to be looked into
+ * @id: the cgroup id
+ *
+ * Returns the cgroup is there's valid one with @id, otherwise returns Null.
+ * Should be called under rcu_readlock().
+ */
+struct cgroup *cgroup_from_id(struct cgroup_subsys *ss, int id)
+{
+	rcu_lockdep_assert(rcu_read_lock_held(),
+			   "cgroup_from_id() needs rcu_read_lock()"
+			   " protection");
+	return idr_find(&ss->root->cgroup_idr, id);
+}
+
 #ifdef CONFIG_CGROUP_DEBUG
 static struct cgroup_subsys_state *debug_css_alloc(struct cgroup *cgrp)
 {
-- 
1.8.0.2

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

* [PATCH v2 3/8] cgroup: implement cgroup_from_id()
@ 2013-07-24 10:00   ` Li Zefan
  0 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24 10:00 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm

This will be used as a replacement for css_lookup().

There's a difference with cgroup id and css id. cgroup id starts with 0,
while css id starts with 1.

Signed-off-by: Li Zefan <lizefan@huawei.com>
---
 include/linux/cgroup.h |  2 ++
 kernel/cgroup.c        | 16 ++++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 8c107e9..e8eb361 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -553,6 +553,8 @@ int task_cgroup_path_from_hierarchy(struct task_struct *task, int hierarchy_id,
 
 int cgroup_task_count(const struct cgroup *cgrp);
 
+struct cgroup *cgroup_from_id(struct cgroup_subsys *ss, int id);
+
 /*
  * Control Group taskset, used to pass around set of tasks to cgroup_subsys
  * methods.
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index ee3c02e..9b27775 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -5536,6 +5536,22 @@ struct cgroup_subsys_state *cgroup_css_from_dir(struct file *f, int id)
 	return css ? css : ERR_PTR(-ENOENT);
 }
 
+/**
+ * cgroup_from_id - lookup cgroup by id
+ * @ss: cgroup subsys to be looked into
+ * @id: the cgroup id
+ *
+ * Returns the cgroup is there's valid one with @id, otherwise returns Null.
+ * Should be called under rcu_readlock().
+ */
+struct cgroup *cgroup_from_id(struct cgroup_subsys *ss, int id)
+{
+	rcu_lockdep_assert(rcu_read_lock_held(),
+			   "cgroup_from_id() needs rcu_read_lock()"
+			   " protection");
+	return idr_find(&ss->root->cgroup_idr, id);
+}
+
 #ifdef CONFIG_CGROUP_DEBUG
 static struct cgroup_subsys_state *debug_css_alloc(struct cgroup *cgrp)
 {
-- 
1.8.0.2

--
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] 52+ messages in thread

* [PATCH v2 4/8] memcg: convert to use cgroup_is_descendant()
  2013-07-24  9:58 ` Li Zefan
  (?)
@ 2013-07-24 10:01   ` Li Zefan
  -1 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24 10:01 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm

This is a preparation to kill css_id.

Signed-off-by: Li Zefan <lizefan@huawei.com>
---
 mm/memcontrol.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index d12ca6f..626c426 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1434,7 +1434,7 @@ bool __mem_cgroup_same_or_subtree(const struct mem_cgroup *root_memcg,
 		return true;
 	if (!root_memcg->use_hierarchy || !memcg)
 		return false;
-	return css_is_ancestor(&memcg->css, &root_memcg->css);
+	return cgroup_is_descendant(memcg->css.cgroup, root_memcg->css.cgroup);
 }
 
 static bool mem_cgroup_same_or_subtree(const struct mem_cgroup *root_memcg,
-- 
1.8.0.2


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

* [PATCH v2 4/8] memcg: convert to use cgroup_is_descendant()
@ 2013-07-24 10:01   ` Li Zefan
  0 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24 10:01 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm

This is a preparation to kill css_id.

Signed-off-by: Li Zefan <lizefan@huawei.com>
---
 mm/memcontrol.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index d12ca6f..626c426 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1434,7 +1434,7 @@ bool __mem_cgroup_same_or_subtree(const struct mem_cgroup *root_memcg,
 		return true;
 	if (!root_memcg->use_hierarchy || !memcg)
 		return false;
-	return css_is_ancestor(&memcg->css, &root_memcg->css);
+	return cgroup_is_descendant(memcg->css.cgroup, root_memcg->css.cgroup);
 }
 
 static bool mem_cgroup_same_or_subtree(const struct mem_cgroup *root_memcg,
-- 
1.8.0.2

--
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] 52+ messages in thread

* [PATCH v2 4/8] memcg: convert to use cgroup_is_descendant()
@ 2013-07-24 10:01   ` Li Zefan
  0 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24 10:01 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm-Bw31MaZKKs3YtjvyW6yDsg

This is a preparation to kill css_id.

Signed-off-by: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
---
 mm/memcontrol.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index d12ca6f..626c426 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1434,7 +1434,7 @@ bool __mem_cgroup_same_or_subtree(const struct mem_cgroup *root_memcg,
 		return true;
 	if (!root_memcg->use_hierarchy || !memcg)
 		return false;
-	return css_is_ancestor(&memcg->css, &root_memcg->css);
+	return cgroup_is_descendant(memcg->css.cgroup, root_memcg->css.cgroup);
 }
 
 static bool mem_cgroup_same_or_subtree(const struct mem_cgroup *root_memcg,
-- 
1.8.0.2

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

* [PATCH v2 5/8] memcg: convert to use cgroup id
  2013-07-24  9:58 ` Li Zefan
@ 2013-07-24 10:01   ` Li Zefan
  -1 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24 10:01 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm

Use cgroup id instead of css id. This is a preparation to kill css id.

Note, as memcg treats 0 as an invalid id, while cgroup id starts with 0,
we define memcg_id == cgroup_id + 1.

Signed-off-by: Li Zefan <lizefan@huawei.com>
---
 mm/memcontrol.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 626c426..35d8286 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -512,6 +512,15 @@ static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg)
 	return (memcg == root_mem_cgroup);
 }
 
+static inline unsigned short mem_cgroup_id(struct mem_cgroup *memcg)
+{
+	/*
+	 * The ID of the root cgroup is 0, but memcg treat 0 as an
+	 * valid ID, so we return (cgroup_id + 1).
+	 */
+	return memcg->css.cgroup->id + 1;
+}
+
 /* Writing them here to avoid exposing memcg's inner layout */
 #if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM)
 
@@ -2821,15 +2830,15 @@ static void __mem_cgroup_cancel_local_charge(struct mem_cgroup *memcg,
  */
 static struct mem_cgroup *mem_cgroup_lookup(unsigned short id)
 {
-	struct cgroup_subsys_state *css;
+	struct cgroup *cgrp;
 
 	/* ID 0 is unused ID */
 	if (!id)
 		return NULL;
-	css = css_lookup(&mem_cgroup_subsys, id);
-	if (!css)
+	cgrp = cgroup_from_id(&mem_cgroup_subsys, id - 1);
+	if (!cgrp)
 		return NULL;
-	return mem_cgroup_from_css(css);
+	return mem_cgroup_from_cont(cgrp);
 }
 
 struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page)
@@ -4328,7 +4337,7 @@ mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent, bool swapout)
 	 * css_get() was called in uncharge().
 	 */
 	if (do_swap_account && swapout && memcg)
-		swap_cgroup_record(ent, css_id(&memcg->css));
+		swap_cgroup_record(ent, mem_cgroup_id(memcg));
 }
 #endif
 
@@ -4380,8 +4389,8 @@ static int mem_cgroup_move_swap_account(swp_entry_t entry,
 {
 	unsigned short old_id, new_id;
 
-	old_id = css_id(&from->css);
-	new_id = css_id(&to->css);
+	old_id = mem_cgroup_id(from);
+	new_id = mem_cgroup_id(to);
 
 	if (swap_cgroup_cmpxchg(entry, old_id, new_id) == old_id) {
 		mem_cgroup_swap_statistics(from, false);
@@ -6542,7 +6551,7 @@ static enum mc_target_type get_mctgt_type(struct vm_area_struct *vma,
 	}
 	/* There is a swap entry and a page doesn't exist or isn't charged */
 	if (ent.val && !ret &&
-			css_id(&mc.from->css) == lookup_swap_cgroup_id(ent)) {
+	    mem_cgroup_id(mc.from) == lookup_swap_cgroup_id(ent)) {
 		ret = MC_TARGET_SWAP;
 		if (target)
 			target->ent = ent;
-- 
1.8.0.2

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

* [PATCH v2 5/8] memcg: convert to use cgroup id
@ 2013-07-24 10:01   ` Li Zefan
  0 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24 10:01 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm

Use cgroup id instead of css id. This is a preparation to kill css id.

Note, as memcg treats 0 as an invalid id, while cgroup id starts with 0,
we define memcg_id == cgroup_id + 1.

Signed-off-by: Li Zefan <lizefan@huawei.com>
---
 mm/memcontrol.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 626c426..35d8286 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -512,6 +512,15 @@ static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg)
 	return (memcg == root_mem_cgroup);
 }
 
+static inline unsigned short mem_cgroup_id(struct mem_cgroup *memcg)
+{
+	/*
+	 * The ID of the root cgroup is 0, but memcg treat 0 as an
+	 * valid ID, so we return (cgroup_id + 1).
+	 */
+	return memcg->css.cgroup->id + 1;
+}
+
 /* Writing them here to avoid exposing memcg's inner layout */
 #if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM)
 
@@ -2821,15 +2830,15 @@ static void __mem_cgroup_cancel_local_charge(struct mem_cgroup *memcg,
  */
 static struct mem_cgroup *mem_cgroup_lookup(unsigned short id)
 {
-	struct cgroup_subsys_state *css;
+	struct cgroup *cgrp;
 
 	/* ID 0 is unused ID */
 	if (!id)
 		return NULL;
-	css = css_lookup(&mem_cgroup_subsys, id);
-	if (!css)
+	cgrp = cgroup_from_id(&mem_cgroup_subsys, id - 1);
+	if (!cgrp)
 		return NULL;
-	return mem_cgroup_from_css(css);
+	return mem_cgroup_from_cont(cgrp);
 }
 
 struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page)
@@ -4328,7 +4337,7 @@ mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent, bool swapout)
 	 * css_get() was called in uncharge().
 	 */
 	if (do_swap_account && swapout && memcg)
-		swap_cgroup_record(ent, css_id(&memcg->css));
+		swap_cgroup_record(ent, mem_cgroup_id(memcg));
 }
 #endif
 
@@ -4380,8 +4389,8 @@ static int mem_cgroup_move_swap_account(swp_entry_t entry,
 {
 	unsigned short old_id, new_id;
 
-	old_id = css_id(&from->css);
-	new_id = css_id(&to->css);
+	old_id = mem_cgroup_id(from);
+	new_id = mem_cgroup_id(to);
 
 	if (swap_cgroup_cmpxchg(entry, old_id, new_id) == old_id) {
 		mem_cgroup_swap_statistics(from, false);
@@ -6542,7 +6551,7 @@ static enum mc_target_type get_mctgt_type(struct vm_area_struct *vma,
 	}
 	/* There is a swap entry and a page doesn't exist or isn't charged */
 	if (ent.val && !ret &&
-			css_id(&mc.from->css) == lookup_swap_cgroup_id(ent)) {
+	    mem_cgroup_id(mc.from) == lookup_swap_cgroup_id(ent)) {
 		ret = MC_TARGET_SWAP;
 		if (target)
 			target->ent = ent;
-- 
1.8.0.2

--
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] 52+ messages in thread

* [PATCH v2 6/8] memcg: fail to create cgroup if the cgroup id is too big
  2013-07-24  9:58 ` Li Zefan
@ 2013-07-24 10:02   ` Li Zefan
  -1 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24 10:02 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm

memcg requires the cgroup id to be smaller than 65536.

Signed-off-by: Li Zefan <lizefan@huawei.com>
---
 mm/memcontrol.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 35d8286..403c8d9 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -512,6 +512,12 @@ static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg)
 	return (memcg == root_mem_cgroup);
 }
 
+/*
+ * We restrict the id in the range of [1, 65535], so it can fit into
+ * an unsigned short.
+ */
+#define MEM_CGROUP_ID_MAX	(65535)
+
 static inline unsigned short mem_cgroup_id(struct mem_cgroup *memcg)
 {
 	/*
@@ -6243,6 +6249,9 @@ mem_cgroup_css_alloc(struct cgroup *cont)
 	long error = -ENOMEM;
 	int node;
 
+	if (cont->id > MEM_CGROUP_ID_MAX)
+		return ERR_PTR(-ENOSPC);
+
 	memcg = mem_cgroup_alloc();
 	if (!memcg)
 		return ERR_PTR(error);
-- 
1.8.0.2

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

* [PATCH v2 6/8] memcg: fail to create cgroup if the cgroup id is too big
@ 2013-07-24 10:02   ` Li Zefan
  0 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24 10:02 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm

memcg requires the cgroup id to be smaller than 65536.

Signed-off-by: Li Zefan <lizefan@huawei.com>
---
 mm/memcontrol.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 35d8286..403c8d9 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -512,6 +512,12 @@ static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg)
 	return (memcg == root_mem_cgroup);
 }
 
+/*
+ * We restrict the id in the range of [1, 65535], so it can fit into
+ * an unsigned short.
+ */
+#define MEM_CGROUP_ID_MAX	(65535)
+
 static inline unsigned short mem_cgroup_id(struct mem_cgroup *memcg)
 {
 	/*
@@ -6243,6 +6249,9 @@ mem_cgroup_css_alloc(struct cgroup *cont)
 	long error = -ENOMEM;
 	int node;
 
+	if (cont->id > MEM_CGROUP_ID_MAX)
+		return ERR_PTR(-ENOSPC);
+
 	memcg = mem_cgroup_alloc();
 	if (!memcg)
 		return ERR_PTR(error);
-- 
1.8.0.2

--
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] 52+ messages in thread

* [PATCH v2 7/8] memcg: stop using css id
  2013-07-24  9:58 ` Li Zefan
  (?)
@ 2013-07-24 10:03   ` Li Zefan
  -1 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24 10:03 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm

Now memcg uses cgroup id instead of css id. Update some comments and
set mem_cgroup_subsys->use_id to 0.

Signed-off-by: Li Zefan <lizefan@huawei.com>
---
 mm/memcontrol.c | 23 ++++++++---------------
 1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 403c8d9..03c8bf7 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -598,16 +598,11 @@ static void disarm_sock_keys(struct mem_cgroup *memcg)
 #ifdef CONFIG_MEMCG_KMEM
 /*
  * This will be the memcg's index in each cache's ->memcg_params->memcg_caches.
- * There are two main reasons for not using the css_id for this:
- *  1) this works better in sparse environments, where we have a lot of memcgs,
- *     but only a few kmem-limited. Or also, if we have, for instance, 200
- *     memcgs, and none but the 200th is kmem-limited, we'd have to have a
- *     200 entry array for that.
- *
- *  2) In order not to violate the cgroup API, we would like to do all memory
- *     allocation in ->create(). At that point, we haven't yet allocated the
- *     css_id. Having a separate index prevents us from messing with the cgroup
- *     core for this
+ * The main reason for not using cgroup id for this:
+ *  this works better in sparse environments, where we have a lot of memcgs,
+ *  but only a few kmem-limited. Or also, if we have, for instance, 200
+ *  memcgs, and none but the 200th is kmem-limited, we'd have to have a
+ *  200 entry array for that.
  *
  * The current size of the caches array is stored in
  * memcg_limited_groups_array_size.  It will double each time we have to
@@ -622,14 +617,14 @@ int memcg_limited_groups_array_size;
  * cgroups is a reasonable guess. In the future, it could be a parameter or
  * tunable, but that is strictly not necessary.
  *
- * MAX_SIZE should be as large as the number of css_ids. Ideally, we could get
+ * MAX_SIZE should be as large as the number of cgrp_ids. Ideally, we could get
  * this constant directly from cgroup, but it is understandable that this is
  * better kept as an internal representation in cgroup.c. In any case, the
- * css_id space is not getting any smaller, and we don't have to necessarily
+ * cgrp_id space is not getting any smaller, and we don't have to necessarily
  * increase ours as well if it increases.
  */
 #define MEMCG_CACHES_MIN_SIZE 4
-#define MEMCG_CACHES_MAX_SIZE 65535
+#define MEMCG_CACHES_MAX_SIZE MEM_CGROUP_ID_MAX
 
 /*
  * A lot of the calls to the cache allocation functions are expected to be
@@ -6183,7 +6178,6 @@ static void __mem_cgroup_free(struct mem_cgroup *memcg)
 	size_t size = memcg_size();
 
 	mem_cgroup_remove_from_trees(memcg);
-	free_css_id(&mem_cgroup_subsys, &memcg->css);
 
 	for_each_node(node)
 		free_mem_cgroup_per_zone_info(memcg, node);
@@ -6980,7 +6974,6 @@ struct cgroup_subsys mem_cgroup_subsys = {
 	.bind = mem_cgroup_bind,
 	.base_cftypes = mem_cgroup_files,
 	.early_init = 0,
-	.use_id = 1,
 };
 
 #ifdef CONFIG_MEMCG_SWAP
-- 
1.8.0.2

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

* [PATCH v2 7/8] memcg: stop using css id
@ 2013-07-24 10:03   ` Li Zefan
  0 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24 10:03 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm

Now memcg uses cgroup id instead of css id. Update some comments and
set mem_cgroup_subsys->use_id to 0.

Signed-off-by: Li Zefan <lizefan@huawei.com>
---
 mm/memcontrol.c | 23 ++++++++---------------
 1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 403c8d9..03c8bf7 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -598,16 +598,11 @@ static void disarm_sock_keys(struct mem_cgroup *memcg)
 #ifdef CONFIG_MEMCG_KMEM
 /*
  * This will be the memcg's index in each cache's ->memcg_params->memcg_caches.
- * There are two main reasons for not using the css_id for this:
- *  1) this works better in sparse environments, where we have a lot of memcgs,
- *     but only a few kmem-limited. Or also, if we have, for instance, 200
- *     memcgs, and none but the 200th is kmem-limited, we'd have to have a
- *     200 entry array for that.
- *
- *  2) In order not to violate the cgroup API, we would like to do all memory
- *     allocation in ->create(). At that point, we haven't yet allocated the
- *     css_id. Having a separate index prevents us from messing with the cgroup
- *     core for this
+ * The main reason for not using cgroup id for this:
+ *  this works better in sparse environments, where we have a lot of memcgs,
+ *  but only a few kmem-limited. Or also, if we have, for instance, 200
+ *  memcgs, and none but the 200th is kmem-limited, we'd have to have a
+ *  200 entry array for that.
  *
  * The current size of the caches array is stored in
  * memcg_limited_groups_array_size.  It will double each time we have to
@@ -622,14 +617,14 @@ int memcg_limited_groups_array_size;
  * cgroups is a reasonable guess. In the future, it could be a parameter or
  * tunable, but that is strictly not necessary.
  *
- * MAX_SIZE should be as large as the number of css_ids. Ideally, we could get
+ * MAX_SIZE should be as large as the number of cgrp_ids. Ideally, we could get
  * this constant directly from cgroup, but it is understandable that this is
  * better kept as an internal representation in cgroup.c. In any case, the
- * css_id space is not getting any smaller, and we don't have to necessarily
+ * cgrp_id space is not getting any smaller, and we don't have to necessarily
  * increase ours as well if it increases.
  */
 #define MEMCG_CACHES_MIN_SIZE 4
-#define MEMCG_CACHES_MAX_SIZE 65535
+#define MEMCG_CACHES_MAX_SIZE MEM_CGROUP_ID_MAX
 
 /*
  * A lot of the calls to the cache allocation functions are expected to be
@@ -6183,7 +6178,6 @@ static void __mem_cgroup_free(struct mem_cgroup *memcg)
 	size_t size = memcg_size();
 
 	mem_cgroup_remove_from_trees(memcg);
-	free_css_id(&mem_cgroup_subsys, &memcg->css);
 
 	for_each_node(node)
 		free_mem_cgroup_per_zone_info(memcg, node);
@@ -6980,7 +6974,6 @@ struct cgroup_subsys mem_cgroup_subsys = {
 	.bind = mem_cgroup_bind,
 	.base_cftypes = mem_cgroup_files,
 	.early_init = 0,
-	.use_id = 1,
 };
 
 #ifdef CONFIG_MEMCG_SWAP
-- 
1.8.0.2

--
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] 52+ messages in thread

* [PATCH v2 7/8] memcg: stop using css id
@ 2013-07-24 10:03   ` Li Zefan
  0 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24 10:03 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm-Bw31MaZKKs3YtjvyW6yDsg

Now memcg uses cgroup id instead of css id. Update some comments and
set mem_cgroup_subsys->use_id to 0.

Signed-off-by: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
---
 mm/memcontrol.c | 23 ++++++++---------------
 1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 403c8d9..03c8bf7 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -598,16 +598,11 @@ static void disarm_sock_keys(struct mem_cgroup *memcg)
 #ifdef CONFIG_MEMCG_KMEM
 /*
  * This will be the memcg's index in each cache's ->memcg_params->memcg_caches.
- * There are two main reasons for not using the css_id for this:
- *  1) this works better in sparse environments, where we have a lot of memcgs,
- *     but only a few kmem-limited. Or also, if we have, for instance, 200
- *     memcgs, and none but the 200th is kmem-limited, we'd have to have a
- *     200 entry array for that.
- *
- *  2) In order not to violate the cgroup API, we would like to do all memory
- *     allocation in ->create(). At that point, we haven't yet allocated the
- *     css_id. Having a separate index prevents us from messing with the cgroup
- *     core for this
+ * The main reason for not using cgroup id for this:
+ *  this works better in sparse environments, where we have a lot of memcgs,
+ *  but only a few kmem-limited. Or also, if we have, for instance, 200
+ *  memcgs, and none but the 200th is kmem-limited, we'd have to have a
+ *  200 entry array for that.
  *
  * The current size of the caches array is stored in
  * memcg_limited_groups_array_size.  It will double each time we have to
@@ -622,14 +617,14 @@ int memcg_limited_groups_array_size;
  * cgroups is a reasonable guess. In the future, it could be a parameter or
  * tunable, but that is strictly not necessary.
  *
- * MAX_SIZE should be as large as the number of css_ids. Ideally, we could get
+ * MAX_SIZE should be as large as the number of cgrp_ids. Ideally, we could get
  * this constant directly from cgroup, but it is understandable that this is
  * better kept as an internal representation in cgroup.c. In any case, the
- * css_id space is not getting any smaller, and we don't have to necessarily
+ * cgrp_id space is not getting any smaller, and we don't have to necessarily
  * increase ours as well if it increases.
  */
 #define MEMCG_CACHES_MIN_SIZE 4
-#define MEMCG_CACHES_MAX_SIZE 65535
+#define MEMCG_CACHES_MAX_SIZE MEM_CGROUP_ID_MAX
 
 /*
  * A lot of the calls to the cache allocation functions are expected to be
@@ -6183,7 +6178,6 @@ static void __mem_cgroup_free(struct mem_cgroup *memcg)
 	size_t size = memcg_size();
 
 	mem_cgroup_remove_from_trees(memcg);
-	free_css_id(&mem_cgroup_subsys, &memcg->css);
 
 	for_each_node(node)
 		free_mem_cgroup_per_zone_info(memcg, node);
@@ -6980,7 +6974,6 @@ struct cgroup_subsys mem_cgroup_subsys = {
 	.bind = mem_cgroup_bind,
 	.base_cftypes = mem_cgroup_files,
 	.early_init = 0,
-	.use_id = 1,
 };
 
 #ifdef CONFIG_MEMCG_SWAP
-- 
1.8.0.2

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

* [PATCH v2 8/8] cgroup: kill css_id
  2013-07-24  9:58 ` Li Zefan
@ 2013-07-24 10:03   ` Li Zefan
  -1 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24 10:03 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm

The only user of css_id was memcg, and it has been convered to use
cgroup->id, so kill css_id.

Signed-off-by: Li Zefan <lizefan@huwei.com>
---
 include/linux/cgroup.h |  37 --------
 kernel/cgroup.c        | 252 +------------------------------------------------
 2 files changed, 1 insertion(+), 288 deletions(-)

diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index e8eb361..ec8c380 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -599,11 +599,6 @@ struct cgroup_subsys {
 	int subsys_id;
 	int disabled;
 	int early_init;
-	/*
-	 * True if this subsys uses ID. ID is not available before cgroup_init()
-	 * (not available in early_init time.)
-	 */
-	bool use_id;
 
 	/*
 	 * If %false, this subsystem is properly hierarchical -
@@ -629,9 +624,6 @@ struct cgroup_subsys {
 	 */
 	struct cgroupfs_root *root;
 	struct list_head sibling;
-	/* used when use_id == true */
-	struct idr idr;
-	spinlock_t id_lock;
 
 	/* list of cftype_sets */
 	struct list_head cftsets;
@@ -858,35 +850,6 @@ int cgroup_scan_tasks(struct cgroup_scanner *scan);
 int cgroup_attach_task_all(struct task_struct *from, struct task_struct *);
 int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from);
 
-/*
- * CSS ID is ID for cgroup_subsys_state structs under subsys. This only works
- * if cgroup_subsys.use_id == true. It can be used for looking up and scanning.
- * CSS ID is assigned at cgroup allocation (create) automatically
- * and removed when subsys calls free_css_id() function. This is because
- * the lifetime of cgroup_subsys_state is subsys's matter.
- *
- * Looking up and scanning function should be called under rcu_read_lock().
- * Taking cgroup_mutex is not necessary for following calls.
- * But the css returned by this routine can be "not populated yet" or "being
- * destroyed". The caller should check css and cgroup's status.
- */
-
-/*
- * Typically Called at ->destroy(), or somewhere the subsys frees
- * cgroup_subsys_state.
- */
-void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css);
-
-/* Find a cgroup_subsys_state which has given ID */
-
-struct cgroup_subsys_state *css_lookup(struct cgroup_subsys *ss, int id);
-
-/* Returns true if root is ancestor of cg */
-bool css_is_ancestor(struct cgroup_subsys_state *cg,
-		     const struct cgroup_subsys_state *root);
-
-/* Get id and depth of css */
-unsigned short css_id(struct cgroup_subsys_state *css);
 struct cgroup_subsys_state *cgroup_css_from_dir(struct file *f, int id);
 
 #else /* !CONFIG_CGROUPS */
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 9b27775..4333cb7 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -123,38 +123,6 @@ struct cfent {
 };
 
 /*
- * CSS ID -- ID per subsys's Cgroup Subsys State(CSS). used only when
- * cgroup_subsys->use_id != 0.
- */
-#define CSS_ID_MAX	(65535)
-struct css_id {
-	/*
-	 * The css to which this ID points. This pointer is set to valid value
-	 * after cgroup is populated. If cgroup is removed, this will be NULL.
-	 * This pointer is expected to be RCU-safe because destroy()
-	 * is called after synchronize_rcu(). But for safe use, css_tryget()
-	 * should be used for avoiding race.
-	 */
-	struct cgroup_subsys_state __rcu *css;
-	/*
-	 * ID of this css.
-	 */
-	unsigned short id;
-	/*
-	 * Depth in hierarchy which this ID belongs to.
-	 */
-	unsigned short depth;
-	/*
-	 * ID is freed by RCU. (and lookup routine is RCU safe.)
-	 */
-	struct rcu_head rcu_head;
-	/*
-	 * Hierarchy of CSS ID belongs to.
-	 */
-	unsigned short stack[0]; /* Array of Length (depth+1) */
-};
-
-/*
  * cgroup_event represents events which userspace want to receive.
  */
 struct cgroup_event {
@@ -364,9 +332,6 @@ struct cgrp_cset_link {
 static struct css_set init_css_set;
 static struct cgrp_cset_link init_cgrp_cset_link;
 
-static int cgroup_init_idr(struct cgroup_subsys *ss,
-			   struct cgroup_subsys_state *css);
-
 /* css_set_lock protects the list of css_set objects, and the
  * chain of tasks off each css_set.  Nests outside task->alloc_lock
  * due to cgroup_iter_start() */
@@ -815,9 +780,6 @@ static struct backing_dev_info cgroup_backing_dev_info = {
 	.capabilities	= BDI_CAP_NO_ACCT_AND_WRITEBACK,
 };
 
-static int alloc_css_id(struct cgroup_subsys *ss,
-			struct cgroup *parent, struct cgroup *child);
-
 static struct inode *cgroup_new_inode(umode_t mode, struct super_block *sb)
 {
 	struct inode *inode = new_inode(sb);
@@ -4160,20 +4122,6 @@ static int cgroup_populate_dir(struct cgroup *cgrp, unsigned long subsys_mask)
 		}
 	}
 
-	/* This cgroup is ready now */
-	for_each_root_subsys(cgrp->root, ss) {
-		struct cgroup_subsys_state *css = cgrp->subsys[ss->subsys_id];
-		struct css_id *id = rcu_dereference_protected(css->id, true);
-
-		/*
-		 * Update id->css pointer and make this css visible from
-		 * CSS ID functions. This pointer will be dereferened
-		 * from RCU-read-side without locks.
-		 */
-		if (id)
-			rcu_assign_pointer(id->css, css);
-	}
-
 	return 0;
 err:
 	cgroup_clear_dir(cgrp, subsys_mask);
@@ -4202,7 +4150,6 @@ static void init_cgroup_css(struct cgroup_subsys_state *css,
 {
 	css->cgroup = cgrp;
 	css->flags = 0;
-	css->id = NULL;
 	if (cgrp == cgroup_dummy_top)
 		css->flags |= CSS_ROOT;
 	BUG_ON(cgrp->subsys[ss->subsys_id]);
@@ -4331,12 +4278,6 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
 			goto err_free_all;
 
 		init_cgroup_css(css, ss, cgrp);
-
-		if (ss->use_id) {
-			err = alloc_css_id(ss, parent, cgrp);
-			if (err)
-				goto err_free_all;
-		}
 	}
 
 	/*
@@ -4741,12 +4682,6 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
 
 	/* our new subsystem will be attached to the dummy hierarchy. */
 	init_cgroup_css(css, ss, cgroup_dummy_top);
-	/* init_idr must be after init_cgroup_css because it sets css->id. */
-	if (ss->use_id) {
-		ret = cgroup_init_idr(ss, css);
-		if (ret)
-			goto err_unload;
-	}
 
 	/*
 	 * Now we need to entangle the css into the existing css_sets. unlike
@@ -4812,9 +4747,6 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss)
 
 	offline_css(ss, cgroup_dummy_top);
 
-	if (ss->use_id)
-		idr_destroy(&ss->idr);
-
 	/* deassign the subsys_id */
 	cgroup_subsys[ss->subsys_id] = NULL;
 
@@ -4841,8 +4773,7 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss)
 	/*
 	 * remove subsystem's css from the cgroup_dummy_top and free it -
 	 * need to free before marking as null because ss->css_free needs
-	 * the cgrp->subsys pointer to find their state. note that this
-	 * also takes care of freeing the css_id.
+	 * the cgrp->subsys pointer to find their state.
 	 */
 	ss->css_free(cgroup_dummy_top);
 	cgroup_dummy_top->subsys[ss->subsys_id] = NULL;
@@ -4913,8 +4844,6 @@ int __init cgroup_init(void)
 	for_each_builtin_subsys(ss, i) {
 		if (!ss->early_init)
 			cgroup_init_subsys(ss);
-		if (ss->use_id)
-			cgroup_init_idr(ss, init_css_set.subsys[ss->subsys_id]);
 	}
 
 	/* allocate id for the dummy hierarchy */
@@ -5335,185 +5264,6 @@ static int __init cgroup_disable(char *str)
 __setup("cgroup_disable=", cgroup_disable);
 
 /*
- * Functons for CSS ID.
- */
-
-/* to get ID other than 0, this should be called when !cgroup_is_dead() */
-unsigned short css_id(struct cgroup_subsys_state *css)
-{
-	struct css_id *cssid;
-
-	/*
-	 * This css_id() can return correct value when somone has refcnt
-	 * on this or this is under rcu_read_lock(). Once css->id is allocated,
-	 * it's unchanged until freed.
-	 */
-	cssid = rcu_dereference_raw(css->id);
-
-	if (cssid)
-		return cssid->id;
-	return 0;
-}
-EXPORT_SYMBOL_GPL(css_id);
-
-/**
- *  css_is_ancestor - test "root" css is an ancestor of "child"
- * @child: the css to be tested.
- * @root: the css supporsed to be an ancestor of the child.
- *
- * Returns true if "root" is an ancestor of "child" in its hierarchy. Because
- * this function reads css->id, the caller must hold rcu_read_lock().
- * But, considering usual usage, the csses should be valid objects after test.
- * Assuming that the caller will do some action to the child if this returns
- * returns true, the caller must take "child";s reference count.
- * If "child" is valid object and this returns true, "root" is valid, too.
- */
-
-bool css_is_ancestor(struct cgroup_subsys_state *child,
-		    const struct cgroup_subsys_state *root)
-{
-	struct css_id *child_id;
-	struct css_id *root_id;
-
-	child_id  = rcu_dereference(child->id);
-	if (!child_id)
-		return false;
-	root_id = rcu_dereference(root->id);
-	if (!root_id)
-		return false;
-	if (child_id->depth < root_id->depth)
-		return false;
-	if (child_id->stack[root_id->depth] != root_id->id)
-		return false;
-	return true;
-}
-
-void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css)
-{
-	struct css_id *id = rcu_dereference_protected(css->id, true);
-
-	/* When this is called before css_id initialization, id can be NULL */
-	if (!id)
-		return;
-
-	BUG_ON(!ss->use_id);
-
-	rcu_assign_pointer(id->css, NULL);
-	rcu_assign_pointer(css->id, NULL);
-	spin_lock(&ss->id_lock);
-	idr_remove(&ss->idr, id->id);
-	spin_unlock(&ss->id_lock);
-	kfree_rcu(id, rcu_head);
-}
-EXPORT_SYMBOL_GPL(free_css_id);
-
-/*
- * This is called by init or create(). Then, calls to this function are
- * always serialized (By cgroup_mutex() at create()).
- */
-
-static struct css_id *get_new_cssid(struct cgroup_subsys *ss, int depth)
-{
-	struct css_id *newid;
-	int ret, size;
-
-	BUG_ON(!ss->use_id);
-
-	size = sizeof(*newid) + sizeof(unsigned short) * (depth + 1);
-	newid = kzalloc(size, GFP_KERNEL);
-	if (!newid)
-		return ERR_PTR(-ENOMEM);
-
-	idr_preload(GFP_KERNEL);
-	spin_lock(&ss->id_lock);
-	/* Don't use 0. allocates an ID of 1-65535 */
-	ret = idr_alloc(&ss->idr, newid, 1, CSS_ID_MAX + 1, GFP_NOWAIT);
-	spin_unlock(&ss->id_lock);
-	idr_preload_end();
-
-	/* Returns error when there are no free spaces for new ID.*/
-	if (ret < 0)
-		goto err_out;
-
-	newid->id = ret;
-	newid->depth = depth;
-	return newid;
-err_out:
-	kfree(newid);
-	return ERR_PTR(ret);
-
-}
-
-static int __init_or_module cgroup_init_idr(struct cgroup_subsys *ss,
-					    struct cgroup_subsys_state *rootcss)
-{
-	struct css_id *newid;
-
-	spin_lock_init(&ss->id_lock);
-	idr_init(&ss->idr);
-
-	newid = get_new_cssid(ss, 0);
-	if (IS_ERR(newid))
-		return PTR_ERR(newid);
-
-	newid->stack[0] = newid->id;
-	RCU_INIT_POINTER(newid->css, rootcss);
-	RCU_INIT_POINTER(rootcss->id, newid);
-	return 0;
-}
-
-static int alloc_css_id(struct cgroup_subsys *ss, struct cgroup *parent,
-			struct cgroup *child)
-{
-	int subsys_id, i, depth = 0;
-	struct cgroup_subsys_state *parent_css, *child_css;
-	struct css_id *child_id, *parent_id;
-
-	subsys_id = ss->subsys_id;
-	parent_css = parent->subsys[subsys_id];
-	child_css = child->subsys[subsys_id];
-	parent_id = rcu_dereference_protected(parent_css->id, true);
-	depth = parent_id->depth + 1;
-
-	child_id = get_new_cssid(ss, depth);
-	if (IS_ERR(child_id))
-		return PTR_ERR(child_id);
-
-	for (i = 0; i < depth; i++)
-		child_id->stack[i] = parent_id->stack[i];
-	child_id->stack[depth] = child_id->id;
-	/*
-	 * child_id->css pointer will be set after this cgroup is available
-	 * see cgroup_populate_dir()
-	 */
-	rcu_assign_pointer(child_css->id, child_id);
-
-	return 0;
-}
-
-/**
- * css_lookup - lookup css by id
- * @ss: cgroup subsys to be looked into.
- * @id: the id
- *
- * Returns pointer to cgroup_subsys_state if there is valid one with id.
- * NULL if not. Should be called under rcu_read_lock()
- */
-struct cgroup_subsys_state *css_lookup(struct cgroup_subsys *ss, int id)
-{
-	struct css_id *cssid = NULL;
-
-	BUG_ON(!ss->use_id);
-	cssid = idr_find(&ss->idr, id);
-
-	if (unlikely(!cssid))
-		return NULL;
-
-	return rcu_dereference(cssid->css);
-}
-EXPORT_SYMBOL_GPL(css_lookup);
-
-/*
  * get corresponding css from file open on cgroupfs directory
  */
 struct cgroup_subsys_state *cgroup_css_from_dir(struct file *f, int id)
-- 
1.8.0.2

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

* [PATCH v2 8/8] cgroup: kill css_id
@ 2013-07-24 10:03   ` Li Zefan
  0 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-24 10:03 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Michal Hocko,
	Johannes Weiner, LKML, Cgroups, linux-mm

The only user of css_id was memcg, and it has been convered to use
cgroup->id, so kill css_id.

Signed-off-by: Li Zefan <lizefan@huwei.com>
---
 include/linux/cgroup.h |  37 --------
 kernel/cgroup.c        | 252 +------------------------------------------------
 2 files changed, 1 insertion(+), 288 deletions(-)

diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index e8eb361..ec8c380 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -599,11 +599,6 @@ struct cgroup_subsys {
 	int subsys_id;
 	int disabled;
 	int early_init;
-	/*
-	 * True if this subsys uses ID. ID is not available before cgroup_init()
-	 * (not available in early_init time.)
-	 */
-	bool use_id;
 
 	/*
 	 * If %false, this subsystem is properly hierarchical -
@@ -629,9 +624,6 @@ struct cgroup_subsys {
 	 */
 	struct cgroupfs_root *root;
 	struct list_head sibling;
-	/* used when use_id == true */
-	struct idr idr;
-	spinlock_t id_lock;
 
 	/* list of cftype_sets */
 	struct list_head cftsets;
@@ -858,35 +850,6 @@ int cgroup_scan_tasks(struct cgroup_scanner *scan);
 int cgroup_attach_task_all(struct task_struct *from, struct task_struct *);
 int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from);
 
-/*
- * CSS ID is ID for cgroup_subsys_state structs under subsys. This only works
- * if cgroup_subsys.use_id == true. It can be used for looking up and scanning.
- * CSS ID is assigned at cgroup allocation (create) automatically
- * and removed when subsys calls free_css_id() function. This is because
- * the lifetime of cgroup_subsys_state is subsys's matter.
- *
- * Looking up and scanning function should be called under rcu_read_lock().
- * Taking cgroup_mutex is not necessary for following calls.
- * But the css returned by this routine can be "not populated yet" or "being
- * destroyed". The caller should check css and cgroup's status.
- */
-
-/*
- * Typically Called at ->destroy(), or somewhere the subsys frees
- * cgroup_subsys_state.
- */
-void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css);
-
-/* Find a cgroup_subsys_state which has given ID */
-
-struct cgroup_subsys_state *css_lookup(struct cgroup_subsys *ss, int id);
-
-/* Returns true if root is ancestor of cg */
-bool css_is_ancestor(struct cgroup_subsys_state *cg,
-		     const struct cgroup_subsys_state *root);
-
-/* Get id and depth of css */
-unsigned short css_id(struct cgroup_subsys_state *css);
 struct cgroup_subsys_state *cgroup_css_from_dir(struct file *f, int id);
 
 #else /* !CONFIG_CGROUPS */
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 9b27775..4333cb7 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -123,38 +123,6 @@ struct cfent {
 };
 
 /*
- * CSS ID -- ID per subsys's Cgroup Subsys State(CSS). used only when
- * cgroup_subsys->use_id != 0.
- */
-#define CSS_ID_MAX	(65535)
-struct css_id {
-	/*
-	 * The css to which this ID points. This pointer is set to valid value
-	 * after cgroup is populated. If cgroup is removed, this will be NULL.
-	 * This pointer is expected to be RCU-safe because destroy()
-	 * is called after synchronize_rcu(). But for safe use, css_tryget()
-	 * should be used for avoiding race.
-	 */
-	struct cgroup_subsys_state __rcu *css;
-	/*
-	 * ID of this css.
-	 */
-	unsigned short id;
-	/*
-	 * Depth in hierarchy which this ID belongs to.
-	 */
-	unsigned short depth;
-	/*
-	 * ID is freed by RCU. (and lookup routine is RCU safe.)
-	 */
-	struct rcu_head rcu_head;
-	/*
-	 * Hierarchy of CSS ID belongs to.
-	 */
-	unsigned short stack[0]; /* Array of Length (depth+1) */
-};
-
-/*
  * cgroup_event represents events which userspace want to receive.
  */
 struct cgroup_event {
@@ -364,9 +332,6 @@ struct cgrp_cset_link {
 static struct css_set init_css_set;
 static struct cgrp_cset_link init_cgrp_cset_link;
 
-static int cgroup_init_idr(struct cgroup_subsys *ss,
-			   struct cgroup_subsys_state *css);
-
 /* css_set_lock protects the list of css_set objects, and the
  * chain of tasks off each css_set.  Nests outside task->alloc_lock
  * due to cgroup_iter_start() */
@@ -815,9 +780,6 @@ static struct backing_dev_info cgroup_backing_dev_info = {
 	.capabilities	= BDI_CAP_NO_ACCT_AND_WRITEBACK,
 };
 
-static int alloc_css_id(struct cgroup_subsys *ss,
-			struct cgroup *parent, struct cgroup *child);
-
 static struct inode *cgroup_new_inode(umode_t mode, struct super_block *sb)
 {
 	struct inode *inode = new_inode(sb);
@@ -4160,20 +4122,6 @@ static int cgroup_populate_dir(struct cgroup *cgrp, unsigned long subsys_mask)
 		}
 	}
 
-	/* This cgroup is ready now */
-	for_each_root_subsys(cgrp->root, ss) {
-		struct cgroup_subsys_state *css = cgrp->subsys[ss->subsys_id];
-		struct css_id *id = rcu_dereference_protected(css->id, true);
-
-		/*
-		 * Update id->css pointer and make this css visible from
-		 * CSS ID functions. This pointer will be dereferened
-		 * from RCU-read-side without locks.
-		 */
-		if (id)
-			rcu_assign_pointer(id->css, css);
-	}
-
 	return 0;
 err:
 	cgroup_clear_dir(cgrp, subsys_mask);
@@ -4202,7 +4150,6 @@ static void init_cgroup_css(struct cgroup_subsys_state *css,
 {
 	css->cgroup = cgrp;
 	css->flags = 0;
-	css->id = NULL;
 	if (cgrp == cgroup_dummy_top)
 		css->flags |= CSS_ROOT;
 	BUG_ON(cgrp->subsys[ss->subsys_id]);
@@ -4331,12 +4278,6 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
 			goto err_free_all;
 
 		init_cgroup_css(css, ss, cgrp);
-
-		if (ss->use_id) {
-			err = alloc_css_id(ss, parent, cgrp);
-			if (err)
-				goto err_free_all;
-		}
 	}
 
 	/*
@@ -4741,12 +4682,6 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
 
 	/* our new subsystem will be attached to the dummy hierarchy. */
 	init_cgroup_css(css, ss, cgroup_dummy_top);
-	/* init_idr must be after init_cgroup_css because it sets css->id. */
-	if (ss->use_id) {
-		ret = cgroup_init_idr(ss, css);
-		if (ret)
-			goto err_unload;
-	}
 
 	/*
 	 * Now we need to entangle the css into the existing css_sets. unlike
@@ -4812,9 +4747,6 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss)
 
 	offline_css(ss, cgroup_dummy_top);
 
-	if (ss->use_id)
-		idr_destroy(&ss->idr);
-
 	/* deassign the subsys_id */
 	cgroup_subsys[ss->subsys_id] = NULL;
 
@@ -4841,8 +4773,7 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss)
 	/*
 	 * remove subsystem's css from the cgroup_dummy_top and free it -
 	 * need to free before marking as null because ss->css_free needs
-	 * the cgrp->subsys pointer to find their state. note that this
-	 * also takes care of freeing the css_id.
+	 * the cgrp->subsys pointer to find their state.
 	 */
 	ss->css_free(cgroup_dummy_top);
 	cgroup_dummy_top->subsys[ss->subsys_id] = NULL;
@@ -4913,8 +4844,6 @@ int __init cgroup_init(void)
 	for_each_builtin_subsys(ss, i) {
 		if (!ss->early_init)
 			cgroup_init_subsys(ss);
-		if (ss->use_id)
-			cgroup_init_idr(ss, init_css_set.subsys[ss->subsys_id]);
 	}
 
 	/* allocate id for the dummy hierarchy */
@@ -5335,185 +5264,6 @@ static int __init cgroup_disable(char *str)
 __setup("cgroup_disable=", cgroup_disable);
 
 /*
- * Functons for CSS ID.
- */
-
-/* to get ID other than 0, this should be called when !cgroup_is_dead() */
-unsigned short css_id(struct cgroup_subsys_state *css)
-{
-	struct css_id *cssid;
-
-	/*
-	 * This css_id() can return correct value when somone has refcnt
-	 * on this or this is under rcu_read_lock(). Once css->id is allocated,
-	 * it's unchanged until freed.
-	 */
-	cssid = rcu_dereference_raw(css->id);
-
-	if (cssid)
-		return cssid->id;
-	return 0;
-}
-EXPORT_SYMBOL_GPL(css_id);
-
-/**
- *  css_is_ancestor - test "root" css is an ancestor of "child"
- * @child: the css to be tested.
- * @root: the css supporsed to be an ancestor of the child.
- *
- * Returns true if "root" is an ancestor of "child" in its hierarchy. Because
- * this function reads css->id, the caller must hold rcu_read_lock().
- * But, considering usual usage, the csses should be valid objects after test.
- * Assuming that the caller will do some action to the child if this returns
- * returns true, the caller must take "child";s reference count.
- * If "child" is valid object and this returns true, "root" is valid, too.
- */
-
-bool css_is_ancestor(struct cgroup_subsys_state *child,
-		    const struct cgroup_subsys_state *root)
-{
-	struct css_id *child_id;
-	struct css_id *root_id;
-
-	child_id  = rcu_dereference(child->id);
-	if (!child_id)
-		return false;
-	root_id = rcu_dereference(root->id);
-	if (!root_id)
-		return false;
-	if (child_id->depth < root_id->depth)
-		return false;
-	if (child_id->stack[root_id->depth] != root_id->id)
-		return false;
-	return true;
-}
-
-void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css)
-{
-	struct css_id *id = rcu_dereference_protected(css->id, true);
-
-	/* When this is called before css_id initialization, id can be NULL */
-	if (!id)
-		return;
-
-	BUG_ON(!ss->use_id);
-
-	rcu_assign_pointer(id->css, NULL);
-	rcu_assign_pointer(css->id, NULL);
-	spin_lock(&ss->id_lock);
-	idr_remove(&ss->idr, id->id);
-	spin_unlock(&ss->id_lock);
-	kfree_rcu(id, rcu_head);
-}
-EXPORT_SYMBOL_GPL(free_css_id);
-
-/*
- * This is called by init or create(). Then, calls to this function are
- * always serialized (By cgroup_mutex() at create()).
- */
-
-static struct css_id *get_new_cssid(struct cgroup_subsys *ss, int depth)
-{
-	struct css_id *newid;
-	int ret, size;
-
-	BUG_ON(!ss->use_id);
-
-	size = sizeof(*newid) + sizeof(unsigned short) * (depth + 1);
-	newid = kzalloc(size, GFP_KERNEL);
-	if (!newid)
-		return ERR_PTR(-ENOMEM);
-
-	idr_preload(GFP_KERNEL);
-	spin_lock(&ss->id_lock);
-	/* Don't use 0. allocates an ID of 1-65535 */
-	ret = idr_alloc(&ss->idr, newid, 1, CSS_ID_MAX + 1, GFP_NOWAIT);
-	spin_unlock(&ss->id_lock);
-	idr_preload_end();
-
-	/* Returns error when there are no free spaces for new ID.*/
-	if (ret < 0)
-		goto err_out;
-
-	newid->id = ret;
-	newid->depth = depth;
-	return newid;
-err_out:
-	kfree(newid);
-	return ERR_PTR(ret);
-
-}
-
-static int __init_or_module cgroup_init_idr(struct cgroup_subsys *ss,
-					    struct cgroup_subsys_state *rootcss)
-{
-	struct css_id *newid;
-
-	spin_lock_init(&ss->id_lock);
-	idr_init(&ss->idr);
-
-	newid = get_new_cssid(ss, 0);
-	if (IS_ERR(newid))
-		return PTR_ERR(newid);
-
-	newid->stack[0] = newid->id;
-	RCU_INIT_POINTER(newid->css, rootcss);
-	RCU_INIT_POINTER(rootcss->id, newid);
-	return 0;
-}
-
-static int alloc_css_id(struct cgroup_subsys *ss, struct cgroup *parent,
-			struct cgroup *child)
-{
-	int subsys_id, i, depth = 0;
-	struct cgroup_subsys_state *parent_css, *child_css;
-	struct css_id *child_id, *parent_id;
-
-	subsys_id = ss->subsys_id;
-	parent_css = parent->subsys[subsys_id];
-	child_css = child->subsys[subsys_id];
-	parent_id = rcu_dereference_protected(parent_css->id, true);
-	depth = parent_id->depth + 1;
-
-	child_id = get_new_cssid(ss, depth);
-	if (IS_ERR(child_id))
-		return PTR_ERR(child_id);
-
-	for (i = 0; i < depth; i++)
-		child_id->stack[i] = parent_id->stack[i];
-	child_id->stack[depth] = child_id->id;
-	/*
-	 * child_id->css pointer will be set after this cgroup is available
-	 * see cgroup_populate_dir()
-	 */
-	rcu_assign_pointer(child_css->id, child_id);
-
-	return 0;
-}
-
-/**
- * css_lookup - lookup css by id
- * @ss: cgroup subsys to be looked into.
- * @id: the id
- *
- * Returns pointer to cgroup_subsys_state if there is valid one with id.
- * NULL if not. Should be called under rcu_read_lock()
- */
-struct cgroup_subsys_state *css_lookup(struct cgroup_subsys *ss, int id)
-{
-	struct css_id *cssid = NULL;
-
-	BUG_ON(!ss->use_id);
-	cssid = idr_find(&ss->idr, id);
-
-	if (unlikely(!cssid))
-		return NULL;
-
-	return rcu_dereference(cssid->css);
-}
-EXPORT_SYMBOL_GPL(css_lookup);
-
-/*
  * get corresponding css from file open on cgroupfs directory
  */
 struct cgroup_subsys_state *cgroup_css_from_dir(struct file *f, int id)
-- 
1.8.0.2

--
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] 52+ messages in thread

* Re: [PATCH v2 1/8] cgroup: convert cgroup_ida to cgroup_idr
  2013-07-24  9:59   ` Li Zefan
@ 2013-07-24 14:07     ` Michal Hocko
  -1 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-24 14:07 UTC (permalink / raw)
  To: Li Zefan
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 17:59:12, Li Zefan wrote:
> This enables us to lookup a cgroup by its id.
> 
> Signed-off-by: Li Zefan <lizefan@huawei.com>

Reviewed-by: Michal Hocko <mhocko@suse.cz>

One nit/question bellow
[...]
> @@ -4268,15 +4271,19 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
>  	if (!cgrp)
>  		return -ENOMEM;
>  
> +	/*
> +	 * Temporarily set the pointer to NULL, so idr_find() won't return
> +	 * a half-baked cgroup.
> +	 */
> +	cgrp->id = idr_alloc(&root->cgroup_idr, NULL, 1, 0, GFP_KERNEL);
> +	if (cgrp->id < 0)
> +		goto err_free_cgrp;
> +
>  	name = cgroup_alloc_name(dentry);
>  	if (!name)
> -		goto err_free_cgrp;
> +		goto err_free_id;
>  	rcu_assign_pointer(cgrp->name, name);
>  
> -	cgrp->id = ida_simple_get(&root->cgroup_ida, 1, 0, GFP_KERNEL);
> -	if (cgrp->id < 0)
> -		goto err_free_name;
> -

Is the move necessary? You would safe few lines in the patch if you kept
the ordering.

>  	/*
>  	 * Only live parents can have children.  Note that the liveliness
>  	 * check isn't strictly necessary because cgroup_mkdir() and
> @@ -4286,7 +4293,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
>  	 */
>  	if (!cgroup_lock_live_group(parent)) {
>  		err = -ENODEV;
> -		goto err_free_id;
> +		goto err_free_name;
>  	}
>  
>  	/* Grab a reference on the superblock so the hierarchy doesn't
> @@ -4371,6 +4378,8 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
>  		}
>  	}
>  
> +	idr_replace(&root->cgroup_idr, cgrp, cgrp->id);
> +
>  	err = cgroup_addrm_files(cgrp, NULL, cgroup_base_files, true);
>  	if (err)
>  		goto err_destroy;
> @@ -4396,10 +4405,10 @@ err_free_all:
>  	mutex_unlock(&cgroup_mutex);
>  	/* Release the reference count that we took on the superblock */
>  	deactivate_super(sb);
> -err_free_id:
> -	ida_simple_remove(&root->cgroup_ida, cgrp->id);
>  err_free_name:
>  	kfree(rcu_dereference_raw(cgrp->name));
> +err_free_id:
> +	idr_remove(&root->cgroup_idr, cgrp->id);
>  err_free_cgrp:
>  	kfree(cgrp);
>  	return err;
[...]
-- 
Michal Hocko
SUSE Labs

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

* Re: [PATCH v2 1/8] cgroup: convert cgroup_ida to cgroup_idr
@ 2013-07-24 14:07     ` Michal Hocko
  0 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-24 14:07 UTC (permalink / raw)
  To: Li Zefan
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 17:59:12, Li Zefan wrote:
> This enables us to lookup a cgroup by its id.
> 
> Signed-off-by: Li Zefan <lizefan@huawei.com>

Reviewed-by: Michal Hocko <mhocko@suse.cz>

One nit/question bellow
[...]
> @@ -4268,15 +4271,19 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
>  	if (!cgrp)
>  		return -ENOMEM;
>  
> +	/*
> +	 * Temporarily set the pointer to NULL, so idr_find() won't return
> +	 * a half-baked cgroup.
> +	 */
> +	cgrp->id = idr_alloc(&root->cgroup_idr, NULL, 1, 0, GFP_KERNEL);
> +	if (cgrp->id < 0)
> +		goto err_free_cgrp;
> +
>  	name = cgroup_alloc_name(dentry);
>  	if (!name)
> -		goto err_free_cgrp;
> +		goto err_free_id;
>  	rcu_assign_pointer(cgrp->name, name);
>  
> -	cgrp->id = ida_simple_get(&root->cgroup_ida, 1, 0, GFP_KERNEL);
> -	if (cgrp->id < 0)
> -		goto err_free_name;
> -

Is the move necessary? You would safe few lines in the patch if you kept
the ordering.

>  	/*
>  	 * Only live parents can have children.  Note that the liveliness
>  	 * check isn't strictly necessary because cgroup_mkdir() and
> @@ -4286,7 +4293,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
>  	 */
>  	if (!cgroup_lock_live_group(parent)) {
>  		err = -ENODEV;
> -		goto err_free_id;
> +		goto err_free_name;
>  	}
>  
>  	/* Grab a reference on the superblock so the hierarchy doesn't
> @@ -4371,6 +4378,8 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
>  		}
>  	}
>  
> +	idr_replace(&root->cgroup_idr, cgrp, cgrp->id);
> +
>  	err = cgroup_addrm_files(cgrp, NULL, cgroup_base_files, true);
>  	if (err)
>  		goto err_destroy;
> @@ -4396,10 +4405,10 @@ err_free_all:
>  	mutex_unlock(&cgroup_mutex);
>  	/* Release the reference count that we took on the superblock */
>  	deactivate_super(sb);
> -err_free_id:
> -	ida_simple_remove(&root->cgroup_ida, cgrp->id);
>  err_free_name:
>  	kfree(rcu_dereference_raw(cgrp->name));
> +err_free_id:
> +	idr_remove(&root->cgroup_idr, cgrp->id);
>  err_free_cgrp:
>  	kfree(cgrp);
>  	return err;
[...]
-- 
Michal Hocko
SUSE Labs

--
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] 52+ messages in thread

* Re: [PATCH v2 2/8] cgroup: document how cgroup IDs are assigned
  2013-07-24  9:59   ` Li Zefan
@ 2013-07-24 14:07     ` Michal Hocko
  -1 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-24 14:07 UTC (permalink / raw)
  To: Li Zefan
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 17:59:55, Li Zefan wrote:
> As cgroup id has been used in netprio cgroup and will be used in memcg,
> it's important to make it clear how a cgroup id is allocated.
> 
> For example, in netprio cgroup, the id is used as index of an array.
> 
> Signed-off-by: Li Zefan <lizefan@huwei.com>

Reviewed-by: Michal Hocko <mhocko@suse.cz>

> ---
>  include/linux/cgroup.h | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
> index 2bd052d..8c107e9 100644
> --- a/include/linux/cgroup.h
> +++ b/include/linux/cgroup.h
> @@ -161,7 +161,13 @@ struct cgroup_name {
>  struct cgroup {
>  	unsigned long flags;		/* "unsigned long" so bitops work */
>  
> -	int id;				/* idr allocated in-hierarchy ID */
> +	/*
> +	 * idr allocated in-hierarchy ID.
> +	 *
> +	 * The ID of the root cgroup is always 0, and a new cgroup
> +	 * will be assigned with a smallest available ID.
> +	 */
> +	int id;
>  
>  	/*
>  	 * We link our 'sibling' struct into our parent's 'children'.
> -- 
> 1.8.0.2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe cgroups" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Michal Hocko
SUSE Labs

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

* Re: [PATCH v2 2/8] cgroup: document how cgroup IDs are assigned
@ 2013-07-24 14:07     ` Michal Hocko
  0 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-24 14:07 UTC (permalink / raw)
  To: Li Zefan
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 17:59:55, Li Zefan wrote:
> As cgroup id has been used in netprio cgroup and will be used in memcg,
> it's important to make it clear how a cgroup id is allocated.
> 
> For example, in netprio cgroup, the id is used as index of an array.
> 
> Signed-off-by: Li Zefan <lizefan@huwei.com>

Reviewed-by: Michal Hocko <mhocko@suse.cz>

> ---
>  include/linux/cgroup.h | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
> index 2bd052d..8c107e9 100644
> --- a/include/linux/cgroup.h
> +++ b/include/linux/cgroup.h
> @@ -161,7 +161,13 @@ struct cgroup_name {
>  struct cgroup {
>  	unsigned long flags;		/* "unsigned long" so bitops work */
>  
> -	int id;				/* idr allocated in-hierarchy ID */
> +	/*
> +	 * idr allocated in-hierarchy ID.
> +	 *
> +	 * The ID of the root cgroup is always 0, and a new cgroup
> +	 * will be assigned with a smallest available ID.
> +	 */
> +	int id;
>  
>  	/*
>  	 * We link our 'sibling' struct into our parent's 'children'.
> -- 
> 1.8.0.2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe cgroups" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Michal Hocko
SUSE Labs

--
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] 52+ messages in thread

* Re: [PATCH v2 3/8] cgroup: implement cgroup_from_id()
  2013-07-24 10:00   ` Li Zefan
@ 2013-07-24 14:10     ` Michal Hocko
  -1 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-24 14:10 UTC (permalink / raw)
  To: Li Zefan
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 18:00:39, Li Zefan wrote:
> This will be used as a replacement for css_lookup().
> 
> There's a difference with cgroup id and css id. cgroup id starts with 0,
> while css id starts with 1.
> 
> Signed-off-by: Li Zefan <lizefan@huawei.com>

Reviewed-by: Michal Hocko <mhocko@suse.cz>

Typo fix bellow
[...]
> diff --git a/kernel/cgroup.c b/kernel/cgroup.c
> index ee3c02e..9b27775 100644
> --- a/kernel/cgroup.c
> +++ b/kernel/cgroup.c
> @@ -5536,6 +5536,22 @@ struct cgroup_subsys_state *cgroup_css_from_dir(struct file *f, int id)
>  	return css ? css : ERR_PTR(-ENOENT);
>  }
>  
> +/**
> + * cgroup_from_id - lookup cgroup by id
> + * @ss: cgroup subsys to be looked into
> + * @id: the cgroup id
> + *
> + * Returns the cgroup is there's valid one with @id, otherwise returns Null.

s/ is / if /

> + * Should be called under rcu_readlock().
> + */
> +struct cgroup *cgroup_from_id(struct cgroup_subsys *ss, int id)
> +{
> +	rcu_lockdep_assert(rcu_read_lock_held(),
> +			   "cgroup_from_id() needs rcu_read_lock()"
> +			   " protection");
> +	return idr_find(&ss->root->cgroup_idr, id);
> +}
> +
>  #ifdef CONFIG_CGROUP_DEBUG
>  static struct cgroup_subsys_state *debug_css_alloc(struct cgroup *cgrp)
>  {
> -- 
> 1.8.0.2

-- 
Michal Hocko
SUSE Labs

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

* Re: [PATCH v2 3/8] cgroup: implement cgroup_from_id()
@ 2013-07-24 14:10     ` Michal Hocko
  0 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-24 14:10 UTC (permalink / raw)
  To: Li Zefan
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 18:00:39, Li Zefan wrote:
> This will be used as a replacement for css_lookup().
> 
> There's a difference with cgroup id and css id. cgroup id starts with 0,
> while css id starts with 1.
> 
> Signed-off-by: Li Zefan <lizefan@huawei.com>

Reviewed-by: Michal Hocko <mhocko@suse.cz>

Typo fix bellow
[...]
> diff --git a/kernel/cgroup.c b/kernel/cgroup.c
> index ee3c02e..9b27775 100644
> --- a/kernel/cgroup.c
> +++ b/kernel/cgroup.c
> @@ -5536,6 +5536,22 @@ struct cgroup_subsys_state *cgroup_css_from_dir(struct file *f, int id)
>  	return css ? css : ERR_PTR(-ENOENT);
>  }
>  
> +/**
> + * cgroup_from_id - lookup cgroup by id
> + * @ss: cgroup subsys to be looked into
> + * @id: the cgroup id
> + *
> + * Returns the cgroup is there's valid one with @id, otherwise returns Null.

s/ is / if /

> + * Should be called under rcu_readlock().
> + */
> +struct cgroup *cgroup_from_id(struct cgroup_subsys *ss, int id)
> +{
> +	rcu_lockdep_assert(rcu_read_lock_held(),
> +			   "cgroup_from_id() needs rcu_read_lock()"
> +			   " protection");
> +	return idr_find(&ss->root->cgroup_idr, id);
> +}
> +
>  #ifdef CONFIG_CGROUP_DEBUG
>  static struct cgroup_subsys_state *debug_css_alloc(struct cgroup *cgrp)
>  {
> -- 
> 1.8.0.2

-- 
Michal Hocko
SUSE Labs

--
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] 52+ messages in thread

* Re: [PATCH v2 4/8] memcg: convert to use cgroup_is_descendant()
  2013-07-24 10:01   ` Li Zefan
@ 2013-07-24 14:20     ` Michal Hocko
  -1 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-24 14:20 UTC (permalink / raw)
  To: Li Zefan
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 18:01:25, Li Zefan wrote:
> This is a preparation to kill css_id.
> 
> Signed-off-by: Li Zefan <lizefan@huawei.com>

css_is_ancestor doesn't depend on the depth of the hierarchy while
cgroup_is_descendant does. I do not think this would be an issue though
as __mem_cgroup_same_or_subtree is not called from any hot path.

Acked-by: Michal Hocko <mhocko@suse.cz>

> ---
>  mm/memcontrol.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index d12ca6f..626c426 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -1434,7 +1434,7 @@ bool __mem_cgroup_same_or_subtree(const struct mem_cgroup *root_memcg,
>  		return true;
>  	if (!root_memcg->use_hierarchy || !memcg)
>  		return false;
> -	return css_is_ancestor(&memcg->css, &root_memcg->css);
> +	return cgroup_is_descendant(memcg->css.cgroup, root_memcg->css.cgroup);
>  }
>  
>  static bool mem_cgroup_same_or_subtree(const struct mem_cgroup *root_memcg,
> -- 
> 1.8.0.2
> 

-- 
Michal Hocko
SUSE Labs

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

* Re: [PATCH v2 4/8] memcg: convert to use cgroup_is_descendant()
@ 2013-07-24 14:20     ` Michal Hocko
  0 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-24 14:20 UTC (permalink / raw)
  To: Li Zefan
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 18:01:25, Li Zefan wrote:
> This is a preparation to kill css_id.
> 
> Signed-off-by: Li Zefan <lizefan@huawei.com>

css_is_ancestor doesn't depend on the depth of the hierarchy while
cgroup_is_descendant does. I do not think this would be an issue though
as __mem_cgroup_same_or_subtree is not called from any hot path.

Acked-by: Michal Hocko <mhocko@suse.cz>

> ---
>  mm/memcontrol.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index d12ca6f..626c426 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -1434,7 +1434,7 @@ bool __mem_cgroup_same_or_subtree(const struct mem_cgroup *root_memcg,
>  		return true;
>  	if (!root_memcg->use_hierarchy || !memcg)
>  		return false;
> -	return css_is_ancestor(&memcg->css, &root_memcg->css);
> +	return cgroup_is_descendant(memcg->css.cgroup, root_memcg->css.cgroup);
>  }
>  
>  static bool mem_cgroup_same_or_subtree(const struct mem_cgroup *root_memcg,
> -- 
> 1.8.0.2
> 

-- 
Michal Hocko
SUSE Labs

--
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] 52+ messages in thread

* Re: [PATCH v2 5/8] memcg: convert to use cgroup id
  2013-07-24 10:01   ` Li Zefan
@ 2013-07-24 14:25     ` Michal Hocko
  -1 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-24 14:25 UTC (permalink / raw)
  To: Li Zefan
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 18:01:53, Li Zefan wrote:
> Use cgroup id instead of css id. This is a preparation to kill css id.
> 
> Note, as memcg treats 0 as an invalid id, while cgroup id starts with 0,
> we define memcg_id == cgroup_id + 1.
> 
> Signed-off-by: Li Zefan <lizefan@huawei.com>

Acked-by: Michal Hocko <mhocko@suse.cz>

two thing bellow

> ---
>  mm/memcontrol.c | 25 +++++++++++++++++--------
>  1 file changed, 17 insertions(+), 8 deletions(-)
> 
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index 626c426..35d8286 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -512,6 +512,15 @@ static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg)
>  	return (memcg == root_mem_cgroup);
>  }
>  
> +static inline unsigned short mem_cgroup_id(struct mem_cgroup *memcg)
> +{
> +	/*
> +	 * The ID of the root cgroup is 0, but memcg treat 0 as an
> +	 * valid ID, so we return (cgroup_id + 1).

s/valid/invalid/ you meant, right?

> +	 */
> +	return memcg->css.cgroup->id + 1;
> +}
> +

Could you add mem_cgroup_from_id(short id) which would hide "id - 1".

>  /* Writing them here to avoid exposing memcg's inner layout */
>  #if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM)
>  
> @@ -2821,15 +2830,15 @@ static void __mem_cgroup_cancel_local_charge(struct mem_cgroup *memcg,
>   */
>  static struct mem_cgroup *mem_cgroup_lookup(unsigned short id)
>  {
> -	struct cgroup_subsys_state *css;
> +	struct cgroup *cgrp;
>  
>  	/* ID 0 is unused ID */
>  	if (!id)
>  		return NULL;
> -	css = css_lookup(&mem_cgroup_subsys, id);
> -	if (!css)
> +	cgrp = cgroup_from_id(&mem_cgroup_subsys, id - 1);
> +	if (!cgrp)
>  		return NULL;
> -	return mem_cgroup_from_css(css);
> +	return mem_cgroup_from_cont(cgrp);
>  }
>  
>  struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page)
> @@ -4328,7 +4337,7 @@ mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent, bool swapout)
>  	 * css_get() was called in uncharge().
>  	 */
>  	if (do_swap_account && swapout && memcg)
> -		swap_cgroup_record(ent, css_id(&memcg->css));
> +		swap_cgroup_record(ent, mem_cgroup_id(memcg));
>  }
>  #endif
>  
> @@ -4380,8 +4389,8 @@ static int mem_cgroup_move_swap_account(swp_entry_t entry,
>  {
>  	unsigned short old_id, new_id;
>  
> -	old_id = css_id(&from->css);
> -	new_id = css_id(&to->css);
> +	old_id = mem_cgroup_id(from);
> +	new_id = mem_cgroup_id(to);
>  
>  	if (swap_cgroup_cmpxchg(entry, old_id, new_id) == old_id) {
>  		mem_cgroup_swap_statistics(from, false);
> @@ -6542,7 +6551,7 @@ static enum mc_target_type get_mctgt_type(struct vm_area_struct *vma,
>  	}
>  	/* There is a swap entry and a page doesn't exist or isn't charged */
>  	if (ent.val && !ret &&
> -			css_id(&mc.from->css) == lookup_swap_cgroup_id(ent)) {
> +	    mem_cgroup_id(mc.from) == lookup_swap_cgroup_id(ent)) {
>  		ret = MC_TARGET_SWAP;
>  		if (target)
>  			target->ent = ent;
> -- 
> 1.8.0.2

-- 
Michal Hocko
SUSE Labs

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

* Re: [PATCH v2 5/8] memcg: convert to use cgroup id
@ 2013-07-24 14:25     ` Michal Hocko
  0 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-24 14:25 UTC (permalink / raw)
  To: Li Zefan
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 18:01:53, Li Zefan wrote:
> Use cgroup id instead of css id. This is a preparation to kill css id.
> 
> Note, as memcg treats 0 as an invalid id, while cgroup id starts with 0,
> we define memcg_id == cgroup_id + 1.
> 
> Signed-off-by: Li Zefan <lizefan@huawei.com>

Acked-by: Michal Hocko <mhocko@suse.cz>

two thing bellow

> ---
>  mm/memcontrol.c | 25 +++++++++++++++++--------
>  1 file changed, 17 insertions(+), 8 deletions(-)
> 
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index 626c426..35d8286 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -512,6 +512,15 @@ static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg)
>  	return (memcg == root_mem_cgroup);
>  }
>  
> +static inline unsigned short mem_cgroup_id(struct mem_cgroup *memcg)
> +{
> +	/*
> +	 * The ID of the root cgroup is 0, but memcg treat 0 as an
> +	 * valid ID, so we return (cgroup_id + 1).

s/valid/invalid/ you meant, right?

> +	 */
> +	return memcg->css.cgroup->id + 1;
> +}
> +

Could you add mem_cgroup_from_id(short id) which would hide "id - 1".

>  /* Writing them here to avoid exposing memcg's inner layout */
>  #if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM)
>  
> @@ -2821,15 +2830,15 @@ static void __mem_cgroup_cancel_local_charge(struct mem_cgroup *memcg,
>   */
>  static struct mem_cgroup *mem_cgroup_lookup(unsigned short id)
>  {
> -	struct cgroup_subsys_state *css;
> +	struct cgroup *cgrp;
>  
>  	/* ID 0 is unused ID */
>  	if (!id)
>  		return NULL;
> -	css = css_lookup(&mem_cgroup_subsys, id);
> -	if (!css)
> +	cgrp = cgroup_from_id(&mem_cgroup_subsys, id - 1);
> +	if (!cgrp)
>  		return NULL;
> -	return mem_cgroup_from_css(css);
> +	return mem_cgroup_from_cont(cgrp);
>  }
>  
>  struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page)
> @@ -4328,7 +4337,7 @@ mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent, bool swapout)
>  	 * css_get() was called in uncharge().
>  	 */
>  	if (do_swap_account && swapout && memcg)
> -		swap_cgroup_record(ent, css_id(&memcg->css));
> +		swap_cgroup_record(ent, mem_cgroup_id(memcg));
>  }
>  #endif
>  
> @@ -4380,8 +4389,8 @@ static int mem_cgroup_move_swap_account(swp_entry_t entry,
>  {
>  	unsigned short old_id, new_id;
>  
> -	old_id = css_id(&from->css);
> -	new_id = css_id(&to->css);
> +	old_id = mem_cgroup_id(from);
> +	new_id = mem_cgroup_id(to);
>  
>  	if (swap_cgroup_cmpxchg(entry, old_id, new_id) == old_id) {
>  		mem_cgroup_swap_statistics(from, false);
> @@ -6542,7 +6551,7 @@ static enum mc_target_type get_mctgt_type(struct vm_area_struct *vma,
>  	}
>  	/* There is a swap entry and a page doesn't exist or isn't charged */
>  	if (ent.val && !ret &&
> -			css_id(&mc.from->css) == lookup_swap_cgroup_id(ent)) {
> +	    mem_cgroup_id(mc.from) == lookup_swap_cgroup_id(ent)) {
>  		ret = MC_TARGET_SWAP;
>  		if (target)
>  			target->ent = ent;
> -- 
> 1.8.0.2

-- 
Michal Hocko
SUSE Labs

--
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] 52+ messages in thread

* Re: [PATCH v2 6/8] memcg: fail to create cgroup if the cgroup id is too big
  2013-07-24 10:02   ` Li Zefan
@ 2013-07-24 14:27     ` Michal Hocko
  -1 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-24 14:27 UTC (permalink / raw)
  To: Li Zefan
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 18:02:19, Li Zefan wrote:
> memcg requires the cgroup id to be smaller than 65536.
> 
> Signed-off-by: Li Zefan <lizefan@huawei.com>

Acked-by: Michal Hocko <mhocko@suse.cz>

One suggestion bellow

> ---
>  mm/memcontrol.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index 35d8286..403c8d9 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -512,6 +512,12 @@ static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg)
>  	return (memcg == root_mem_cgroup);
>  }
>  
> +/*
> + * We restrict the id in the range of [1, 65535], so it can fit into
> + * an unsigned short.
> + */
> +#define MEM_CGROUP_ID_MAX	(65535)

USHRT_MAX

> +
>  static inline unsigned short mem_cgroup_id(struct mem_cgroup *memcg)
>  {
>  	/*
> @@ -6243,6 +6249,9 @@ mem_cgroup_css_alloc(struct cgroup *cont)
>  	long error = -ENOMEM;
>  	int node;
>  
> +	if (cont->id > MEM_CGROUP_ID_MAX)
> +		return ERR_PTR(-ENOSPC);
> +
>  	memcg = mem_cgroup_alloc();
>  	if (!memcg)
>  		return ERR_PTR(error);
> -- 
> 1.8.0.2
> 
> --
> 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>

-- 
Michal Hocko
SUSE Labs

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

* Re: [PATCH v2 6/8] memcg: fail to create cgroup if the cgroup id is too big
@ 2013-07-24 14:27     ` Michal Hocko
  0 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-24 14:27 UTC (permalink / raw)
  To: Li Zefan
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 18:02:19, Li Zefan wrote:
> memcg requires the cgroup id to be smaller than 65536.
> 
> Signed-off-by: Li Zefan <lizefan@huawei.com>

Acked-by: Michal Hocko <mhocko@suse.cz>

One suggestion bellow

> ---
>  mm/memcontrol.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index 35d8286..403c8d9 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -512,6 +512,12 @@ static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg)
>  	return (memcg == root_mem_cgroup);
>  }
>  
> +/*
> + * We restrict the id in the range of [1, 65535], so it can fit into
> + * an unsigned short.
> + */
> +#define MEM_CGROUP_ID_MAX	(65535)

USHRT_MAX

> +
>  static inline unsigned short mem_cgroup_id(struct mem_cgroup *memcg)
>  {
>  	/*
> @@ -6243,6 +6249,9 @@ mem_cgroup_css_alloc(struct cgroup *cont)
>  	long error = -ENOMEM;
>  	int node;
>  
> +	if (cont->id > MEM_CGROUP_ID_MAX)
> +		return ERR_PTR(-ENOSPC);
> +
>  	memcg = mem_cgroup_alloc();
>  	if (!memcg)
>  		return ERR_PTR(error);
> -- 
> 1.8.0.2
> 
> --
> 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>

-- 
Michal Hocko
SUSE Labs

--
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] 52+ messages in thread

* Re: [PATCH v2 7/8] memcg: stop using css id
  2013-07-24 10:03   ` Li Zefan
@ 2013-07-24 14:30     ` Michal Hocko
  -1 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-24 14:30 UTC (permalink / raw)
  To: Li Zefan
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 18:03:03, Li Zefan wrote:
> Now memcg uses cgroup id instead of css id. Update some comments and
> set mem_cgroup_subsys->use_id to 0.
> 
> Signed-off-by: Li Zefan <lizefan@huawei.com>

Acked-by: Michal Hocko <mhocko@suse.cz>

> ---
>  mm/memcontrol.c | 23 ++++++++---------------
>  1 file changed, 8 insertions(+), 15 deletions(-)
> 
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index 403c8d9..03c8bf7 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -598,16 +598,11 @@ static void disarm_sock_keys(struct mem_cgroup *memcg)
>  #ifdef CONFIG_MEMCG_KMEM
>  /*
>   * This will be the memcg's index in each cache's ->memcg_params->memcg_caches.
> - * There are two main reasons for not using the css_id for this:
> - *  1) this works better in sparse environments, where we have a lot of memcgs,
> - *     but only a few kmem-limited. Or also, if we have, for instance, 200
> - *     memcgs, and none but the 200th is kmem-limited, we'd have to have a
> - *     200 entry array for that.
> - *
> - *  2) In order not to violate the cgroup API, we would like to do all memory
> - *     allocation in ->create(). At that point, we haven't yet allocated the
> - *     css_id. Having a separate index prevents us from messing with the cgroup
> - *     core for this
> + * The main reason for not using cgroup id for this:
> + *  this works better in sparse environments, where we have a lot of memcgs,
> + *  but only a few kmem-limited. Or also, if we have, for instance, 200
> + *  memcgs, and none but the 200th is kmem-limited, we'd have to have a
> + *  200 entry array for that.
>   *
>   * The current size of the caches array is stored in
>   * memcg_limited_groups_array_size.  It will double each time we have to
> @@ -622,14 +617,14 @@ int memcg_limited_groups_array_size;
>   * cgroups is a reasonable guess. In the future, it could be a parameter or
>   * tunable, but that is strictly not necessary.
>   *
> - * MAX_SIZE should be as large as the number of css_ids. Ideally, we could get
> + * MAX_SIZE should be as large as the number of cgrp_ids. Ideally, we could get
>   * this constant directly from cgroup, but it is understandable that this is
>   * better kept as an internal representation in cgroup.c. In any case, the
> - * css_id space is not getting any smaller, and we don't have to necessarily
> + * cgrp_id space is not getting any smaller, and we don't have to necessarily
>   * increase ours as well if it increases.
>   */
>  #define MEMCG_CACHES_MIN_SIZE 4
> -#define MEMCG_CACHES_MAX_SIZE 65535
> +#define MEMCG_CACHES_MAX_SIZE MEM_CGROUP_ID_MAX
>  
>  /*
>   * A lot of the calls to the cache allocation functions are expected to be
> @@ -6183,7 +6178,6 @@ static void __mem_cgroup_free(struct mem_cgroup *memcg)
>  	size_t size = memcg_size();
>  
>  	mem_cgroup_remove_from_trees(memcg);
> -	free_css_id(&mem_cgroup_subsys, &memcg->css);
>  
>  	for_each_node(node)
>  		free_mem_cgroup_per_zone_info(memcg, node);
> @@ -6980,7 +6974,6 @@ struct cgroup_subsys mem_cgroup_subsys = {
>  	.bind = mem_cgroup_bind,
>  	.base_cftypes = mem_cgroup_files,
>  	.early_init = 0,
> -	.use_id = 1,
>  };
>  
>  #ifdef CONFIG_MEMCG_SWAP
> -- 
> 1.8.0.2

-- 
Michal Hocko
SUSE Labs

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

* Re: [PATCH v2 7/8] memcg: stop using css id
@ 2013-07-24 14:30     ` Michal Hocko
  0 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-24 14:30 UTC (permalink / raw)
  To: Li Zefan
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 18:03:03, Li Zefan wrote:
> Now memcg uses cgroup id instead of css id. Update some comments and
> set mem_cgroup_subsys->use_id to 0.
> 
> Signed-off-by: Li Zefan <lizefan@huawei.com>

Acked-by: Michal Hocko <mhocko@suse.cz>

> ---
>  mm/memcontrol.c | 23 ++++++++---------------
>  1 file changed, 8 insertions(+), 15 deletions(-)
> 
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index 403c8d9..03c8bf7 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -598,16 +598,11 @@ static void disarm_sock_keys(struct mem_cgroup *memcg)
>  #ifdef CONFIG_MEMCG_KMEM
>  /*
>   * This will be the memcg's index in each cache's ->memcg_params->memcg_caches.
> - * There are two main reasons for not using the css_id for this:
> - *  1) this works better in sparse environments, where we have a lot of memcgs,
> - *     but only a few kmem-limited. Or also, if we have, for instance, 200
> - *     memcgs, and none but the 200th is kmem-limited, we'd have to have a
> - *     200 entry array for that.
> - *
> - *  2) In order not to violate the cgroup API, we would like to do all memory
> - *     allocation in ->create(). At that point, we haven't yet allocated the
> - *     css_id. Having a separate index prevents us from messing with the cgroup
> - *     core for this
> + * The main reason for not using cgroup id for this:
> + *  this works better in sparse environments, where we have a lot of memcgs,
> + *  but only a few kmem-limited. Or also, if we have, for instance, 200
> + *  memcgs, and none but the 200th is kmem-limited, we'd have to have a
> + *  200 entry array for that.
>   *
>   * The current size of the caches array is stored in
>   * memcg_limited_groups_array_size.  It will double each time we have to
> @@ -622,14 +617,14 @@ int memcg_limited_groups_array_size;
>   * cgroups is a reasonable guess. In the future, it could be a parameter or
>   * tunable, but that is strictly not necessary.
>   *
> - * MAX_SIZE should be as large as the number of css_ids. Ideally, we could get
> + * MAX_SIZE should be as large as the number of cgrp_ids. Ideally, we could get
>   * this constant directly from cgroup, but it is understandable that this is
>   * better kept as an internal representation in cgroup.c. In any case, the
> - * css_id space is not getting any smaller, and we don't have to necessarily
> + * cgrp_id space is not getting any smaller, and we don't have to necessarily
>   * increase ours as well if it increases.
>   */
>  #define MEMCG_CACHES_MIN_SIZE 4
> -#define MEMCG_CACHES_MAX_SIZE 65535
> +#define MEMCG_CACHES_MAX_SIZE MEM_CGROUP_ID_MAX
>  
>  /*
>   * A lot of the calls to the cache allocation functions are expected to be
> @@ -6183,7 +6178,6 @@ static void __mem_cgroup_free(struct mem_cgroup *memcg)
>  	size_t size = memcg_size();
>  
>  	mem_cgroup_remove_from_trees(memcg);
> -	free_css_id(&mem_cgroup_subsys, &memcg->css);
>  
>  	for_each_node(node)
>  		free_mem_cgroup_per_zone_info(memcg, node);
> @@ -6980,7 +6974,6 @@ struct cgroup_subsys mem_cgroup_subsys = {
>  	.bind = mem_cgroup_bind,
>  	.base_cftypes = mem_cgroup_files,
>  	.early_init = 0,
> -	.use_id = 1,
>  };
>  
>  #ifdef CONFIG_MEMCG_SWAP
> -- 
> 1.8.0.2

-- 
Michal Hocko
SUSE Labs

--
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] 52+ messages in thread

* Re: [PATCH v2 8/8] cgroup: kill css_id
  2013-07-24 10:03   ` Li Zefan
@ 2013-07-24 14:31     ` Michal Hocko
  -1 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-24 14:31 UTC (permalink / raw)
  To: Li Zefan
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 18:03:36, Li Zefan wrote:
> The only user of css_id was memcg, and it has been convered to use
> cgroup->id, so kill css_id.
> 
> Signed-off-by: Li Zefan <lizefan@huwei.com>

Nice
Reviewed-by: Michal Hocko <mhocko@suse.cz>

> ---
>  include/linux/cgroup.h |  37 --------
>  kernel/cgroup.c        | 252 +------------------------------------------------
>  2 files changed, 1 insertion(+), 288 deletions(-)
> 
> diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
> index e8eb361..ec8c380 100644
> --- a/include/linux/cgroup.h
> +++ b/include/linux/cgroup.h
> @@ -599,11 +599,6 @@ struct cgroup_subsys {
>  	int subsys_id;
>  	int disabled;
>  	int early_init;
> -	/*
> -	 * True if this subsys uses ID. ID is not available before cgroup_init()
> -	 * (not available in early_init time.)
> -	 */
> -	bool use_id;
>  
>  	/*
>  	 * If %false, this subsystem is properly hierarchical -
> @@ -629,9 +624,6 @@ struct cgroup_subsys {
>  	 */
>  	struct cgroupfs_root *root;
>  	struct list_head sibling;
> -	/* used when use_id == true */
> -	struct idr idr;
> -	spinlock_t id_lock;
>  
>  	/* list of cftype_sets */
>  	struct list_head cftsets;
> @@ -858,35 +850,6 @@ int cgroup_scan_tasks(struct cgroup_scanner *scan);
>  int cgroup_attach_task_all(struct task_struct *from, struct task_struct *);
>  int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from);
>  
> -/*
> - * CSS ID is ID for cgroup_subsys_state structs under subsys. This only works
> - * if cgroup_subsys.use_id == true. It can be used for looking up and scanning.
> - * CSS ID is assigned at cgroup allocation (create) automatically
> - * and removed when subsys calls free_css_id() function. This is because
> - * the lifetime of cgroup_subsys_state is subsys's matter.
> - *
> - * Looking up and scanning function should be called under rcu_read_lock().
> - * Taking cgroup_mutex is not necessary for following calls.
> - * But the css returned by this routine can be "not populated yet" or "being
> - * destroyed". The caller should check css and cgroup's status.
> - */
> -
> -/*
> - * Typically Called at ->destroy(), or somewhere the subsys frees
> - * cgroup_subsys_state.
> - */
> -void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css);
> -
> -/* Find a cgroup_subsys_state which has given ID */
> -
> -struct cgroup_subsys_state *css_lookup(struct cgroup_subsys *ss, int id);
> -
> -/* Returns true if root is ancestor of cg */
> -bool css_is_ancestor(struct cgroup_subsys_state *cg,
> -		     const struct cgroup_subsys_state *root);
> -
> -/* Get id and depth of css */
> -unsigned short css_id(struct cgroup_subsys_state *css);
>  struct cgroup_subsys_state *cgroup_css_from_dir(struct file *f, int id);
>  
>  #else /* !CONFIG_CGROUPS */
> diff --git a/kernel/cgroup.c b/kernel/cgroup.c
> index 9b27775..4333cb7 100644
> --- a/kernel/cgroup.c
> +++ b/kernel/cgroup.c
> @@ -123,38 +123,6 @@ struct cfent {
>  };
>  
>  /*
> - * CSS ID -- ID per subsys's Cgroup Subsys State(CSS). used only when
> - * cgroup_subsys->use_id != 0.
> - */
> -#define CSS_ID_MAX	(65535)
> -struct css_id {
> -	/*
> -	 * The css to which this ID points. This pointer is set to valid value
> -	 * after cgroup is populated. If cgroup is removed, this will be NULL.
> -	 * This pointer is expected to be RCU-safe because destroy()
> -	 * is called after synchronize_rcu(). But for safe use, css_tryget()
> -	 * should be used for avoiding race.
> -	 */
> -	struct cgroup_subsys_state __rcu *css;
> -	/*
> -	 * ID of this css.
> -	 */
> -	unsigned short id;
> -	/*
> -	 * Depth in hierarchy which this ID belongs to.
> -	 */
> -	unsigned short depth;
> -	/*
> -	 * ID is freed by RCU. (and lookup routine is RCU safe.)
> -	 */
> -	struct rcu_head rcu_head;
> -	/*
> -	 * Hierarchy of CSS ID belongs to.
> -	 */
> -	unsigned short stack[0]; /* Array of Length (depth+1) */
> -};
> -
> -/*
>   * cgroup_event represents events which userspace want to receive.
>   */
>  struct cgroup_event {
> @@ -364,9 +332,6 @@ struct cgrp_cset_link {
>  static struct css_set init_css_set;
>  static struct cgrp_cset_link init_cgrp_cset_link;
>  
> -static int cgroup_init_idr(struct cgroup_subsys *ss,
> -			   struct cgroup_subsys_state *css);
> -
>  /* css_set_lock protects the list of css_set objects, and the
>   * chain of tasks off each css_set.  Nests outside task->alloc_lock
>   * due to cgroup_iter_start() */
> @@ -815,9 +780,6 @@ static struct backing_dev_info cgroup_backing_dev_info = {
>  	.capabilities	= BDI_CAP_NO_ACCT_AND_WRITEBACK,
>  };
>  
> -static int alloc_css_id(struct cgroup_subsys *ss,
> -			struct cgroup *parent, struct cgroup *child);
> -
>  static struct inode *cgroup_new_inode(umode_t mode, struct super_block *sb)
>  {
>  	struct inode *inode = new_inode(sb);
> @@ -4160,20 +4122,6 @@ static int cgroup_populate_dir(struct cgroup *cgrp, unsigned long subsys_mask)
>  		}
>  	}
>  
> -	/* This cgroup is ready now */
> -	for_each_root_subsys(cgrp->root, ss) {
> -		struct cgroup_subsys_state *css = cgrp->subsys[ss->subsys_id];
> -		struct css_id *id = rcu_dereference_protected(css->id, true);
> -
> -		/*
> -		 * Update id->css pointer and make this css visible from
> -		 * CSS ID functions. This pointer will be dereferened
> -		 * from RCU-read-side without locks.
> -		 */
> -		if (id)
> -			rcu_assign_pointer(id->css, css);
> -	}
> -
>  	return 0;
>  err:
>  	cgroup_clear_dir(cgrp, subsys_mask);
> @@ -4202,7 +4150,6 @@ static void init_cgroup_css(struct cgroup_subsys_state *css,
>  {
>  	css->cgroup = cgrp;
>  	css->flags = 0;
> -	css->id = NULL;
>  	if (cgrp == cgroup_dummy_top)
>  		css->flags |= CSS_ROOT;
>  	BUG_ON(cgrp->subsys[ss->subsys_id]);
> @@ -4331,12 +4278,6 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
>  			goto err_free_all;
>  
>  		init_cgroup_css(css, ss, cgrp);
> -
> -		if (ss->use_id) {
> -			err = alloc_css_id(ss, parent, cgrp);
> -			if (err)
> -				goto err_free_all;
> -		}
>  	}
>  
>  	/*
> @@ -4741,12 +4682,6 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
>  
>  	/* our new subsystem will be attached to the dummy hierarchy. */
>  	init_cgroup_css(css, ss, cgroup_dummy_top);
> -	/* init_idr must be after init_cgroup_css because it sets css->id. */
> -	if (ss->use_id) {
> -		ret = cgroup_init_idr(ss, css);
> -		if (ret)
> -			goto err_unload;
> -	}
>  
>  	/*
>  	 * Now we need to entangle the css into the existing css_sets. unlike
> @@ -4812,9 +4747,6 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss)
>  
>  	offline_css(ss, cgroup_dummy_top);
>  
> -	if (ss->use_id)
> -		idr_destroy(&ss->idr);
> -
>  	/* deassign the subsys_id */
>  	cgroup_subsys[ss->subsys_id] = NULL;
>  
> @@ -4841,8 +4773,7 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss)
>  	/*
>  	 * remove subsystem's css from the cgroup_dummy_top and free it -
>  	 * need to free before marking as null because ss->css_free needs
> -	 * the cgrp->subsys pointer to find their state. note that this
> -	 * also takes care of freeing the css_id.
> +	 * the cgrp->subsys pointer to find their state.
>  	 */
>  	ss->css_free(cgroup_dummy_top);
>  	cgroup_dummy_top->subsys[ss->subsys_id] = NULL;
> @@ -4913,8 +4844,6 @@ int __init cgroup_init(void)
>  	for_each_builtin_subsys(ss, i) {
>  		if (!ss->early_init)
>  			cgroup_init_subsys(ss);
> -		if (ss->use_id)
> -			cgroup_init_idr(ss, init_css_set.subsys[ss->subsys_id]);
>  	}
>  
>  	/* allocate id for the dummy hierarchy */
> @@ -5335,185 +5264,6 @@ static int __init cgroup_disable(char *str)
>  __setup("cgroup_disable=", cgroup_disable);
>  
>  /*
> - * Functons for CSS ID.
> - */
> -
> -/* to get ID other than 0, this should be called when !cgroup_is_dead() */
> -unsigned short css_id(struct cgroup_subsys_state *css)
> -{
> -	struct css_id *cssid;
> -
> -	/*
> -	 * This css_id() can return correct value when somone has refcnt
> -	 * on this or this is under rcu_read_lock(). Once css->id is allocated,
> -	 * it's unchanged until freed.
> -	 */
> -	cssid = rcu_dereference_raw(css->id);
> -
> -	if (cssid)
> -		return cssid->id;
> -	return 0;
> -}
> -EXPORT_SYMBOL_GPL(css_id);
> -
> -/**
> - *  css_is_ancestor - test "root" css is an ancestor of "child"
> - * @child: the css to be tested.
> - * @root: the css supporsed to be an ancestor of the child.
> - *
> - * Returns true if "root" is an ancestor of "child" in its hierarchy. Because
> - * this function reads css->id, the caller must hold rcu_read_lock().
> - * But, considering usual usage, the csses should be valid objects after test.
> - * Assuming that the caller will do some action to the child if this returns
> - * returns true, the caller must take "child";s reference count.
> - * If "child" is valid object and this returns true, "root" is valid, too.
> - */
> -
> -bool css_is_ancestor(struct cgroup_subsys_state *child,
> -		    const struct cgroup_subsys_state *root)
> -{
> -	struct css_id *child_id;
> -	struct css_id *root_id;
> -
> -	child_id  = rcu_dereference(child->id);
> -	if (!child_id)
> -		return false;
> -	root_id = rcu_dereference(root->id);
> -	if (!root_id)
> -		return false;
> -	if (child_id->depth < root_id->depth)
> -		return false;
> -	if (child_id->stack[root_id->depth] != root_id->id)
> -		return false;
> -	return true;
> -}
> -
> -void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css)
> -{
> -	struct css_id *id = rcu_dereference_protected(css->id, true);
> -
> -	/* When this is called before css_id initialization, id can be NULL */
> -	if (!id)
> -		return;
> -
> -	BUG_ON(!ss->use_id);
> -
> -	rcu_assign_pointer(id->css, NULL);
> -	rcu_assign_pointer(css->id, NULL);
> -	spin_lock(&ss->id_lock);
> -	idr_remove(&ss->idr, id->id);
> -	spin_unlock(&ss->id_lock);
> -	kfree_rcu(id, rcu_head);
> -}
> -EXPORT_SYMBOL_GPL(free_css_id);
> -
> -/*
> - * This is called by init or create(). Then, calls to this function are
> - * always serialized (By cgroup_mutex() at create()).
> - */
> -
> -static struct css_id *get_new_cssid(struct cgroup_subsys *ss, int depth)
> -{
> -	struct css_id *newid;
> -	int ret, size;
> -
> -	BUG_ON(!ss->use_id);
> -
> -	size = sizeof(*newid) + sizeof(unsigned short) * (depth + 1);
> -	newid = kzalloc(size, GFP_KERNEL);
> -	if (!newid)
> -		return ERR_PTR(-ENOMEM);
> -
> -	idr_preload(GFP_KERNEL);
> -	spin_lock(&ss->id_lock);
> -	/* Don't use 0. allocates an ID of 1-65535 */
> -	ret = idr_alloc(&ss->idr, newid, 1, CSS_ID_MAX + 1, GFP_NOWAIT);
> -	spin_unlock(&ss->id_lock);
> -	idr_preload_end();
> -
> -	/* Returns error when there are no free spaces for new ID.*/
> -	if (ret < 0)
> -		goto err_out;
> -
> -	newid->id = ret;
> -	newid->depth = depth;
> -	return newid;
> -err_out:
> -	kfree(newid);
> -	return ERR_PTR(ret);
> -
> -}
> -
> -static int __init_or_module cgroup_init_idr(struct cgroup_subsys *ss,
> -					    struct cgroup_subsys_state *rootcss)
> -{
> -	struct css_id *newid;
> -
> -	spin_lock_init(&ss->id_lock);
> -	idr_init(&ss->idr);
> -
> -	newid = get_new_cssid(ss, 0);
> -	if (IS_ERR(newid))
> -		return PTR_ERR(newid);
> -
> -	newid->stack[0] = newid->id;
> -	RCU_INIT_POINTER(newid->css, rootcss);
> -	RCU_INIT_POINTER(rootcss->id, newid);
> -	return 0;
> -}
> -
> -static int alloc_css_id(struct cgroup_subsys *ss, struct cgroup *parent,
> -			struct cgroup *child)
> -{
> -	int subsys_id, i, depth = 0;
> -	struct cgroup_subsys_state *parent_css, *child_css;
> -	struct css_id *child_id, *parent_id;
> -
> -	subsys_id = ss->subsys_id;
> -	parent_css = parent->subsys[subsys_id];
> -	child_css = child->subsys[subsys_id];
> -	parent_id = rcu_dereference_protected(parent_css->id, true);
> -	depth = parent_id->depth + 1;
> -
> -	child_id = get_new_cssid(ss, depth);
> -	if (IS_ERR(child_id))
> -		return PTR_ERR(child_id);
> -
> -	for (i = 0; i < depth; i++)
> -		child_id->stack[i] = parent_id->stack[i];
> -	child_id->stack[depth] = child_id->id;
> -	/*
> -	 * child_id->css pointer will be set after this cgroup is available
> -	 * see cgroup_populate_dir()
> -	 */
> -	rcu_assign_pointer(child_css->id, child_id);
> -
> -	return 0;
> -}
> -
> -/**
> - * css_lookup - lookup css by id
> - * @ss: cgroup subsys to be looked into.
> - * @id: the id
> - *
> - * Returns pointer to cgroup_subsys_state if there is valid one with id.
> - * NULL if not. Should be called under rcu_read_lock()
> - */
> -struct cgroup_subsys_state *css_lookup(struct cgroup_subsys *ss, int id)
> -{
> -	struct css_id *cssid = NULL;
> -
> -	BUG_ON(!ss->use_id);
> -	cssid = idr_find(&ss->idr, id);
> -
> -	if (unlikely(!cssid))
> -		return NULL;
> -
> -	return rcu_dereference(cssid->css);
> -}
> -EXPORT_SYMBOL_GPL(css_lookup);
> -
> -/*
>   * get corresponding css from file open on cgroupfs directory
>   */
>  struct cgroup_subsys_state *cgroup_css_from_dir(struct file *f, int id)
> -- 
> 1.8.0.2
> 
> --
> 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>

-- 
Michal Hocko
SUSE Labs

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

* Re: [PATCH v2 8/8] cgroup: kill css_id
@ 2013-07-24 14:31     ` Michal Hocko
  0 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-24 14:31 UTC (permalink / raw)
  To: Li Zefan
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 18:03:36, Li Zefan wrote:
> The only user of css_id was memcg, and it has been convered to use
> cgroup->id, so kill css_id.
> 
> Signed-off-by: Li Zefan <lizefan@huwei.com>

Nice
Reviewed-by: Michal Hocko <mhocko@suse.cz>

> ---
>  include/linux/cgroup.h |  37 --------
>  kernel/cgroup.c        | 252 +------------------------------------------------
>  2 files changed, 1 insertion(+), 288 deletions(-)
> 
> diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
> index e8eb361..ec8c380 100644
> --- a/include/linux/cgroup.h
> +++ b/include/linux/cgroup.h
> @@ -599,11 +599,6 @@ struct cgroup_subsys {
>  	int subsys_id;
>  	int disabled;
>  	int early_init;
> -	/*
> -	 * True if this subsys uses ID. ID is not available before cgroup_init()
> -	 * (not available in early_init time.)
> -	 */
> -	bool use_id;
>  
>  	/*
>  	 * If %false, this subsystem is properly hierarchical -
> @@ -629,9 +624,6 @@ struct cgroup_subsys {
>  	 */
>  	struct cgroupfs_root *root;
>  	struct list_head sibling;
> -	/* used when use_id == true */
> -	struct idr idr;
> -	spinlock_t id_lock;
>  
>  	/* list of cftype_sets */
>  	struct list_head cftsets;
> @@ -858,35 +850,6 @@ int cgroup_scan_tasks(struct cgroup_scanner *scan);
>  int cgroup_attach_task_all(struct task_struct *from, struct task_struct *);
>  int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from);
>  
> -/*
> - * CSS ID is ID for cgroup_subsys_state structs under subsys. This only works
> - * if cgroup_subsys.use_id == true. It can be used for looking up and scanning.
> - * CSS ID is assigned at cgroup allocation (create) automatically
> - * and removed when subsys calls free_css_id() function. This is because
> - * the lifetime of cgroup_subsys_state is subsys's matter.
> - *
> - * Looking up and scanning function should be called under rcu_read_lock().
> - * Taking cgroup_mutex is not necessary for following calls.
> - * But the css returned by this routine can be "not populated yet" or "being
> - * destroyed". The caller should check css and cgroup's status.
> - */
> -
> -/*
> - * Typically Called at ->destroy(), or somewhere the subsys frees
> - * cgroup_subsys_state.
> - */
> -void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css);
> -
> -/* Find a cgroup_subsys_state which has given ID */
> -
> -struct cgroup_subsys_state *css_lookup(struct cgroup_subsys *ss, int id);
> -
> -/* Returns true if root is ancestor of cg */
> -bool css_is_ancestor(struct cgroup_subsys_state *cg,
> -		     const struct cgroup_subsys_state *root);
> -
> -/* Get id and depth of css */
> -unsigned short css_id(struct cgroup_subsys_state *css);
>  struct cgroup_subsys_state *cgroup_css_from_dir(struct file *f, int id);
>  
>  #else /* !CONFIG_CGROUPS */
> diff --git a/kernel/cgroup.c b/kernel/cgroup.c
> index 9b27775..4333cb7 100644
> --- a/kernel/cgroup.c
> +++ b/kernel/cgroup.c
> @@ -123,38 +123,6 @@ struct cfent {
>  };
>  
>  /*
> - * CSS ID -- ID per subsys's Cgroup Subsys State(CSS). used only when
> - * cgroup_subsys->use_id != 0.
> - */
> -#define CSS_ID_MAX	(65535)
> -struct css_id {
> -	/*
> -	 * The css to which this ID points. This pointer is set to valid value
> -	 * after cgroup is populated. If cgroup is removed, this will be NULL.
> -	 * This pointer is expected to be RCU-safe because destroy()
> -	 * is called after synchronize_rcu(). But for safe use, css_tryget()
> -	 * should be used for avoiding race.
> -	 */
> -	struct cgroup_subsys_state __rcu *css;
> -	/*
> -	 * ID of this css.
> -	 */
> -	unsigned short id;
> -	/*
> -	 * Depth in hierarchy which this ID belongs to.
> -	 */
> -	unsigned short depth;
> -	/*
> -	 * ID is freed by RCU. (and lookup routine is RCU safe.)
> -	 */
> -	struct rcu_head rcu_head;
> -	/*
> -	 * Hierarchy of CSS ID belongs to.
> -	 */
> -	unsigned short stack[0]; /* Array of Length (depth+1) */
> -};
> -
> -/*
>   * cgroup_event represents events which userspace want to receive.
>   */
>  struct cgroup_event {
> @@ -364,9 +332,6 @@ struct cgrp_cset_link {
>  static struct css_set init_css_set;
>  static struct cgrp_cset_link init_cgrp_cset_link;
>  
> -static int cgroup_init_idr(struct cgroup_subsys *ss,
> -			   struct cgroup_subsys_state *css);
> -
>  /* css_set_lock protects the list of css_set objects, and the
>   * chain of tasks off each css_set.  Nests outside task->alloc_lock
>   * due to cgroup_iter_start() */
> @@ -815,9 +780,6 @@ static struct backing_dev_info cgroup_backing_dev_info = {
>  	.capabilities	= BDI_CAP_NO_ACCT_AND_WRITEBACK,
>  };
>  
> -static int alloc_css_id(struct cgroup_subsys *ss,
> -			struct cgroup *parent, struct cgroup *child);
> -
>  static struct inode *cgroup_new_inode(umode_t mode, struct super_block *sb)
>  {
>  	struct inode *inode = new_inode(sb);
> @@ -4160,20 +4122,6 @@ static int cgroup_populate_dir(struct cgroup *cgrp, unsigned long subsys_mask)
>  		}
>  	}
>  
> -	/* This cgroup is ready now */
> -	for_each_root_subsys(cgrp->root, ss) {
> -		struct cgroup_subsys_state *css = cgrp->subsys[ss->subsys_id];
> -		struct css_id *id = rcu_dereference_protected(css->id, true);
> -
> -		/*
> -		 * Update id->css pointer and make this css visible from
> -		 * CSS ID functions. This pointer will be dereferened
> -		 * from RCU-read-side without locks.
> -		 */
> -		if (id)
> -			rcu_assign_pointer(id->css, css);
> -	}
> -
>  	return 0;
>  err:
>  	cgroup_clear_dir(cgrp, subsys_mask);
> @@ -4202,7 +4150,6 @@ static void init_cgroup_css(struct cgroup_subsys_state *css,
>  {
>  	css->cgroup = cgrp;
>  	css->flags = 0;
> -	css->id = NULL;
>  	if (cgrp == cgroup_dummy_top)
>  		css->flags |= CSS_ROOT;
>  	BUG_ON(cgrp->subsys[ss->subsys_id]);
> @@ -4331,12 +4278,6 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
>  			goto err_free_all;
>  
>  		init_cgroup_css(css, ss, cgrp);
> -
> -		if (ss->use_id) {
> -			err = alloc_css_id(ss, parent, cgrp);
> -			if (err)
> -				goto err_free_all;
> -		}
>  	}
>  
>  	/*
> @@ -4741,12 +4682,6 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
>  
>  	/* our new subsystem will be attached to the dummy hierarchy. */
>  	init_cgroup_css(css, ss, cgroup_dummy_top);
> -	/* init_idr must be after init_cgroup_css because it sets css->id. */
> -	if (ss->use_id) {
> -		ret = cgroup_init_idr(ss, css);
> -		if (ret)
> -			goto err_unload;
> -	}
>  
>  	/*
>  	 * Now we need to entangle the css into the existing css_sets. unlike
> @@ -4812,9 +4747,6 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss)
>  
>  	offline_css(ss, cgroup_dummy_top);
>  
> -	if (ss->use_id)
> -		idr_destroy(&ss->idr);
> -
>  	/* deassign the subsys_id */
>  	cgroup_subsys[ss->subsys_id] = NULL;
>  
> @@ -4841,8 +4773,7 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss)
>  	/*
>  	 * remove subsystem's css from the cgroup_dummy_top and free it -
>  	 * need to free before marking as null because ss->css_free needs
> -	 * the cgrp->subsys pointer to find their state. note that this
> -	 * also takes care of freeing the css_id.
> +	 * the cgrp->subsys pointer to find their state.
>  	 */
>  	ss->css_free(cgroup_dummy_top);
>  	cgroup_dummy_top->subsys[ss->subsys_id] = NULL;
> @@ -4913,8 +4844,6 @@ int __init cgroup_init(void)
>  	for_each_builtin_subsys(ss, i) {
>  		if (!ss->early_init)
>  			cgroup_init_subsys(ss);
> -		if (ss->use_id)
> -			cgroup_init_idr(ss, init_css_set.subsys[ss->subsys_id]);
>  	}
>  
>  	/* allocate id for the dummy hierarchy */
> @@ -5335,185 +5264,6 @@ static int __init cgroup_disable(char *str)
>  __setup("cgroup_disable=", cgroup_disable);
>  
>  /*
> - * Functons for CSS ID.
> - */
> -
> -/* to get ID other than 0, this should be called when !cgroup_is_dead() */
> -unsigned short css_id(struct cgroup_subsys_state *css)
> -{
> -	struct css_id *cssid;
> -
> -	/*
> -	 * This css_id() can return correct value when somone has refcnt
> -	 * on this or this is under rcu_read_lock(). Once css->id is allocated,
> -	 * it's unchanged until freed.
> -	 */
> -	cssid = rcu_dereference_raw(css->id);
> -
> -	if (cssid)
> -		return cssid->id;
> -	return 0;
> -}
> -EXPORT_SYMBOL_GPL(css_id);
> -
> -/**
> - *  css_is_ancestor - test "root" css is an ancestor of "child"
> - * @child: the css to be tested.
> - * @root: the css supporsed to be an ancestor of the child.
> - *
> - * Returns true if "root" is an ancestor of "child" in its hierarchy. Because
> - * this function reads css->id, the caller must hold rcu_read_lock().
> - * But, considering usual usage, the csses should be valid objects after test.
> - * Assuming that the caller will do some action to the child if this returns
> - * returns true, the caller must take "child";s reference count.
> - * If "child" is valid object and this returns true, "root" is valid, too.
> - */
> -
> -bool css_is_ancestor(struct cgroup_subsys_state *child,
> -		    const struct cgroup_subsys_state *root)
> -{
> -	struct css_id *child_id;
> -	struct css_id *root_id;
> -
> -	child_id  = rcu_dereference(child->id);
> -	if (!child_id)
> -		return false;
> -	root_id = rcu_dereference(root->id);
> -	if (!root_id)
> -		return false;
> -	if (child_id->depth < root_id->depth)
> -		return false;
> -	if (child_id->stack[root_id->depth] != root_id->id)
> -		return false;
> -	return true;
> -}
> -
> -void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css)
> -{
> -	struct css_id *id = rcu_dereference_protected(css->id, true);
> -
> -	/* When this is called before css_id initialization, id can be NULL */
> -	if (!id)
> -		return;
> -
> -	BUG_ON(!ss->use_id);
> -
> -	rcu_assign_pointer(id->css, NULL);
> -	rcu_assign_pointer(css->id, NULL);
> -	spin_lock(&ss->id_lock);
> -	idr_remove(&ss->idr, id->id);
> -	spin_unlock(&ss->id_lock);
> -	kfree_rcu(id, rcu_head);
> -}
> -EXPORT_SYMBOL_GPL(free_css_id);
> -
> -/*
> - * This is called by init or create(). Then, calls to this function are
> - * always serialized (By cgroup_mutex() at create()).
> - */
> -
> -static struct css_id *get_new_cssid(struct cgroup_subsys *ss, int depth)
> -{
> -	struct css_id *newid;
> -	int ret, size;
> -
> -	BUG_ON(!ss->use_id);
> -
> -	size = sizeof(*newid) + sizeof(unsigned short) * (depth + 1);
> -	newid = kzalloc(size, GFP_KERNEL);
> -	if (!newid)
> -		return ERR_PTR(-ENOMEM);
> -
> -	idr_preload(GFP_KERNEL);
> -	spin_lock(&ss->id_lock);
> -	/* Don't use 0. allocates an ID of 1-65535 */
> -	ret = idr_alloc(&ss->idr, newid, 1, CSS_ID_MAX + 1, GFP_NOWAIT);
> -	spin_unlock(&ss->id_lock);
> -	idr_preload_end();
> -
> -	/* Returns error when there are no free spaces for new ID.*/
> -	if (ret < 0)
> -		goto err_out;
> -
> -	newid->id = ret;
> -	newid->depth = depth;
> -	return newid;
> -err_out:
> -	kfree(newid);
> -	return ERR_PTR(ret);
> -
> -}
> -
> -static int __init_or_module cgroup_init_idr(struct cgroup_subsys *ss,
> -					    struct cgroup_subsys_state *rootcss)
> -{
> -	struct css_id *newid;
> -
> -	spin_lock_init(&ss->id_lock);
> -	idr_init(&ss->idr);
> -
> -	newid = get_new_cssid(ss, 0);
> -	if (IS_ERR(newid))
> -		return PTR_ERR(newid);
> -
> -	newid->stack[0] = newid->id;
> -	RCU_INIT_POINTER(newid->css, rootcss);
> -	RCU_INIT_POINTER(rootcss->id, newid);
> -	return 0;
> -}
> -
> -static int alloc_css_id(struct cgroup_subsys *ss, struct cgroup *parent,
> -			struct cgroup *child)
> -{
> -	int subsys_id, i, depth = 0;
> -	struct cgroup_subsys_state *parent_css, *child_css;
> -	struct css_id *child_id, *parent_id;
> -
> -	subsys_id = ss->subsys_id;
> -	parent_css = parent->subsys[subsys_id];
> -	child_css = child->subsys[subsys_id];
> -	parent_id = rcu_dereference_protected(parent_css->id, true);
> -	depth = parent_id->depth + 1;
> -
> -	child_id = get_new_cssid(ss, depth);
> -	if (IS_ERR(child_id))
> -		return PTR_ERR(child_id);
> -
> -	for (i = 0; i < depth; i++)
> -		child_id->stack[i] = parent_id->stack[i];
> -	child_id->stack[depth] = child_id->id;
> -	/*
> -	 * child_id->css pointer will be set after this cgroup is available
> -	 * see cgroup_populate_dir()
> -	 */
> -	rcu_assign_pointer(child_css->id, child_id);
> -
> -	return 0;
> -}
> -
> -/**
> - * css_lookup - lookup css by id
> - * @ss: cgroup subsys to be looked into.
> - * @id: the id
> - *
> - * Returns pointer to cgroup_subsys_state if there is valid one with id.
> - * NULL if not. Should be called under rcu_read_lock()
> - */
> -struct cgroup_subsys_state *css_lookup(struct cgroup_subsys *ss, int id)
> -{
> -	struct css_id *cssid = NULL;
> -
> -	BUG_ON(!ss->use_id);
> -	cssid = idr_find(&ss->idr, id);
> -
> -	if (unlikely(!cssid))
> -		return NULL;
> -
> -	return rcu_dereference(cssid->css);
> -}
> -EXPORT_SYMBOL_GPL(css_lookup);
> -
> -/*
>   * get corresponding css from file open on cgroupfs directory
>   */
>  struct cgroup_subsys_state *cgroup_css_from_dir(struct file *f, int id)
> -- 
> 1.8.0.2
> 
> --
> 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>

-- 
Michal Hocko
SUSE Labs

--
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] 52+ messages in thread

* Re: [PATCH v2 0/8] memcg, cgroup: kill css_id
  2013-07-24  9:58 ` Li Zefan
@ 2013-07-24 14:32   ` Michal Hocko
  -1 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-24 14:32 UTC (permalink / raw)
  To: Li Zefan
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 17:58:44, Li Zefan wrote:
> This patchset converts memcg to use cgroup->id, and then we can remove
> cgroup css_id.
> 
> As we've removed memcg's own refcnt, converting memcg to use cgroup->id
> is very straight-forward.
> 
> The patchset is based on Tejun's cgroup tree.

Does it depend on any particular patches? I am asking because I would
need to cherry pick those and apply them into my -mm git tree before
these.

> Li Zefan (8):
>       cgroup: convert cgroup_ida to cgroup_idr
>       cgroup: document how cgroup IDs are assigned
>       cgroup: implement cgroup_from_id()
>       memcg: convert to use cgroup_is_descendant()
>       memcg: convert to use cgroup id
>       memcg: fail to create cgroup if the cgroup id is too big
>       memcg: stop using css id
>       cgroup: kill css_id
> --
>  include/linux/cgroup.h |  49 ++-------
>  kernel/cgroup.c        | 308 ++++++++-----------------------------------------------
>  mm/memcontrol.c        |  59 ++++++-----
>  3 files changed, 90 insertions(+), 326 deletions(-)

-- 
Michal Hocko
SUSE Labs

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

* Re: [PATCH v2 0/8] memcg, cgroup: kill css_id
@ 2013-07-24 14:32   ` Michal Hocko
  0 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-24 14:32 UTC (permalink / raw)
  To: Li Zefan
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 17:58:44, Li Zefan wrote:
> This patchset converts memcg to use cgroup->id, and then we can remove
> cgroup css_id.
> 
> As we've removed memcg's own refcnt, converting memcg to use cgroup->id
> is very straight-forward.
> 
> The patchset is based on Tejun's cgroup tree.

Does it depend on any particular patches? I am asking because I would
need to cherry pick those and apply them into my -mm git tree before
these.

> Li Zefan (8):
>       cgroup: convert cgroup_ida to cgroup_idr
>       cgroup: document how cgroup IDs are assigned
>       cgroup: implement cgroup_from_id()
>       memcg: convert to use cgroup_is_descendant()
>       memcg: convert to use cgroup id
>       memcg: fail to create cgroup if the cgroup id is too big
>       memcg: stop using css id
>       cgroup: kill css_id
> --
>  include/linux/cgroup.h |  49 ++-------
>  kernel/cgroup.c        | 308 ++++++++-----------------------------------------------
>  mm/memcontrol.c        |  59 ++++++-----
>  3 files changed, 90 insertions(+), 326 deletions(-)

-- 
Michal Hocko
SUSE Labs

--
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] 52+ messages in thread

* Re: [PATCH v2 0/8] memcg, cgroup: kill css_id
  2013-07-24 14:32   ` Michal Hocko
@ 2013-07-24 16:14     ` Tejun Heo
  -1 siblings, 0 replies; 52+ messages in thread
From: Tejun Heo @ 2013-07-24 16:14 UTC (permalink / raw)
  To: Michal Hocko
  Cc: Li Zefan, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed, Jul 24, 2013 at 04:32:14PM +0200, Michal Hocko wrote:
> On Wed 24-07-13 17:58:44, Li Zefan wrote:
> > This patchset converts memcg to use cgroup->id, and then we can remove
> > cgroup css_id.
> > 
> > As we've removed memcg's own refcnt, converting memcg to use cgroup->id
> > is very straight-forward.
> > 
> > The patchset is based on Tejun's cgroup tree.
> 
> Does it depend on any particular patches? I am asking because I would
> need to cherry pick those and apply them into my -mm git tree before
> these.

I'll set up a branch with the prep cgroup patches bsaed on top of
v3.10 which you can pull into your tree (let's please not cherry-pick)
and the memcg part and actual css_id removal can be carried through
-mm.

Thanks.

-- 
tejun

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

* Re: [PATCH v2 0/8] memcg, cgroup: kill css_id
@ 2013-07-24 16:14     ` Tejun Heo
  0 siblings, 0 replies; 52+ messages in thread
From: Tejun Heo @ 2013-07-24 16:14 UTC (permalink / raw)
  To: Michal Hocko
  Cc: Li Zefan, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed, Jul 24, 2013 at 04:32:14PM +0200, Michal Hocko wrote:
> On Wed 24-07-13 17:58:44, Li Zefan wrote:
> > This patchset converts memcg to use cgroup->id, and then we can remove
> > cgroup css_id.
> > 
> > As we've removed memcg's own refcnt, converting memcg to use cgroup->id
> > is very straight-forward.
> > 
> > The patchset is based on Tejun's cgroup tree.
> 
> Does it depend on any particular patches? I am asking because I would
> need to cherry pick those and apply them into my -mm git tree before
> these.

I'll set up a branch with the prep cgroup patches bsaed on top of
v3.10 which you can pull into your tree (let's please not cherry-pick)
and the memcg part and actual css_id removal can be carried through
-mm.

Thanks.

-- 
tejun

--
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] 52+ messages in thread

* Re: [PATCH v2 0/8] memcg, cgroup: kill css_id
  2013-07-24 14:32   ` Michal Hocko
@ 2013-07-25  0:59     ` Li Zefan
  -1 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-25  0:59 UTC (permalink / raw)
  To: Michal Hocko
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On 2013/7/24 22:32, Michal Hocko wrote:
> On Wed 24-07-13 17:58:44, Li Zefan wrote:
>> This patchset converts memcg to use cgroup->id, and then we can remove
>> cgroup css_id.
>>
>> As we've removed memcg's own refcnt, converting memcg to use cgroup->id
>> is very straight-forward.
>>
>> The patchset is based on Tejun's cgroup tree.
> 
> Does it depend on any particular patches? I am asking because I would
> need to cherry pick those and apply them into my -mm git tree before
> these.
> 

Nope, but you should see a few but small conflicts if you apply them to
your git tree.


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

* Re: [PATCH v2 0/8] memcg, cgroup: kill css_id
@ 2013-07-25  0:59     ` Li Zefan
  0 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-25  0:59 UTC (permalink / raw)
  To: Michal Hocko
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On 2013/7/24 22:32, Michal Hocko wrote:
> On Wed 24-07-13 17:58:44, Li Zefan wrote:
>> This patchset converts memcg to use cgroup->id, and then we can remove
>> cgroup css_id.
>>
>> As we've removed memcg's own refcnt, converting memcg to use cgroup->id
>> is very straight-forward.
>>
>> The patchset is based on Tejun's cgroup tree.
> 
> Does it depend on any particular patches? I am asking because I would
> need to cherry pick those and apply them into my -mm git tree before
> these.
> 

Nope, but you should see a few but small conflicts if you apply them to
your git tree.

--
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] 52+ messages in thread

* Re: [PATCH v2 1/8] cgroup: convert cgroup_ida to cgroup_idr
  2013-07-24 14:07     ` Michal Hocko
@ 2013-07-25  1:08       ` Li Zefan
  -1 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-25  1:08 UTC (permalink / raw)
  To: Michal Hocko
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On 2013/7/24 22:07, Michal Hocko wrote:
> On Wed 24-07-13 17:59:12, Li Zefan wrote:
>> This enables us to lookup a cgroup by its id.
>>
>> Signed-off-by: Li Zefan <lizefan@huawei.com>
> 
> Reviewed-by: Michal Hocko <mhocko@suse.cz>

Thanks for the review! I'll wait a couple of days for other comments,
and then update the patchset.


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

* Re: [PATCH v2 1/8] cgroup: convert cgroup_ida to cgroup_idr
@ 2013-07-25  1:08       ` Li Zefan
  0 siblings, 0 replies; 52+ messages in thread
From: Li Zefan @ 2013-07-25  1:08 UTC (permalink / raw)
  To: Michal Hocko
  Cc: Tejun Heo, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On 2013/7/24 22:07, Michal Hocko wrote:
> On Wed 24-07-13 17:59:12, Li Zefan wrote:
>> This enables us to lookup a cgroup by its id.
>>
>> Signed-off-by: Li Zefan <lizefan@huawei.com>
> 
> Reviewed-by: Michal Hocko <mhocko@suse.cz>

Thanks for the review! I'll wait a couple of days for other comments,
and then update the patchset.

--
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] 52+ messages in thread

* Re: [PATCH v2 0/8] memcg, cgroup: kill css_id
  2013-07-24 16:14     ` Tejun Heo
  (?)
@ 2013-07-25  7:40       ` Michal Hocko
  -1 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-25  7:40 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Li Zefan, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 12:14:07, Tejun Heo wrote:
> On Wed, Jul 24, 2013 at 04:32:14PM +0200, Michal Hocko wrote:
> > On Wed 24-07-13 17:58:44, Li Zefan wrote:
> > > This patchset converts memcg to use cgroup->id, and then we can remove
> > > cgroup css_id.
> > > 
> > > As we've removed memcg's own refcnt, converting memcg to use cgroup->id
> > > is very straight-forward.
> > > 
> > > The patchset is based on Tejun's cgroup tree.
> > 
> > Does it depend on any particular patches? I am asking because I would
> > need to cherry pick those and apply them into my -mm git tree before
> > these.
> 
> I'll set up a branch with the prep cgroup patches bsaed on top of
> v3.10 which you can pull into your tree (let's please not cherry-pick)
> and the memcg part and actual css_id removal can be carried through
> -mm.

Great. Thanks a lot Tejun!

> 
> Thanks.
> 
> -- 
> tejun

-- 
Michal Hocko
SUSE Labs

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

* Re: [PATCH v2 0/8] memcg, cgroup: kill css_id
@ 2013-07-25  7:40       ` Michal Hocko
  0 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-25  7:40 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Li Zefan, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm

On Wed 24-07-13 12:14:07, Tejun Heo wrote:
> On Wed, Jul 24, 2013 at 04:32:14PM +0200, Michal Hocko wrote:
> > On Wed 24-07-13 17:58:44, Li Zefan wrote:
> > > This patchset converts memcg to use cgroup->id, and then we can remove
> > > cgroup css_id.
> > > 
> > > As we've removed memcg's own refcnt, converting memcg to use cgroup->id
> > > is very straight-forward.
> > > 
> > > The patchset is based on Tejun's cgroup tree.
> > 
> > Does it depend on any particular patches? I am asking because I would
> > need to cherry pick those and apply them into my -mm git tree before
> > these.
> 
> I'll set up a branch with the prep cgroup patches bsaed on top of
> v3.10 which you can pull into your tree (let's please not cherry-pick)
> and the memcg part and actual css_id removal can be carried through
> -mm.

Great. Thanks a lot Tejun!

> 
> Thanks.
> 
> -- 
> tejun

-- 
Michal Hocko
SUSE Labs

--
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] 52+ messages in thread

* Re: [PATCH v2 0/8] memcg, cgroup: kill css_id
@ 2013-07-25  7:40       ` Michal Hocko
  0 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-25  7:40 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Li Zefan, Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki,
	Johannes Weiner, LKML, Cgroups, linux-mm-Bw31MaZKKs3YtjvyW6yDsg

On Wed 24-07-13 12:14:07, Tejun Heo wrote:
> On Wed, Jul 24, 2013 at 04:32:14PM +0200, Michal Hocko wrote:
> > On Wed 24-07-13 17:58:44, Li Zefan wrote:
> > > This patchset converts memcg to use cgroup->id, and then we can remove
> > > cgroup css_id.
> > > 
> > > As we've removed memcg's own refcnt, converting memcg to use cgroup->id
> > > is very straight-forward.
> > > 
> > > The patchset is based on Tejun's cgroup tree.
> > 
> > Does it depend on any particular patches? I am asking because I would
> > need to cherry pick those and apply them into my -mm git tree before
> > these.
> 
> I'll set up a branch with the prep cgroup patches bsaed on top of
> v3.10 which you can pull into your tree (let's please not cherry-pick)
> and the memcg part and actual css_id removal can be carried through
> -mm.

Great. Thanks a lot Tejun!

> 
> Thanks.
> 
> -- 
> tejun

-- 
Michal Hocko
SUSE Labs

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

* Re: [PATCH v2 0/8] memcg, cgroup: kill css_id
  2013-07-25  0:59     ` Li Zefan
  (?)
@ 2013-07-25  7:41       ` Michal Hocko
  -1 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-25  7:41 UTC (permalink / raw)
  To: Tejun Heo, Li Zefan
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Johannes Weiner,
	LKML, Cgroups, linux-mm

On Thu 25-07-13 08:59:15, Li Zefan wrote:
> On 2013/7/24 22:32, Michal Hocko wrote:
> > On Wed 24-07-13 17:58:44, Li Zefan wrote:
> >> This patchset converts memcg to use cgroup->id, and then we can remove
> >> cgroup css_id.
> >>
> >> As we've removed memcg's own refcnt, converting memcg to use cgroup->id
> >> is very straight-forward.
> >>
> >> The patchset is based on Tejun's cgroup tree.
> > 
> > Does it depend on any particular patches? I am asking because I would
> > need to cherry pick those and apply them into my -mm git tree before
> > these.
> > 
> 
> Nope, but you should see a few but small conflicts if you apply them to
> your git tree.
 
Ohh, then there is no problem at all and Tejun, doesn't have to prepare
any special branch.

Thanks!
-- 
Michal Hocko
SUSE Labs

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

* Re: [PATCH v2 0/8] memcg, cgroup: kill css_id
@ 2013-07-25  7:41       ` Michal Hocko
  0 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-25  7:41 UTC (permalink / raw)
  To: Tejun Heo, Li Zefan
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Johannes Weiner,
	LKML, Cgroups, linux-mm

On Thu 25-07-13 08:59:15, Li Zefan wrote:
> On 2013/7/24 22:32, Michal Hocko wrote:
> > On Wed 24-07-13 17:58:44, Li Zefan wrote:
> >> This patchset converts memcg to use cgroup->id, and then we can remove
> >> cgroup css_id.
> >>
> >> As we've removed memcg's own refcnt, converting memcg to use cgroup->id
> >> is very straight-forward.
> >>
> >> The patchset is based on Tejun's cgroup tree.
> > 
> > Does it depend on any particular patches? I am asking because I would
> > need to cherry pick those and apply them into my -mm git tree before
> > these.
> > 
> 
> Nope, but you should see a few but small conflicts if you apply them to
> your git tree.
 
Ohh, then there is no problem at all and Tejun, doesn't have to prepare
any special branch.

Thanks!
-- 
Michal Hocko
SUSE Labs

--
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] 52+ messages in thread

* Re: [PATCH v2 0/8] memcg, cgroup: kill css_id
@ 2013-07-25  7:41       ` Michal Hocko
  0 siblings, 0 replies; 52+ messages in thread
From: Michal Hocko @ 2013-07-25  7:41 UTC (permalink / raw)
  To: Tejun Heo, Li Zefan
  Cc: Andrew Morton, Glauber Costa, KAMEZAWA Hiroyuki, Johannes Weiner,
	LKML, Cgroups, linux-mm-Bw31MaZKKs3YtjvyW6yDsg

On Thu 25-07-13 08:59:15, Li Zefan wrote:
> On 2013/7/24 22:32, Michal Hocko wrote:
> > On Wed 24-07-13 17:58:44, Li Zefan wrote:
> >> This patchset converts memcg to use cgroup->id, and then we can remove
> >> cgroup css_id.
> >>
> >> As we've removed memcg's own refcnt, converting memcg to use cgroup->id
> >> is very straight-forward.
> >>
> >> The patchset is based on Tejun's cgroup tree.
> > 
> > Does it depend on any particular patches? I am asking because I would
> > need to cherry pick those and apply them into my -mm git tree before
> > these.
> > 
> 
> Nope, but you should see a few but small conflicts if you apply them to
> your git tree.
 
Ohh, then there is no problem at all and Tejun, doesn't have to prepare
any special branch.

Thanks!
-- 
Michal Hocko
SUSE Labs

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

end of thread, other threads:[~2013-07-25  7:41 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-24  9:58 [PATCH v2 0/8] memcg, cgroup: kill css_id Li Zefan
2013-07-24  9:58 ` Li Zefan
2013-07-24  9:59 ` [PATCH v2 1/8] cgroup: convert cgroup_ida to cgroup_idr Li Zefan
2013-07-24  9:59   ` Li Zefan
2013-07-24  9:59   ` Li Zefan
2013-07-24 14:07   ` Michal Hocko
2013-07-24 14:07     ` Michal Hocko
2013-07-25  1:08     ` Li Zefan
2013-07-25  1:08       ` Li Zefan
2013-07-24  9:59 ` [PATCH v2 2/8] cgroup: document how cgroup IDs are assigned Li Zefan
2013-07-24  9:59   ` Li Zefan
2013-07-24  9:59   ` Li Zefan
2013-07-24 14:07   ` Michal Hocko
2013-07-24 14:07     ` Michal Hocko
2013-07-24 10:00 ` [PATCH v2 3/8] cgroup: implement cgroup_from_id() Li Zefan
2013-07-24 10:00   ` Li Zefan
2013-07-24 14:10   ` Michal Hocko
2013-07-24 14:10     ` Michal Hocko
2013-07-24 10:01 ` [PATCH v2 4/8] memcg: convert to use cgroup_is_descendant() Li Zefan
2013-07-24 10:01   ` Li Zefan
2013-07-24 10:01   ` Li Zefan
2013-07-24 14:20   ` Michal Hocko
2013-07-24 14:20     ` Michal Hocko
2013-07-24 10:01 ` [PATCH v2 5/8] memcg: convert to use cgroup id Li Zefan
2013-07-24 10:01   ` Li Zefan
2013-07-24 14:25   ` Michal Hocko
2013-07-24 14:25     ` Michal Hocko
2013-07-24 10:02 ` [PATCH v2 6/8] memcg: fail to create cgroup if the cgroup id is too big Li Zefan
2013-07-24 10:02   ` Li Zefan
2013-07-24 14:27   ` Michal Hocko
2013-07-24 14:27     ` Michal Hocko
2013-07-24 10:03 ` [PATCH v2 7/8] memcg: stop using css id Li Zefan
2013-07-24 10:03   ` Li Zefan
2013-07-24 10:03   ` Li Zefan
2013-07-24 14:30   ` Michal Hocko
2013-07-24 14:30     ` Michal Hocko
2013-07-24 10:03 ` [PATCH v2 8/8] cgroup: kill css_id Li Zefan
2013-07-24 10:03   ` Li Zefan
2013-07-24 14:31   ` Michal Hocko
2013-07-24 14:31     ` Michal Hocko
2013-07-24 14:32 ` [PATCH v2 0/8] memcg, " Michal Hocko
2013-07-24 14:32   ` Michal Hocko
2013-07-24 16:14   ` Tejun Heo
2013-07-24 16:14     ` Tejun Heo
2013-07-25  7:40     ` Michal Hocko
2013-07-25  7:40       ` Michal Hocko
2013-07-25  7:40       ` Michal Hocko
2013-07-25  0:59   ` Li Zefan
2013-07-25  0:59     ` Li Zefan
2013-07-25  7:41     ` Michal Hocko
2013-07-25  7:41       ` Michal Hocko
2013-07-25  7:41       ` Michal Hocko

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.