[Devel] [PATCH RHEL9 COMMIT] ve: cgroup -- don't use atomic lock in the sleepable context

Konstantin Khorenko khorenko at virtuozzo.com
Fri Nov 12 19:42:49 MSK 2021


The commit is pushed to "branch-rh9-5.14.vz9.1.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh9-5.14.0-4.vz9.10.26
------>
commit 6834afadd23fb879c2527f83b1ca00302fd57889
Author: Cyrill Gorcunov <gorcunov at virtuozzo.com>
Date:   Fri Nov 12 19:42:49 2021 +0300

    ve: cgroup -- don't use atomic lock in the sleepable context
    
    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.
    Similarly to cgroup_mark_ve_roots() function we can traverse
    the @cgrp_links using only @cgroup_mutex without @css_set_lock.
    
    https://jira.sw.ru/browse/PSBM-135460
    
    Reviewed-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
    Signed-off-by: Cyrill Gorcunov <gorcunov at gmail.com>
---
 kernel/cgroup/cgroup.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index 0c4d44e497e3..d9d6942f60a4 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -2152,9 +2152,9 @@ void cgroup_unmark_ve_roots(struct ve_struct *ve)
 	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,24 @@ void cgroup_unmark_ve_roots(struct ve_struct *ve)
 	 */
 	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 for
+	 * the same reasons as in cgroup_mark_ve_roots().
+	 */
 	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();


More information about the Devel mailing list