Re: [PATCH V2 0/5] vDPA/ifcvf: implement immediate initialization mechanism
ping On 5/9/2023 2:05 AM, Zhu Lingshan wrote: Formerly, ifcvf driver has implemented a lazy-initialization mechanism for the virtqueues and other config space contents, it would store all configurations that passed down from the userspace, then load them to the device config space upon DRIVER_OK. This can not serve live migration, so this series implement an immediate initialization mechanism, which means rather than the former store-load process, the virtio operations like vq ops would take immediate actions by access the virtio registers. This series also implement irq synchronization in the reset routine Changes from V1: 1)pull device status in devce_reset (Jason) 2)simplify the procedure which sycn irqs (Jason) 3)fix typos(Michael) Zhu Lingshan (5): vDPA/ifcvf: virt queue ops take immediate actions vDPA/ifcvf: get_driver_features from virtio registers vDPA/ifcvf: retire ifcvf_start_datapath and ifcvf_add_status vDPA/ifcvf: synchronize irqs in the reset routine vDPA/ifcvf: a vendor driver should not set _CONFIG_S_FAILED drivers/vdpa/ifcvf/ifcvf_base.c | 146 ++-- drivers/vdpa/ifcvf/ifcvf_base.h | 17 ++-- drivers/vdpa/ifcvf/ifcvf_main.c | 98 - 3 files changed, 108 insertions(+), 153 deletions(-) ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH 0/3] vhost: Fix freezer/ps regressions
The following patches made over Linus's tree fix the 2 bugs: 1. vhost worker task shows up as a process forked from the parent that did VHOST_SET_OWNER ioctl instead of a process under root/kthreadd. This was causing breaking scripts. 2. vhost_tasks didn't disable or add support for freeze requests. The following patches fix these issues by making the vhost_task task a thread under the process that did the VHOST_SET_OWNER and uses get_signal() to handle freeze and SIGSTOP/KILL signals which is required when using CLONE_THREAD (really CLONE_THREAD requires CLONE_SIGHAND which requires SIGKILL/STOP to be supported). ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH 3/3] fork, vhost: Use CLONE_THREAD to fix freezer/ps regression
When switching from kthreads to vhost_tasks two bugs were added: 1. The vhost worker tasks's now show up as processes so scripts doing ps or ps a would not incorrectly detect the vhost task as another process. 2. kthreads disabled freeze by setting PF_NOFREEZE, but vhost tasks's didn't disable or add support for them. To fix both bugs, this switches the vhost task to be thread in the process that does the VHOST_SET_OWNER ioctl, and has vhost_worker call get_signal to support SIGKILL/SIGSTOP and freeze signals. Note that SIGKILL/STOP support is required because CLONE_THREAD requires CLONE_SIGHAND which requires those 2 signals to be suppported. This a modified version of patch originally written by Linus which handles his review comment to himself to rename ignore_signals to block_signals to better represent what it now does. And it includes a change to vhost_worker() to support SIGSTOP/KILL and freeze, and it drops the wait use per Oleg's review comment that it's no longer needed when using CLONE_THREAD. Fixes: 6e890c5d5021 ("vhost: use vhost_tasks for worker threads") Signed-off-by: Mike Christie --- drivers/vhost/vhost.c | 17 - include/linux/sched/task.h | 2 +- kernel/fork.c | 12 +++- kernel/signal.c| 1 + kernel/vhost_task.c| 16 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index a92af08e7864..bf83e9340e40 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -338,6 +338,7 @@ static int vhost_worker(void *data) struct vhost_worker *worker = data; struct vhost_work *work, *work_next; struct llist_node *node; + bool dead = false; for (;;) { /* mb paired w/ kthread_stop */ @@ -349,8 +350,22 @@ 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 tell us to return and exit. +*/ + if (!dead && signal_pending(current)) { + struct ksignal ksig; + + dead = get_signal(&ksig); + if (dead) + clear_thread_flag(TIF_SIGPENDING); + } + } node = llist_reverse_order(node); /* make sure flag is seen after deletion */ diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h index 537cbf9a2ade..249a5ece9def 100644 --- a/include/linux/sched/task.h +++ b/include/linux/sched/task.h @@ -29,7 +29,7 @@ struct kernel_clone_args { u32 io_thread:1; u32 user_worker:1; u32 no_files:1; - u32 ignore_signals:1; + u32 block_signals:1; unsigned long stack; unsigned long stack_size; unsigned long tls; diff --git a/kernel/fork.c b/kernel/fork.c index ed4e01daccaa..9e04ab5c3946 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -2338,14 +2338,10 @@ __latent_entropy struct task_struct *copy_process( p->flags |= PF_KTHREAD; if (args->user_worker) p->flags |= PF_USER_WORKER; - if (args->io_thread) { - /* -* Mark us an IO worker, and block any signal that isn't -* fatal or STOP -*/ + if (args->io_thread) p->flags |= PF_IO_WORKER; + if (args->block_signals) siginitsetinv(&p->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP)); - } if (args->name) strscpy_pad(p->comm, args->name, sizeof(p->comm)); @@ -2517,9 +2513,6 @@ __latent_entropy struct task_struct *copy_process( if (retval) goto bad_fork_cleanup_io; - if (args->ignore_signals) - ignore_signals(p); - stackleak_task_init(p); if (pid != &init_struct_pid) { @@ -2861,6 +2854,7 @@ struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node) .fn_arg = arg, .io_thread = 1, .user_worker= 1, + .block_signals = 1, }; return copy_process(NULL, 0, node, &args); diff --git a/kernel/signal.c b/kernel/signal.c index 8050fe23c732..a0f00a078cbb 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2891,6 +2891,7 @@ bool get_signal(struct ksignal *ksig) return ksig->sig > 0; } +EXPORT_SYMBOL_GPL(get_signal); /** * signal_delivered - called after signal deliver
[PATCH 2/3] signal: Don't exit for PF_USER_WORKER tasks
vhost_tasks also need to perform cleanup before exiting so this changes the check in get_signal to be more generic so both io thread and vhost tasks can do their cleanup. Signed-off-by: Mike Christie --- kernel/signal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index 3dc99b9aec7f..8050fe23c732 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2869,11 +2869,11 @@ bool get_signal(struct ksignal *ksig) } /* -* PF_IO_WORKER threads will catch and exit on fatal signals +* PF_USER_WORKER threads will catch and exit on fatal signals * themselves. They have cleanup that must be performed, so * we cannot call do_exit() on their behalf. */ - if (current->flags & PF_IO_WORKER) + if (current->flags & PF_USER_WORKER) goto out; /* -- 2.25.1 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH 1/3] signal: Don't always put SIGKILL in shared_pending
When get_pending detects the task has been marked to be killed we try to clean up the SIGKLL by doing a sigdelset and recalc_sigpending, but we still leave it in shared_pending. If the signal is being short circuit delivered there is no need to put in shared_pending so this adds a check in complete_signal. This patch was modified from Eric Biederman original patch. Signed-off-by: Mike Christie --- kernel/signal.c | 8 1 file changed, 8 insertions(+) diff --git a/kernel/signal.c b/kernel/signal.c index 8f6330f0e9ca..3dc99b9aec7f 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1052,6 +1052,14 @@ static void complete_signal(int sig, struct task_struct *p, enum pid_type type) signal->flags = SIGNAL_GROUP_EXIT; signal->group_exit_code = sig; signal->group_stop_count = 0; + + /* +* The signal is being short circuit delivered so +* don't set pending. +*/ + if (type != PIDTYPE_PID) + sigdelset(&signal->shared_pending.signal, sig); + t = p; do { task_clear_jobctl_pending(t, JOBCTL_PENDING_MASK); -- 2.25.1 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization