On 5/29/23 9:38 PM, Eric W. Biederman wrote: > diff --git a/kernel/vhost_task.c b/kernel/vhost_task.c > index b7cbd66f889e..f3ce0fa6edd7 100644 > --- a/kernel/vhost_task.c > +++ b/kernel/vhost_task.c ... > static int vhost_task_fn(void *data) > { > struct vhost_task *vtsk = data; > - int ret; > + bool dead = false; > + > + for (;;) { > + bool did_work; > + > + /* mb paired w/ kthread_stop */ > + set_current_state(TASK_INTERRUPTIBLE); > + > + if (test_bit(VHOST_TASK_FLAGS_STOP, &vtsk->flags)) { > + __set_current_state(TASK_RUNNING); > + break; > + } > + > + if (!dead && signal_pending(current)) { > + struct ksignal ksig; > + /* > + * Calling get_signal will block in SIGSTOP, > + * or clear fatal_signal_pending, but remember > + * what was set. > + * > + * This thread won't actually exit until all > + * of the file descriptors are closed, and > + * the release function is called. > + */ > + dead = get_signal(&ksig); Hey Eric, the patch works well. Thanks! There was just one small issue. get_signal() does try_to_freeze() -> ... __might_sleep() which wants the state to be TASK_RUNNING. We just need the patch below on top of yours which I think also cleans up some of the state setting weirdness with the code like where vhost.c calls __set_current_state(TASK_RUNNING) for each work. It looks like that was not needed for any reason like a work->fn changing the state and the old code could have done: node = llist_del_all(&worker->work_list); if (!node) { schedule(); continue; } else { __set_current_state(TASK_RUNNING); } So I think we can do the following on top of your patch: diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 221d1b6c1be5..074273020849 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -346,7 +346,6 @@ static bool vhost_worker(void *data) smp_wmb(); llist_for_each_entry_safe(work, work_next, node, node) { clear_bit(VHOST_WORK_QUEUED, &work->flags); - __set_current_state(TASK_RUNNING); kcov_remote_start_common(worker->kcov_handle); work->fn(work); kcov_remote_stop(); diff --git a/kernel/vhost_task.c b/kernel/vhost_task.c index f3ce0fa6edd7..fead2ed29561 100644 --- a/kernel/vhost_task.c +++ b/kernel/vhost_task.c @@ -29,12 +29,8 @@ static int vhost_task_fn(void *data) bool did_work; /* mb paired w/ kthread_stop */ - set_current_state(TASK_INTERRUPTIBLE); - - if (test_bit(VHOST_TASK_FLAGS_STOP, &vtsk->flags)) { - __set_current_state(TASK_RUNNING); + if (test_bit(VHOST_TASK_FLAGS_STOP, &vtsk->flags)) break; - } if (!dead && signal_pending(current)) { struct ksignal ksig; @@ -53,8 +49,10 @@ static int vhost_task_fn(void *data) } did_work = vtsk->fn(vtsk->data); - if (!did_work) + if (!did_work) { + set_current_state(TASK_INTERRUPTIBLE); schedule(); + } } complete(&vtsk->exited); _______________________________________________ Virtualization mailing list Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/virtualization