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 016e0ef689badaaa0efc95463900cfd31b9d6798
Author: Stanislav Kinsburskiy <skinsbur...@virtuozzo.com>
Date:   Tue Sep 28 14:42:33 2021 +0300

    ve/kthreadd: add per-ve kthreads creation interface
    
    Patch introduces new function kthread_create_on_node_ve_flags and a few 
helpers:
    1) kthread_create_on_node_ve and
    1) kthread_run_ve and
    2) kthread_create_ve
    
    Note: we need to able to provide fork flags to kthread creation to be able 
to
    fork one kthread from another as a sibling (this is needed to be able to put
    kthreadd in contianer pid ns, but keep global kthreadd as its parent).
    
    Signed-off-by: Stanislav Kinsburskiy <skinsbur...@virtuozzo.com>
    
    +++
    ve, kthread: Remove some useless crud.
    
    Simplify the code by removing useless macroses.
    
    Signed-off-by: Andrey Ryabinin <aryabi...@virtuozzo.com>
    
    +++
    ve,kthread: fix use-after-return.
    
    __kthread_create_ve() passes pointer to the data on stack to
    another thread, and return immidiately causing use-after-return.
    
    Fix this by moving all in upper function which waits
    another thread finishes it's job.
    
    https://jira.sw.ru/browse/PSBM-93708
    Signed-off-by: Andrey Ryabinin <aryabi...@virtuozzo.com>
    
    (cherry-picked from vz8 commit 9aea2bf6c848 ("ve/kthreadd: add per-ve 
kthreads
    creation interface"))
    
    Signed-off-by: Nikita Yushchenko <nikita.yushche...@virtuozzo.com>
---
 include/linux/kthread.h | 10 +++++
 kernel/kthread.c        | 97 +++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 95 insertions(+), 12 deletions(-)

diff --git a/include/linux/kthread.h b/include/linux/kthread.h
index 346b0f269161..6d5827ab4bf8 100644
--- a/include/linux/kthread.h
+++ b/include/linux/kthread.h
@@ -56,6 +56,16 @@ bool kthread_is_per_cpu(struct task_struct *k);
        __k;                                                               \
 })
 
+#ifdef CONFIG_VE
+
+__printf(6, 7)
+struct task_struct *kthread_create_on_node_ve_flags(struct ve_struct *ve,
+                                                   unsigned long flags,
+                                                   int (*threadfn)(void *data),
+                                                   void *data, int node,
+                                                   const char namefmt[],
+                                                   ...);
+#endif
 void free_kthread_struct(struct task_struct *k);
 void kthread_bind(struct task_struct *k, unsigned int cpu);
 void kthread_bind_mask(struct task_struct *k, const struct cpumask *mask);
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 5b37a8567168..127ecaa457b5 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -28,6 +28,7 @@
 #include <linux/uaccess.h>
 #include <linux/numa.h>
 #include <linux/sched/isolation.h>
+#include <linux/ve.h>
 #include <trace/events/sched.h>
 
 
@@ -331,7 +332,8 @@ int tsk_fork_get_node(struct task_struct *tsk)
        return NUMA_NO_NODE;
 }
 
-static void create_kthread(struct kthread_create_info *create)
+static void create_kthread_flags(struct kthread_create_info *create,
+                                unsigned long flags)
 {
        int pid;
 
@@ -339,7 +341,8 @@ static void create_kthread(struct kthread_create_info 
*create)
        current->pref_node_fork = create->node;
 #endif
        /* We want our own signal handler (we take no signals by default). */
-       pid = kernel_thread(kthread, create, CLONE_FS | CLONE_FILES | SIGCHLD);
+       pid = kernel_thread(kthread, create,
+                           flags | CLONE_FS | CLONE_FILES | SIGCHLD);
        if (pid < 0) {
                /* If user was SIGKILLed, I release the structure. */
                struct completion *done = xchg(&create->done, NULL);
@@ -353,13 +356,48 @@ static void create_kthread(struct kthread_create_info 
*create)
        }
 }
 
