Skip to content

Commit

Permalink
cgroups: remove events before destroying subsystem state objects
Browse files Browse the repository at this point in the history
Events should be removed after rmdir of cgroup directory, but before
destroying subsystem state objects.  Let's take reference to cgroup
directory dentry to do that.

Signed-off-by: Kirill A. Shutemov <[email protected]>
Acked-by: KAMEZAWA Hiroyuki <[email protected]>
Cc: Paul Menage <[email protected]>
Acked-by: Li Zefan <[email protected]>
Cc: Balbir Singh <[email protected]>
Cc: Pavel Emelyanov <[email protected]>
Cc: Dan Malek <[email protected]>
Cc: Daisuke Nishimura <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
kiryl authored and torvalds committed Mar 12, 2010
1 parent 4ab7868 commit a0a4db5
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 12 deletions.
3 changes: 0 additions & 3 deletions include/linux/cgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -396,9 +396,6 @@ struct cftype {
* closes the eventfd or on cgroup removing.
* This callback must be implemented, if you want provide
* notification functionality.
*
* Be careful. It can be called after destroy(), so you have
* to keep all nesessary data, until all events are removed.
*/
int (*unregister_event)(struct cgroup *cgrp, struct cftype *cft,
struct eventfd_ctx *eventfd);
Expand Down
8 changes: 8 additions & 0 deletions kernel/cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -2994,6 +2994,7 @@ static void cgroup_event_remove(struct work_struct *work)

eventfd_ctx_put(event->eventfd);
kfree(event);
dput(cgrp->dentry);
}

/*
Expand Down Expand Up @@ -3114,6 +3115,13 @@ static int cgroup_write_event_control(struct cgroup *cgrp, struct cftype *cft,
goto fail;
}

/*
* Events should be removed after rmdir of cgroup directory, but before
* destroying subsystem state objects. Let's take reference to cgroup
* directory dentry to do that.
*/
dget(cgrp->dentry);

spin_lock(&cgrp->event_list_lock);
list_add(&event->list, &cgrp->event_list);
spin_unlock(&cgrp->event_list_lock);
Expand Down
9 changes: 0 additions & 9 deletions mm/memcontrol.c
Original file line number Diff line number Diff line change
Expand Up @@ -3361,12 +3361,6 @@ static int mem_cgroup_register_event(struct cgroup *cgrp, struct cftype *cft,
}
}

/*
* We need to increment refcnt to be sure that all thresholds
* will be unregistered before calling __mem_cgroup_free()
*/
mem_cgroup_get(memcg);

if (type == _MEM)
rcu_assign_pointer(memcg->thresholds, thresholds_new);
else
Expand Down Expand Up @@ -3460,9 +3454,6 @@ static int mem_cgroup_unregister_event(struct cgroup *cgrp, struct cftype *cft,
/* To be sure that nobody uses thresholds before freeing it */
synchronize_rcu();

for (i = 0; i < thresholds->size - size; i++)
mem_cgroup_put(memcg);

kfree(thresholds);
unlock:
mutex_unlock(&memcg->thresholds_lock);
Expand Down

0 comments on commit a0a4db5

Please sign in to comment.