[Devel] [PATCH VZ9 1/3] fs/fuse kio: properly attach an address space to the krpc_send kthread
Alexey Kuznetsov
kuznet at virtuozzo.com
Sat Apr 5 13:37:44 MSK 2025
Ack all 3
On Sat, Apr 5, 2025 at 10:26 AM Liu Kui <kui.liu at virtuozzo.com> wrote:
>
> 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>
> ---
> 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;
> };
>
> --
> 2.39.5 (Apple Git-154)
More information about the Devel
mailing list