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 ark-5.14
------>
commit 74116ac9747f54416882cd312b68ae3fbd63bd6b
Author: Stanislav Kinsburskiy <skinsbur...@virtuozzo.com>
Date:   Tue Sep 28 14:42:34 2021 +0300

    ve/kthreadd: create kthreadd in a containers pid ns
    
    The idea is simple: create another kworker in the one, attached to CT.
    The latter has containers pid ns for children, so the former will appear in
    containers pid ns.
    The latter then can be destroyed, thus leaving us "kthreadd" kernel thread 
not
    just attached, but also visible in the desired container.
    
    Notes:
    1) We create new kthread by using per-container creation helper.
    2) We don't need original attached worker when we have this new fully 
entered
    kthreadd, so this patch destroys original worker.
    3) New kthreadd is forked with CLONE_PARENT flag and thus will be reparented
    to host kthreadd.
    
    Signed-off-by: Stanislav Kinsburskiy <skinsbur...@virtuozzo.com>
    
    (cherry-picked from vz8 commit 2f1fad726487 ("ve/kthreadd: create kthreadd
    in a containers pid ns"))
    
    Signed-off-by: Nikita Yushchenko <nikita.yushche...@virtuozzo.com>
---
 include/linux/ve.h |  1 +
 kernel/ve/ve.c     | 41 ++++++++++++++++++++++++++++++++++++++---
 2 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/include/linux/ve.h b/include/linux/ve.h
index 6f75bd084e2e..cea4fa48d939 100644
--- a/include/linux/ve.h
+++ b/include/linux/ve.h
@@ -61,6 +61,7 @@ struct ve_struct {
        int                     _randomize_va_space;
 
        struct kthread_worker   *kthreadd_worker;
+       struct task_struct      *kthreadd_task;
 };
 
 extern int nr_ve;
diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index da86dae1a5f4..9c0070c39eb4 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -267,7 +267,9 @@ static void ve_drop_context(struct ve_struct *ve)
 
 static void ve_stop_kthreadd(struct ve_struct *ve)
 {
-       kthread_destroy_worker(ve->kthreadd_worker);
+       kthread_flush_worker(ve->kthreadd_worker);
+       kthread_stop(ve->kthreadd_task);
+       kfree(ve->kthreadd_worker);
        ve->kthreadd_worker = NULL;
 }
 
@@ -334,16 +336,49 @@ static struct kthread_worker *ve_create_kworker(struct 
ve_struct *ve)
        return w;
 }
 
+static int ve_create_kthreadd(struct ve_struct *ve,
+                             struct kthread_worker *gastarbeiter)
+{
+       struct kthread_worker *w;
+       struct task_struct *task;
+
+       w = kmalloc(sizeof(struct kthread_worker), GFP_KERNEL);
+       if (!w)
+               return -ENOMEM;
+       kthread_init_worker(w);
+
+       /* This is a trick to fork kthread in a container */
+       ve->kthreadd_worker = gastarbeiter;
+
+       /* We create kthread with CLONE_PARENT flags, because otherwise when
+        * gastarbeiter will be stopped, kthreadd will be reparented to idle,
+        * while we want to keep all the threads in kthreadd pool */
+       task = kthread_create_on_node_ve_flags(ve, CLONE_PARENT, 
kthread_worker_fn,
+                                              w, NUMA_NO_NODE, "kthreadd");
+       if (IS_ERR(task)) {
+               kfree(w);
+               return PTR_ERR(task);
+       }
+       wake_up_process(task);
+
+       ve->kthreadd_task = task;
+       ve->kthreadd_worker = w;
+       return 0;
+}
+
 static int ve_start_kthreadd(struct ve_struct *ve)
 {
        struct kthread_worker *w;
+       int err;
 
        w = ve_create_kworker(ve);
        if (IS_ERR(w))
                return PTR_ERR(w);
 
-       ve->kthreadd_worker = w;
-       return 0;
+       err = ve_create_kthreadd(ve, w);
+
+       kthread_destroy_worker(w);
+       return err;
 }
 
 /* under ve->op_sem write-lock */
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to