This commit restores the previously removed functions kthread wake/stop/create, and use ops structure vhost_worker_ops to manage worker wakeup, stop and creation. The function vhost_worker_create initializes these ops pointers based on the value of inherit_owner
The old function was remove in commit 6e890c5d5021 ("vhost: use vhost_tasks for worker threads") Signed-off-by: Cindy Lu <l...@redhat.com> --- drivers/vhost/vhost.c | 48 ++++++++++++++++++++++++++++++++++++++++++- drivers/vhost/vhost.h | 1 + 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index c162ad772f8f..be97028a8baf 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -734,11 +734,21 @@ static void vhost_task_wakeup(struct vhost_worker *worker) return vhost_task_wake(worker->vtsk); } +static void vhost_kthread_wakeup(struct vhost_worker *worker) +{ + wake_up_process(worker->kthread_task); +} + static void vhost_task_do_stop(struct vhost_worker *worker) { return vhost_task_stop(worker->vtsk); } +static void vhost_kthread_do_stop(struct vhost_worker *worker) +{ + kthread_stop(worker->kthread_task); +} + static int vhost_task_worker_create(struct vhost_worker *worker, struct vhost_dev *dev, const char *name) { @@ -762,6 +772,41 @@ static int vhost_task_worker_create(struct vhost_worker *worker, return 0; } +static int vhost_kthread_worker_create(struct vhost_worker *worker, + struct vhost_dev *dev, const char *name) +{ + struct task_struct *task; + u32 id; + int ret; + + task = kthread_create(vhost_run_work_kthread_list, worker, "%s", name); + if (IS_ERR(task)) + return PTR_ERR(task); + + worker->kthread_task = task; + wake_up_process(task); + ret = xa_alloc(&dev->worker_xa, &id, worker, xa_limit_32b, GFP_KERNEL); + if (ret < 0) + goto stop_worker; + + ret = vhost_attach_task_to_cgroups(worker); + if (ret) + goto stop_worker; + + worker->id = id; + return 0; + +stop_worker: + vhost_kthread_do_stop(worker); + return ret; +} + +static const struct vhost_worker_ops kthread_ops = { + .create = vhost_kthread_worker_create, + .stop = vhost_kthread_do_stop, + .wakeup = vhost_kthread_wakeup, +}; + static const struct vhost_worker_ops vhost_task_ops = { .create = vhost_task_worker_create, .stop = vhost_task_do_stop, @@ -773,7 +818,8 @@ static struct vhost_worker *vhost_worker_create(struct vhost_dev *dev) struct vhost_worker *worker; char name[TASK_COMM_LEN]; int ret; - const struct vhost_worker_ops *ops = &vhost_task_ops; + const struct vhost_worker_ops *ops = + dev->inherit_owner ? &vhost_task_ops : &kthread_ops; worker = kzalloc(sizeof(*worker), GFP_KERNEL_ACCOUNT); if (!worker) diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index 98895e299efa..af4b2f7d3b91 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -37,6 +37,7 @@ struct vhost_worker_ops { }; struct vhost_worker { + struct task_struct *kthread_task; struct vhost_task *vtsk; struct vhost_dev *dev; /* Used to serialize device wide flushing with worker swapping. */ -- 2.45.0