diff options
author | Mike Christie <michael.christie@oracle.com> | 2023-06-07 22:23:38 +0300 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2023-06-08 22:43:09 +0300 |
commit | 4b13cbef797048fbb525f8c635a5279e9d209d93 (patch) | |
tree | 59de4d4c9dc49411fe09d36c1390f58f08e7ad36 /drivers/vhost | |
parent | a284f09effea1908db7985dbfb5458c9100038d8 (diff) | |
download | linux-4b13cbef797048fbb525f8c635a5279e9d209d93.tar.xz |
vhost: Fix worker hangs due to missed wake up calls
We can race where we have added work to the work_list, but
vhost_task_fn has passed that check but not yet set us into
TASK_INTERRUPTIBLE. wake_up_process will see us in TASK_RUNNING and
just return.
This bug was intoduced in commit f9010dbdce91 ("fork, vhost: Use
CLONE_THREAD to fix freezer/ps regression") when I moved the setting
of TASK_INTERRUPTIBLE to simplfy the code and avoid get_signal from
logging warnings about being in the wrong state. This moves the setting
of TASK_INTERRUPTIBLE back to before we test if we need to stop the
task to avoid a possible race there as well. We then have vhost_worker
set TASK_RUNNING if it finds work similar to before.
Fixes: f9010dbdce91 ("fork, vhost: Use CLONE_THREAD to fix freezer/ps regression")
Signed-off-by: Mike Christie <michael.christie@oracle.com>
Message-Id: <20230607192338.6041-3-michael.christie@oracle.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'drivers/vhost')
-rw-r--r-- | drivers/vhost/vhost.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index ca1041c88c68..1f80eac5d6ae 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -341,6 +341,8 @@ static bool vhost_worker(void *data) node = llist_del_all(&worker->work_list); if (node) { + __set_current_state(TASK_RUNNING); + node = llist_reverse_order(node); /* make sure flag is seen after deletion */ smp_wmb(); |