[RFC PATCH 2/8] vhost/vhost_task: Hook vhost layer into signal handler

From: Mike Christie
Date: Wed May 17 2023 - 20:10:13 EST


This patch has vhost use get_signal to handle freezing and sort of
handle signals. By the latter I mean that when we get SIGKILL, our
parent will exit and call our file_operatons release function. That will
then stop new work from breing queued and wait for the vhost_task to
handle completions for running IO. We then exit when those are done.

The next patches will then have us work more like io_uring where
we handle the get_signal return value and key off that to cleanup.

Signed-off-by: Mike Christie <michael.christie@xxxxxxxxxx>
---
drivers/vhost/vhost.c | 10 +++++++++-
include/linux/sched/vhost_task.h | 1 +
kernel/vhost_task.c | 20 ++++++++++++++++++++
3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index a92af08e7864..1ba9e068b2ab 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -349,8 +349,16 @@ static int vhost_worker(void *data)
}

node = llist_del_all(&worker->work_list);
- if (!node)
+ if (!node) {
schedule();
+ /*
+ * When we get a SIGKILL our release function will
+ * be called. That will stop new IOs from being queued
+ * and check for outstanding cmd responses. It will then
+ * call vhost_task_stop to exit us.
+ */
+ vhost_task_get_signal();
+ }

node = llist_reverse_order(node);
/* make sure flag is seen after deletion */
diff --git a/include/linux/sched/vhost_task.h b/include/linux/sched/vhost_task.h
index 6123c10b99cf..54b68115eb3b 100644
--- a/include/linux/sched/vhost_task.h
+++ b/include/linux/sched/vhost_task.h
@@ -19,5 +19,6 @@ struct vhost_task *vhost_task_create(int (*fn)(void *), void *arg,
void vhost_task_start(struct vhost_task *vtsk);
void vhost_task_stop(struct vhost_task *vtsk);
bool vhost_task_should_stop(struct vhost_task *vtsk);
+bool vhost_task_get_signal(void);

#endif
diff --git a/kernel/vhost_task.c b/kernel/vhost_task.c
index b7cbd66f889e..a661cfa32ba3 100644
--- a/kernel/vhost_task.c
+++ b/kernel/vhost_task.c
@@ -61,6 +61,26 @@ bool vhost_task_should_stop(struct vhost_task *vtsk)
}
EXPORT_SYMBOL_GPL(vhost_task_should_stop);

+/**
+ * vhost_task_get_signal - Check if there are pending signals
+ *
+ * Return true if we got SIGKILL.
+ */
+bool vhost_task_get_signal(void)
+{
+ struct ksignal ksig;
+ bool rc;
+
+ if (!signal_pending(current))
+ return false;
+
+ __set_current_state(TASK_RUNNING);
+ rc = get_signal(&ksig);
+ set_current_state(TASK_INTERRUPTIBLE);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(vhost_task_get_signal);
+
/**
* vhost_task_create - create a copy of a process to be used by the kernel
* @fn: thread stack
--
2.25.1