-static __printf(4, 0)
-struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data),
-                                                   void *data, int node,
-                                                   const char namefmt[],
-                                                   va_list args)
+static void create_kthread(struct kthread_create_info *create)
+{
+       return create_kthread_flags(create, 0);
+}
+
+#ifdef CONFIG_VE
+struct kthread_create_work {
+       struct kthread_work work;
+       struct kthread_create_info *info;
+       unsigned long flags;
+};
+
+static void kthread_create_fn(struct kthread_work *w)
+{
+       struct kthread_create_work *work = container_of(w,
+                       struct kthread_create_work, work);
+
+       create_kthread_flags(work->info, work->flags);
+}
+
+#endif
+static void kthread_create_add(struct kthread_create_info *create)
+{
+       spin_lock(&kthread_create_lock);
+       list_add_tail(&create->list, &kthread_create_list);
+       spin_unlock(&kthread_create_lock);
+
+       wake_up_process(kthreadd_task);
+}
+
+static __printf(6, 0)
+struct task_struct *__kthread_create_on_node_ve(struct ve_struct *ve,
+                                               unsigned long flags,
+                                               int (*threadfn)(void *data),
+                                               void *data, int node,
+                                               const char namefmt[],
+                                               va_list args)
 {
        DECLARE_COMPLETION_ONSTACK(done);
+       struct kthread_create_work work = {
+               KTHREAD_WORK_INIT(work.work, kthread_create_fn),
+       };
        struct task_struct *task;
        struct kthread_create_info *create = kmalloc(sizeof(*create),
                                                     GFP_KERNEL);
@@ -371,11 +409,15 @@ struct task_struct *__kthread_create_on_node(int 
(*threadfn)(void *data),
        create->node = node;
        create->done = &done;
 
-       spin_lock(&kthread_create_lock);
-       list_add_tail(&create->list, &kthread_create_list);
-       spin_unlock(&kthread_create_lock);
-
-       wake_up_process(kthreadd_task);
+#ifdef CONFIG_VE
+       if (!ve_is_super(ve))
+       {
+               work.info = create;
+               work.flags = flags;
+               kthread_queue_work(ve->kthreadd_worker, &work.work);
+       } else
+#endif
+               kthread_create_add(create);
        /*
         * Wait for completion in killable state, for I might be chosen by
         * the OOM killer while kthreadd is trying to allocate memory for
@@ -418,6 +460,16 @@ struct task_struct *__kthread_create_on_node(int 
(*threadfn)(void *data),
        return task;
 }
 
+static __printf(4, 0)
+struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data),
+                                                   void *data, int node,
+                                                   const char namefmt[],
+                                                   va_list args)
+{
+       return __kthread_create_on_node_ve(get_ve0(), 0,
+                                          threadfn, data, node, namefmt, args);
+}
+
 /**
  * kthread_create_on_node - create a kthread.
  * @threadfn: the function to run until signal_pending(current).
@@ -457,6 +509,27 @@ struct task_struct *kthread_create_on_node(int 
(*threadfn)(void *data),
 }
 EXPORT_SYMBOL(kthread_create_on_node);
 
+#ifdef CONFIG_VE
+struct task_struct *kthread_create_on_node_ve_flags(struct ve_struct *ve,
+                                                   unsigned long flags,
+                                                   int (*threadfn)(void *data),
+                                                   void *data, int node,
+                                                   const char namefmt[],
+                                                   ...)
+{
+       struct task_struct *task;
+       va_list args;
+
+       va_start(args, namefmt);
+       task = __kthread_create_on_node_ve(ve, flags,
+                                          threadfn, data, node, namefmt, args);
+       va_end(args);
+
+       return task;
+}
+EXPORT_SYMBOL(kthread_create_on_node_ve_flags);
+#endif
+
 static void __kthread_bind_mask(struct task_struct *p, const struct cpumask 
*mask, unsigned int state)
 {
        unsigned long flags;
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to