* [PATCH v2 0/8] memcg, cgroup: kill css_id
@ 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
` (8 more replies)
0 siblings, 9 replies; 23+ 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] 23+ messages in thread
* [PATCH v2 1/8] cgroup: convert cgroup_ida to cgroup_idr
2013-07-24 9:58 [PATCH v2 0/8] memcg, cgroup: kill css_id Li Zefan
@ 2013-07-24 9:59 ` Li Zefan
2013-07-24 14:07 ` Michal Hocko
2013-07-24 9:59 ` [PATCH v2 2/8] cgroup: document how cgroup IDs are assigned Li Zefan
` (7 subsequent siblings)
8 siblings, 1 reply; 23+ 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] 23+ messages in thread
* [PATCH v2 2/8] cgroup: document how cgroup IDs are assigned
2013-07-24 9:58 [PATCH v2 0/8] memcg, cgroup: kill css_id 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 14:07 ` Michal Hocko
2013-07-24 10:00 ` [PATCH v2 3/8] cgroup: implement cgroup_from_id() Li Zefan
` (6 subsequent siblings)
8 siblings, 1 reply; 23+ 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] 23+ messages in thread
* [PATCH v2 3/8] cgroup: implement cgroup_from_id()
2013-07-24 9:58 [PATCH v2 0/8] memcg, cgroup: kill css_id 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 ` [PATCH v2 2/8] cgroup: document how cgroup IDs are assigned Li Zefan
@ 2013-07-24 10:00 ` Li Zefan
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
` (5 subsequent siblings)
8 siblings, 1 reply; 23+ 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] 23+ messages in thread
* [PATCH v2 4/8] memcg: convert to use cgroup_is_descendant()
2013-07-24 9:58 [PATCH v2 0/8] memcg, cgroup: kill css_id Li Zefan
` (2 preceding siblings ...)
2013-07-24 10:00 ` [PATCH v2 3/8] cgroup: implement cgroup_from_id() Li Zefan
@ 2013-07-24 10:01 ` Li Zefan
2013-07-24 14:20 ` Michal Hocko
2013-07-24 10:01 ` [PATCH v2 5/8] memcg: convert to use cgroup id Li Zefan
` (4 subsequent siblings)
8 siblings, 1 reply; 23+ 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] 23+ messages in thread
* [PATCH v2 5/8] memcg: convert to use cgroup id
2013-07-24 9:58 [PATCH v2 0/8] memcg, cgroup: kill css_id Li Zefan
` (3 preceding siblings ...)
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 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
` (3 subsequent siblings)
8 siblings, 1 reply; 23+ 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] 23+ messages in thread
* [PATCH v2 6/8] memcg: fail to create cgroup if the cgroup id is too big
2013-07-24 9:58 [PATCH v2 0/8] memcg, cgroup: kill css_id Li Zefan
` (4 preceding siblings ...)
2013-07-24 10:01 ` [PATCH v2 5/8] memcg: convert to use cgroup id Li Zefan
@ 2013-07-24 10:02 ` Li Zefan
2013-07-24 14:27 ` Michal Hocko
2013-07-24 10:03 ` [PATCH v2 7/8] memcg: stop using css id Li Zefan
` (2 subsequent siblings)
8 siblings, 1 reply; 23+ 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] 23+ messages in thread
* [PATCH v2 7/8] memcg: stop using css id
2013-07-24 9:58 [PATCH v2 0/8] memcg, cgroup: kill css_id Li Zefan
` (5 preceding siblings ...)
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:03 ` Li Zefan
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 14:32 ` [PATCH v2 0/8] memcg, " Michal Hocko
8 siblings, 1 reply; 23+ 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] 23+ messages in thread
* [PATCH v2 8/8] cgroup: kill css_id
2013-07-24 9:58 [PATCH v2 0/8] memcg, cgroup: kill css_id Li Zefan
` (6 preceding siblings ...)
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 14:31 ` Michal Hocko
2013-07-24 14:32 ` [PATCH v2 0/8] memcg, " Michal Hocko
8 siblings, 1 reply; 23+ 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] 23+ messages in thread
* Re: [PATCH v2 1/8] cgroup: convert cgroup_ida to cgroup_idr
2013-07-24 9:59 ` [PATCH v2 1/8] cgroup: convert cgroup_ida to cgroup_idr Li Zefan
@ 2013-07-24 14:07 ` Michal Hocko
2013-07-25 1:08 ` Li Zefan
0 siblings, 1 reply; 23+ 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] 23+ messages in thread
* Re: [PATCH v2 2/8] cgroup: document how cgroup IDs are assigned
2013-07-24 9:59 ` [PATCH v2 2/8] cgroup: document how cgroup IDs are assigned Li Zefan
@ 2013-07-24 14:07 ` Michal Hocko
0 siblings, 0 replies; 23+ 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] 23+ messages in thread
* Re: [PATCH v2 3/8] cgroup: implement cgroup_from_id()
2013-07-24 10:00 ` [PATCH v2 3/8] cgroup: implement cgroup_from_id() Li Zefan
@ 2013-07-24 14:10 ` Michal Hocko
0 siblings, 0 replies; 23+ 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] 23+ messages in thread
* Re: [PATCH v2 4/8] memcg: convert to use cgroup_is_descendant()
2013-07-24 10:01 ` [PATCH v2 4/8] memcg: convert to use cgroup_is_descendant() Li Zefan
@ 2013-07-24 14:20 ` Michal Hocko
0 siblings, 0 replies; 23+ 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] 23+ messages in thread
* Re: [PATCH v2 5/8] memcg: convert to use cgroup id
2013-07-24 10:01 ` [PATCH v2 5/8] memcg: convert to use cgroup id Li Zefan
@ 2013-07-24 14:25 ` Michal Hocko
0 siblings, 0 replies; 23+ 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] 23+ 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 ` [PATCH v2 6/8] memcg: fail to create cgroup if the cgroup id is too big Li Zefan
@ 2013-07-24 14:27 ` Michal Hocko
0 siblings, 0 replies; 23+ 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] 23+ messages in thread
* Re: [PATCH v2 7/8] memcg: stop using css id
2013-07-24 10:03 ` [PATCH v2 7/8] memcg: stop using css id Li Zefan
@ 2013-07-24 14:30 ` Michal Hocko
0 siblings, 0 replies; 23+ 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] 23+ messages in thread
* Re: [PATCH v2 8/8] cgroup: kill css_id
2013-07-24 10:03 ` [PATCH v2 8/8] cgroup: kill css_id Li Zefan
@ 2013-07-24 14:31 ` Michal Hocko
0 siblings, 0 replies; 23+ 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] 23+ messages in thread
* Re: [PATCH v2 0/8] memcg, cgroup: kill css_id
2013-07-24 9:58 [PATCH v2 0/8] memcg, cgroup: kill css_id Li Zefan
` (7 preceding siblings ...)
2013-07-24 10:03 ` [PATCH v2 8/8] cgroup: kill css_id Li Zefan
@ 2013-07-24 14:32 ` Michal Hocko
2013-07-24 16:14 ` Tejun Heo
2013-07-25 0:59 ` Li Zefan
8 siblings, 2 replies; 23+ 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] 23+ messages in thread
* Re: [PATCH v2 0/8] memcg, cgroup: kill css_id
2013-07-24 14:32 ` [PATCH v2 0/8] memcg, " Michal Hocko
@ 2013-07-24 16:14 ` Tejun Heo
2013-07-25 7:40 ` Michal Hocko
2013-07-25 0:59 ` Li Zefan
1 sibling, 1 reply; 23+ 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] 23+ messages in thread
* Re: [PATCH v2 0/8] memcg, cgroup: kill css_id
2013-07-24 14:32 ` [PATCH v2 0/8] memcg, " Michal Hocko
2013-07-24 16:14 ` Tejun Heo
@ 2013-07-25 0:59 ` Li Zefan
2013-07-25 7:41 ` Michal Hocko
1 sibling, 1 reply; 23+ 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] 23+ 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
0 siblings, 0 replies; 23+ 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] 23+ 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
0 siblings, 0 replies; 23+ 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] 23+ 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
0 siblings, 0 replies; 23+ 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] 23+ messages in thread
end of thread, other threads:[~2013-07-25 7:41 UTC | newest]
Thread overview: 23+ 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:59 ` [PATCH v2 1/8] cgroup: convert cgroup_ida to cgroup_idr Li Zefan
2013-07-24 14:07 ` Michal Hocko
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 14:07 ` Michal Hocko
2013-07-24 10:00 ` [PATCH v2 3/8] cgroup: implement cgroup_from_id() Li Zefan
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 14:20 ` Michal Hocko
2013-07-24 10:01 ` [PATCH v2 5/8] memcg: convert to use cgroup id Li Zefan
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 14:27 ` Michal Hocko
2013-07-24 10:03 ` [PATCH v2 7/8] memcg: stop using css id Li Zefan
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 14:31 ` Michal Hocko
2013-07-24 14:32 ` [PATCH v2 0/8] memcg, " Michal Hocko
2013-07-24 16:14 ` Tejun Heo
2013-07-25 7:40 ` Michal Hocko
2013-07-25 0:59 ` Li Zefan
2013-07-25 7:41 ` Michal Hocko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).