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>
---
 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;
 };
 
-- 
2.39.5 (Apple Git-154)

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to