aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/cgroup.h3
-rw-r--r--kernel/cgroup.c8
-rw-r--r--mm/memcontrol.c9
3 files changed, 8 insertions, 12 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index b4f2201321cd..b8ad1ea99586 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -396,9 +396,6 @@ struct cftype {
396 * closes the eventfd or on cgroup removing. 396 * closes the eventfd or on cgroup removing.
397 * This callback must be implemented, if you want provide 397 * This callback must be implemented, if you want provide
398 * notification functionality. 398 * notification functionality.
399 *
400 * Be careful. It can be called after destroy(), so you have
401 * to keep all nesessary data, until all events are removed.
402 */ 399 */
403 int (*unregister_event)(struct cgroup *cgrp, struct cftype *cft, 400 int (*unregister_event)(struct cgroup *cgrp, struct cftype *cft,
404 struct eventfd_ctx *eventfd); 401 struct eventfd_ctx *eventfd);
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 87441fc75663..ef909a329750 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -2994,6 +2994,7 @@ static void cgroup_event_remove(struct work_struct *work)
2994 2994
2995 eventfd_ctx_put(event->eventfd); 2995 eventfd_ctx_put(event->eventfd);
2996 kfree(event); 2996 kfree(event);
2997 dput(cgrp->dentry);
2997} 2998}
2998 2999
2999/* 3000/*
@@ -3114,6 +3115,13 @@ static int cgroup_write_event_control(struct cgroup *cgrp, struct cftype *cft,
3114 goto fail; 3115 goto fail;
3115 } 3116 }
3116 3117
3118 /*
3119 * Events should be removed after rmdir of cgroup directory, but before
3120 * destroying subsystem state objects. Let's take reference to cgroup
3121 * directory dentry to do that.
3122 */
3123 dget(cgrp->dentry);
3124
3117 spin_lock(&cgrp->event_list_lock); 3125 spin_lock(&cgrp->event_list_lock);
3118 list_add(&event->list, &cgrp->event_list); 3126 list_add(&event->list, &cgrp->event_list);
3119 spin_unlock(&cgrp->event_list_lock); 3127 spin_unlock(&cgrp->event_list_lock);
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index f9ae4b4c36eb..f7b910fc14fb 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -3361,12 +3361,6 @@ static int mem_cgroup_register_event(struct cgroup *cgrp, struct cftype *cft,
3361 } 3361 }
3362 } 3362 }
3363 3363
3364 /*
3365 * We need to increment refcnt to be sure that all thresholds
3366 * will be unregistered before calling __mem_cgroup_free()
3367 */
3368 mem_cgroup_get(memcg);
3369
3370 if (type == _MEM) 3364 if (type == _MEM)
3371 rcu_assign_pointer(memcg->thresholds, thresholds_new); 3365 rcu_assign_pointer(memcg->thresholds, thresholds_new);
3372 else 3366 else
@@ -3460,9 +3454,6 @@ assign:
3460 /* To be sure that nobody uses thresholds before freeing it */ 3454 /* To be sure that nobody uses thresholds before freeing it */
3461 synchronize_rcu(); 3455 synchronize_rcu();
3462 3456
3463 for (i = 0; i < thresholds->size - size; i++)
3464 mem_cgroup_put(memcg);
3465
3466 kfree(thresholds); 3457 kfree(thresholds);
3467unlock: 3458unlock:
3468 mutex_unlock(&memcg->thresholds_lock); 3459 mutex_unlock(&memcg->thresholds_lock);