Skip to content

Commit

Permalink
memcg: don't need to free memcg via RCU or workqueue
Browse files Browse the repository at this point in the history
Now memcg has the same life cycle with its corresponding cgroup, and a
cgroup is freed via RCU and then mem_cgroup_css_free() will be called in
a work function, so we can simply call __mem_cgroup_free() in
mem_cgroup_css_free().

This actually reverts commit 59927fb ("memcg: free mem_cgroup by RCU
to fix oops").

Signed-off-by: Li Zefan <[email protected]>
Cc: Hugh Dickins <[email protected]>
Acked-by: Michal Hocko <[email protected]>
Acked-by: KAMEZAWA Hiroyuki <[email protected]>
Cc: Tejun Heo <[email protected]>
Cc: Glauber Costa <[email protected]>
Cc: Johannes Weiner <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
lizf-os authored and torvalds committed Jul 9, 2013
1 parent e0743e6 commit 465939a
Showing 1 changed file with 5 additions and 46 deletions.
51 changes: 5 additions & 46 deletions mm/memcontrol.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,28 +263,10 @@ struct mem_cgroup {
/* vmpressure notifications */
struct vmpressure vmpressure;

union {
/*
* the counter to account for mem+swap usage.
*/
struct res_counter memsw;

/*
* rcu_freeing is used only when freeing struct mem_cgroup,
* so put it into a union to avoid wasting more memory.
* It must be disjoint from the css field. It could be
* in a union with the res field, but res plays a much
* larger part in mem_cgroup life than memsw, and might
* be of interest, even at time of free, when debugging.
* So share rcu_head with the less interesting memsw.
*/
struct rcu_head rcu_freeing;
/*
* We also need some space for a worker in deferred freeing.
* By the time we call it, rcu_freeing is no longer in use.
*/
struct work_struct work_freeing;
};
/*
* the counter to account for mem+swap usage.
*/
struct res_counter memsw;

/*
* the counter to account for kernel memory usage.
Expand Down Expand Up @@ -6211,29 +6193,6 @@ static void __mem_cgroup_free(struct mem_cgroup *memcg)
vfree(memcg);
}


/*
* Helpers for freeing a kmalloc()ed/vzalloc()ed mem_cgroup by RCU,
* but in process context. The work_freeing structure is overlaid
* on the rcu_freeing structure, which itself is overlaid on memsw.
*/
static void free_work(struct work_struct *work)
{
struct mem_cgroup *memcg;

memcg = container_of(work, struct mem_cgroup, work_freeing);
__mem_cgroup_free(memcg);
}

static void free_rcu(struct rcu_head *rcu_head)
{
struct mem_cgroup *memcg;

memcg = container_of(rcu_head, struct mem_cgroup, rcu_freeing);
INIT_WORK(&memcg->work_freeing, free_work);
schedule_work(&memcg->work_freeing);
}

/*
* Returns the parent mem_cgroup in memcgroup hierarchy with hierarchy enabled.
*/
Expand Down Expand Up @@ -6383,7 +6342,7 @@ static void mem_cgroup_css_free(struct cgroup *cont)
struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);

memcg_destroy_kmem(memcg);
call_rcu(&memcg->rcu_freeing, free_rcu);
__mem_cgroup_free(memcg);
}

#ifdef CONFIG_MMU
Expand Down

0 comments on commit 465939a

Please sign in to comment.