[Devel] [PATCH RHEL9 COMMIT] fs/fuse kio: properly attach an address space to the krpc_send kthread

Konstantin Khorenko khorenko at virtuozzo.com
Mon Apr 7 16:03:25 MSK 2025


The commit is pushed to "branch-rh9-5.14.0-427.44.1.vz9.80.x-ovz" and will appear at git at bitbucket.org:openvz/vzkernel.git
after rh9-5.14.0-427.44.1.vz9.80.24
------>
commit b82e0c1576ce00e7ea36d956c0a121ed03c02b31
Author: Liu Kui <kui.liu at virtuozzo.com>
Date:   Sat Apr 5 10:22:01 2025 +0800

    fs/fuse kio: properly attach an address space to the krpc_send kthread
    
    We need to use kthread_use_mm() to make a kthread operate on an
    address space. Simply assigning a value to the mm and active_mm
    field of a kthread's task_struct would race against the scheduler
    resulting in crash.
    
    Fixes: #VSTOR-103399
    https://virtuozzo.atlassian.net/browse/VSTOR-103399
    
    Signed-off-by: Liu Kui <kui.liu at virtuozzo.com>
    Acked-by: Alexey Kuznetsov <kuznet at virtuozzo.com>
    
    Feature: fuse: kRPC - single RPC for kernel and userspace
---
 fs/fuse/kio/pcs/pcs_krpc.c | 28 +++++++++++++++++++---------
 fs/fuse/kio/pcs/pcs_krpc.h |  1 +
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/fs/fuse/kio/pcs/pcs_krpc.c b/fs/fuse/kio/pcs/pcs_krpc.c
index 28c6104d7dc3..eac6ac9c34bd 100644
--- a/fs/fuse/kio/pcs/pcs_krpc.c
+++ b/fs/fuse/kio/pcs/pcs_krpc.c
@@ -633,6 +633,8 @@ static int krpc_threadfn(void *data)
 {
 	struct pcs_krpc_set *krpcs = data;
 
+	kthread_use_mm(krpcs->mm);
+
 	for (;;) {
 		struct llist_node *ll;
 
@@ -643,7 +645,7 @@ static int krpc_threadfn(void *data)
 		if (ll == NULL) {
 			if (kthread_should_stop()) {
 				__set_current_state(TASK_RUNNING);
-				return 0;
+				break;
 			}
 			schedule();
 			continue;
@@ -660,6 +662,9 @@ static int krpc_threadfn(void *data)
 			ll = next;
 		}
 	}
+
+	kthread_unuse_mm(krpcs->mm);
+	return 0;
 }
 
 static int pcs_krpc_ioctl_send_msg(struct krpc_req *kreq)
@@ -671,14 +676,17 @@ static int pcs_krpc_ioctl_send_msg(struct krpc_req *kreq)
 		cc = container_of(kreq->krpc->krpcs, struct pcs_cluster_core, krpcs);
 		tsk = cc->krpcs.krpc_task;
 		if (unlikely(tsk == NULL)) {
-			tsk = kthread_create(krpc_threadfn, &cc->krpcs, "krpc_send");
-			if (tsk && !IS_ERR(tsk)) {
-				cc->krpcs.krpc_task = get_task_struct(tsk);
-				mmget(current->mm);
-				tsk->mm = current->mm;
-				tsk->active_mm = current->mm;
-				atomic_inc(&current->files->count);
-				tsk->files = current->files;
+			cc->krpcs.mm = get_task_mm(current);
+			if (cc->krpcs.mm) {
+				tsk = kthread_create(krpc_threadfn, &cc->krpcs, "krpc_send");
+				if (tsk && !IS_ERR(tsk)) {
+					cc->krpcs.krpc_task = get_task_struct(tsk);
+					atomic_inc(&current->files->count);
+					tsk->files = current->files;
+				} else {
+					mmput(cc->krpcs.mm);
+					cc->krpcs.mm = NULL;
+				}
 			}
 		}
 
@@ -1170,6 +1178,7 @@ void pcs_krpcset_init(struct pcs_krpc_set *krpcs)
 	INIT_LIST_HEAD(&krpcs->list);
 	krpcs->nkrpc = 0;
 	krpcs->krpc_task = NULL;
+	krpcs->mm = NULL;
 	init_llist_head(&krpcs->req_llist);
 	spin_lock_init(&krpcs->lock);
 }
@@ -1199,6 +1208,7 @@ void pcs_krpcset_fini(struct pcs_krpc_set *krpcs)
 	if (krpcs->krpc_task) {
 		kthread_stop(krpcs->krpc_task);
 		put_task_struct(krpcs->krpc_task);
+		mmput(krpcs->mm);
 	}
 	BUG_ON(!list_empty(&krpcs->list));
 	BUG_ON(krpcs->nkrpc != 0);
diff --git a/fs/fuse/kio/pcs/pcs_krpc.h b/fs/fuse/kio/pcs/pcs_krpc.h
index 15d9f77aa401..6a090ef66185 100644
--- a/fs/fuse/kio/pcs/pcs_krpc.h
+++ b/fs/fuse/kio/pcs/pcs_krpc.h
@@ -38,6 +38,7 @@ struct pcs_krpc_set {
 
 	spinlock_t			lock;
 	struct task_struct		*krpc_task;
+	struct mm_struct		*mm;
 	struct llist_head		req_llist;
 };
 


More information about the Devel mailing list