The commit is pushed to "branch-rh9-5.14.0-427.44.1.vz9.80.x-ovz" and will appear at g...@bitbucket.org:openvz/vzkernel.git after rh9-5.14.0-427.44.1.vz9.80.24 ------> commit b82e0c1576ce00e7ea36d956c0a121ed03c02b31 Author: Liu Kui <kui....@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....@virtuozzo.com> Acked-by: Alexey Kuznetsov <kuz...@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(¤t->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(¤t->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; }; _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel