We should not keep @css_set_lock spinlock while removing group files
which leads to

 | BUG: sleeping function called from invalid context at 
kernel/locking/mutex.c:938

This is because cgroup_rm_file() function takes @kernfs_mutex itself.
Since we're keeping the reference to cset in VE itself we don't even
need to take spinlock at all, because cset won't disappear until last
put_ve() call.

https://jira.sw.ru/browse/PSBM-135460

Signed-off-by: Cyrill Gorcunov <gorcu...@gmail.com>
---
 kernel/cgroup/cgroup.c |   13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

Index: vzkernel/kernel/cgroup/cgroup.c
===================================================================
--- vzkernel.orig/kernel/cgroup/cgroup.c
+++ vzkernel/kernel/cgroup/cgroup.c
@@ -2152,9 +2152,9 @@ void cgroup_unmark_ve_roots(struct ve_st
        struct cftype *cft;
 
        cft = get_cftype_by_name(CGROUP_FILENAME_RELEASE_AGENT);
+       BUG_ON(!cft || cft->file_offset);
 
        mutex_lock(&cgroup_mutex);
-       spin_lock_irq(&css_set_lock);
 
        /*
         * We can safely use ve->ve_ns without rcu_read_lock here, as we are
@@ -2163,19 +2163,26 @@ void cgroup_unmark_ve_roots(struct ve_st
         */
        cset = rcu_dereference_protected(ve->ve_ns,
                        lockdep_is_held(&ve->op_sem))->cgroup_ns->root_cset;
+       BUG_ON(!cset);
 
+       /*
+        * Traversing @cgrp_links without @css_set_lock is safe here because
+        * we ourself are keeping the reference to the @cset so it won't
+        * disappear until the last reference get dropped upon ve destruction
+        * via put_ve() call.
+        */
        list_for_each_entry(link, &cset->cgrp_links, cgrp_link) {
                cgrp = link->cgrp;
 
                if (!is_virtualized_cgroup(cgrp))
                        continue;
 
-               cgroup_rm_file(cgrp, cft);
+               if (!cgroup_is_dead(cgrp))
+                       cgroup_rm_file(cgrp, cft);
                rcu_assign_pointer(cgrp->ve_owner, NULL);
                clear_bit(CGRP_VE_ROOT, &cgrp->flags);
        }
 
-       spin_unlock_irq(&css_set_lock);
        mutex_unlock(&cgroup_mutex);
        /* ve_owner == NULL will be visible */
        synchronize_rcu();
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to