Signed-off-by: Valeriy Vdovin <[email protected]>
---
 include/linux/ve.h |  2 ++
 kernel/cgroup.c    |  1 +
 kernel/ve/ve.c     | 33 +++++++++++++++++++++++++++------
 3 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/include/linux/ve.h b/include/linux/ve.h
index 5bf275f..bf92bc9 100644
--- a/include/linux/ve.h
+++ b/include/linux/ve.h
@@ -220,6 +220,8 @@ int ve_set_release_agent_path(struct cgroup *cgroot,
 
 const char *ve_get_release_agent_path(struct cgroup *cgrp_root);
 
+void ve_cleanup_per_cgroot_data(struct cgroup *cgrp);
+
 extern struct ve_struct *get_ve(struct ve_struct *ve);
 extern void put_ve(struct ve_struct *ve);
 
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 704e1f4..68d8d80 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1578,6 +1578,7 @@ static void cgroup_drop_root(struct cgroupfs_root *root)
 {
        if (!root)
                return;
+       ve_cleanup_per_cgroot_data(&root->top_cgroup);
 
        BUG_ON(!root->hierarchy_id);
        spin_lock(&hierarchy_id_lock);
diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index fbbd704..239b3cd 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -745,18 +745,39 @@ err_list:
        return err;
 }
 
+static inline void per_cgroot_data_free(struct per_cgroot_data *data)
+{
+       struct cgroup_rcu_string *release_agent = data->release_agent_path;
+       RCU_INIT_POINTER(data->release_agent_path, NULL);
+       if (release_agent)
+               kfree_rcu(release_agent, rcu_head);
+       kfree(data);
+}
+
+void ve_cleanup_per_cgroot_data(struct cgroup *cgrp)
+{
+       struct per_cgroot_data *data, *saved;
+       struct ve_struct *ve;
+       rcu_read_lock();
+       ve = cgroup_get_ve_owner(cgrp);
+       raw_spin_lock(&ve->per_cgroot_list_lock);
+       list_for_each_entry_safe(data, saved, &ve->per_cgroot_list, list) {
+               if (data->cgroot == cgrp) {
+                       list_del_init(&data->list);
+                       per_cgroot_data_free(data);
+               }
+       }
+       raw_spin_unlock(&ve->per_cgroot_list_lock);
+       rcu_read_unlock();
+}
+
 static void ve_per_cgroot_free(struct ve_struct *ve)
 {
        struct per_cgroot_data *data, *saved;
-       struct cgroup_rcu_string *release_agent;
        raw_spin_lock(&ve->per_cgroot_list_lock);
        list_for_each_entry_safe(data, saved, &ve->per_cgroot_list, list) {
-               release_agent = data->release_agent_path;
-               RCU_INIT_POINTER(data->release_agent_path, NULL);
-               if (release_agent)
-                       kfree_rcu(release_agent, rcu_head);
                list_del_init(&data->list);
-               kfree(data);
+               per_cgroot_data_free(data);
        }
        raw_spin_unlock(&ve->per_cgroot_list_lock);
 }
-- 
1.8.3.1

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to