drivers/vfio/pci/virtio/common.h | 2 +- drivers/vfio/pci/virtio/legacy_io.c | 17 +++--- drivers/vfio/pci/virtio/migrate.c | 90 ++++++++++++----------------- 3 files changed, 46 insertions(+), 63 deletions(-)
Jinhui Guo reported a mismatched spin_lock()/spin_unlock_irq() pair in virtiovf_read_device_context_chunk() where spin_unlock_irq() would unconditionally enable interrupts despite spin_lock() never having disabled them. On closer inspection, the list_lock spinlock with IRQ disabling was copied from the mlx5 variant driver where a hardirq completion callback justifies it, but the virtio driver has no interrupt context usage of list_lock. Patch 1 converts list_lock to a mutex, fixing the mismatch and aligning with peer vfio-pci variant drivers. Patch 2 converts the list_lock acquisitions to guard()/scoped_guard() where the lock scope aligns naturally with function or block scope. Patches 3 and 4 extend the same guard() conversion to the remaining two mutexes in the driver (migf->lock and bar_mutex). These are relatively independent of the list_lock fix but complete the conversion across the driver. Thanks, Alex Alex Williamson (4): vfio/virtio: Convert list_lock from spinlock to mutex vfio/virtio: Use guard() for list_lock where applicable vfio/virtio: Use guard() for migf->lock where applicable vfio/virtio: Use guard() for bar_mutex in legacy I/O drivers/vfio/pci/virtio/common.h | 2 +- drivers/vfio/pci/virtio/legacy_io.c | 17 +++--- drivers/vfio/pci/virtio/migrate.c | 90 ++++++++++++----------------- 3 files changed, 46 insertions(+), 63 deletions(-) -- 2.51.0
On 14/04/2026 23:06, Alex Williamson wrote: > Jinhui Guo reported a mismatched spin_lock()/spin_unlock_irq() pair > in virtiovf_read_device_context_chunk() where spin_unlock_irq() would > unconditionally enable interrupts despite spin_lock() never having > disabled them. On closer inspection, the list_lock spinlock with IRQ > disabling was copied from the mlx5 variant driver where a hardirq > completion callback justifies it, but the virtio driver has no > interrupt context usage of list_lock. Patch 1 converts list_lock to > a mutex, fixing the mismatch and aligning with peer vfio-pci variant > drivers. Alex, How about staying with spin_lock but without the 'irq' variant, instead of replacing to mutex ? The scope of the lock is very small which can fit spin. We may potentially get a performance degradation compared to mutex as part of the hot path of STOP_COPY where this lock is used. Note: I don't see that other peer vfio-pci variant drivers maintain a list of buffers as of this driver, unless I missed that. > Patch 2 converts the list_lock acquisitions to guard()/scoped_guard() > where the lock scope aligns naturally with function or block scope. > This patch might not be applicable if we'll stay with spin_lock. > Patches 3 and 4 extend the same guard() conversion to the remaining > two mutexes in the driver (migf->lock and bar_mutex). These are > relatively independent of the list_lock fix but complete the > conversion across the driver. Thanks, > Those 2 patches seem fine to me. Reviewed-by: Yishai Hadas <yishaih@nvidia.com> Yishai > Alex > > Alex Williamson (4): > vfio/virtio: Convert list_lock from spinlock to mutex > vfio/virtio: Use guard() for list_lock where applicable > vfio/virtio: Use guard() for migf->lock where applicable > vfio/virtio: Use guard() for bar_mutex in legacy I/O > > drivers/vfio/pci/virtio/common.h | 2 +- > drivers/vfio/pci/virtio/legacy_io.c | 17 +++--- > drivers/vfio/pci/virtio/migrate.c | 90 ++++++++++++----------------- > 3 files changed, 46 insertions(+), 63 deletions(-) >
On Wed, 15 Apr 2026 18:12:50 +0300 Yishai Hadas <yishaih@nvidia.com> wrote: > On 14/04/2026 23:06, Alex Williamson wrote: > > Jinhui Guo reported a mismatched spin_lock()/spin_unlock_irq() pair > > in virtiovf_read_device_context_chunk() where spin_unlock_irq() would > > unconditionally enable interrupts despite spin_lock() never having > > disabled them. On closer inspection, the list_lock spinlock with IRQ > > disabling was copied from the mlx5 variant driver where a hardirq > > completion callback justifies it, but the virtio driver has no > > interrupt context usage of list_lock. Patch 1 converts list_lock to > > a mutex, fixing the mismatch and aligning with peer vfio-pci variant > > drivers. > > Alex, > How about staying with spin_lock but without the 'irq' variant, instead > of replacing to mutex ? > > The scope of the lock is very small which can fit spin. > We may potentially get a performance degradation compared to mutex as > part of the hot path of STOP_COPY where this lock is used. > > Note: > I don't see that other peer vfio-pci variant drivers maintain a list of > buffers as of this driver, unless I missed that. The argument doesn't make sense to me, we use a spinlock if we have an operation that cannot be preempted and a spinlock-irq if we need to manage that from a hardirq context. I think we just need mutual exclusion here. Stealing the CPU because you want the absolute best performance for a little bit of list manipulation is not valid justification. Documentation/locking/mutex-design.rst: When to use mutexes ------------------- Unless the strict semantics of mutexes are unsuitable and/or the critical region prevents the lock from being shared, always prefer them to any other locking primitive. Can you cite specific requirements for a spinlock in the critical section here? Thanks, Alex > > Patch 2 converts the list_lock acquisitions to guard()/scoped_guard() > > where the lock scope aligns naturally with function or block scope. > > > > This patch might not be applicable if we'll stay with spin_lock. > > > Patches 3 and 4 extend the same guard() conversion to the remaining > > two mutexes in the driver (migf->lock and bar_mutex). These are > > relatively independent of the list_lock fix but complete the > > conversion across the driver. Thanks, > > > > Those 2 patches seem fine to me. > Reviewed-by: Yishai Hadas <yishaih@nvidia.com> > > Yishai > > > Alex > > > > Alex Williamson (4): > > vfio/virtio: Convert list_lock from spinlock to mutex > > vfio/virtio: Use guard() for list_lock where applicable > > vfio/virtio: Use guard() for migf->lock where applicable > > vfio/virtio: Use guard() for bar_mutex in legacy I/O > > > > drivers/vfio/pci/virtio/common.h | 2 +- > > drivers/vfio/pci/virtio/legacy_io.c | 17 +++--- > > drivers/vfio/pci/virtio/migrate.c | 90 ++++++++++++----------------- > > 3 files changed, 46 insertions(+), 63 deletions(-) > > >
On 15/04/2026 18:39, Alex Williamson wrote: > On Wed, 15 Apr 2026 18:12:50 +0300 > Yishai Hadas <yishaih@nvidia.com> wrote: > >> On 14/04/2026 23:06, Alex Williamson wrote: >>> Jinhui Guo reported a mismatched spin_lock()/spin_unlock_irq() pair >>> in virtiovf_read_device_context_chunk() where spin_unlock_irq() would >>> unconditionally enable interrupts despite spin_lock() never having >>> disabled them. On closer inspection, the list_lock spinlock with IRQ >>> disabling was copied from the mlx5 variant driver where a hardirq >>> completion callback justifies it, but the virtio driver has no >>> interrupt context usage of list_lock. Patch 1 converts list_lock to >>> a mutex, fixing the mismatch and aligning with peer vfio-pci variant >>> drivers. >> >> Alex, >> How about staying with spin_lock but without the 'irq' variant, instead >> of replacing to mutex ? >> >> The scope of the lock is very small which can fit spin. >> We may potentially get a performance degradation compared to mutex as >> part of the hot path of STOP_COPY where this lock is used. >> >> Note: >> I don't see that other peer vfio-pci variant drivers maintain a list of >> buffers as of this driver, unless I missed that. > > The argument doesn't make sense to me, we use a spinlock if we have an > operation that cannot be preempted and a spinlock-irq if we need to > manage that from a hardirq context. I think we just need mutual > exclusion here. Stealing the CPU because you want the absolute best > performance for a little bit of list manipulation is not valid > justification. > > Documentation/locking/mutex-design.rst: > > When to use mutexes > ------------------- > > Unless the strict semantics of mutexes are unsuitable and/or the critical > region prevents the lock from being shared, always prefer them to any other > locking primitive. > > Can you cite specific requirements for a spinlock in the critical > section here? Thanks, > I see In our use case, we mostly expect a single task handling the migration, so real contention is unlikely and we don’t anticipate the overhead of sleeping and waking to be triggered. That said, I’m fine with using a mutex here as of your patch. So, Reviewed-by: Yishai Hadas <yishaih@nvidia.com> For the full series. Yishai > >>> Patch 2 converts the list_lock acquisitions to guard()/scoped_guard() >>> where the lock scope aligns naturally with function or block scope. >>> >> >> This patch might not be applicable if we'll stay with spin_lock. >> >>> Patches 3 and 4 extend the same guard() conversion to the remaining >>> two mutexes in the driver (migf->lock and bar_mutex). These are >>> relatively independent of the list_lock fix but complete the >>> conversion across the driver. Thanks, >>> >> >> Those 2 patches seem fine to me. >> Reviewed-by: Yishai Hadas <yishaih@nvidia.com> >> >> Yishai >> >>> Alex >>> >>> Alex Williamson (4): >>> vfio/virtio: Convert list_lock from spinlock to mutex >>> vfio/virtio: Use guard() for list_lock where applicable >>> vfio/virtio: Use guard() for migf->lock where applicable >>> vfio/virtio: Use guard() for bar_mutex in legacy I/O >>> >>> drivers/vfio/pci/virtio/common.h | 2 +- >>> drivers/vfio/pci/virtio/legacy_io.c | 17 +++--- >>> drivers/vfio/pci/virtio/migrate.c | 90 ++++++++++++----------------- >>> 3 files changed, 46 insertions(+), 63 deletions(-) >>> >> >
© 2016 - 2026 Red Hat, Inc.