[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <BN9PR11MB52765AD421658A2C867AD77E8CD5A@BN9PR11MB5276.namprd11.prod.outlook.com>
Date: Fri, 21 Nov 2025 07:13:38 +0000
From: "Tian, Kevin" <kevin.tian@...el.com>
To: "Winiarski, Michal" <michal.winiarski@...el.com>, Jason Gunthorpe
<jgg@...pe.ca>, Alex Williamson <alex@...zbot.org>, Yishai Hadas
<yishaih@...dia.com>, Longfang Liu <liulongfang@...wei.com>, Shameer Kolothum
<skolothumtho@...dia.com>, Brett Creeley <brett.creeley@....com>, "Cabiddu,
Giovanni" <giovanni.cabiddu@...el.com>, "kvm@...r.kernel.org"
<kvm@...r.kernel.org>, qat-linux <qat-linux@...el.com>,
"virtualization@...ts.linux.dev" <virtualization@...ts.linux.dev>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
Subject: RE: [PATCH 1/6] vfio: Introduce .migration_reset_state() callback
> From: Winiarski, Michal <michal.winiarski@...el.com>
> Sent: Thursday, November 20, 2025 8:37 PM
>
> Resetting the migration device state is typically delegated to PCI
> .reset_done() callback.
> With VFIO, reset is usually called under vdev->memory_lock, which causes
> lockdep to report a following circular locking dependency scenario:
>
> 0: set_device_state
> driver->state_mutex -> migf->lock
> 1: data_read
> migf->lock -> mm->mmap_lock
> 2: vfio_pin_dma
> mm->mmap_lock -> vdev->memory_lock
> 3: vfio_pci_ioctl_reset
> vdev->memory_lock -> driver->state_mutex
>
> Introduce a .migration_reset_state() callback called outside of
> vdev->memory_lock to break the dependency chain.
so it kind of unifies the deferred_reset logic cross all drivers.
sounds reasonable as nobody should expect a concrete sequence of
a reset done vs. a racing set_device_state.
>
> +static void vfio_pci_dev_migration_reset_state(struct vfio_pci_core_device
> *vdev)
> +{
> + lockdep_assert_not_held(&vdev->memory_lock);
> +
> + if (!vdev->vdev.mig_ops->migration_reset_state)
> + return;
mig_ops could be NULL.
> @@ -1230,6 +1242,8 @@ static int vfio_pci_ioctl_reset(struct
> vfio_pci_core_device *vdev,
> ret = pci_try_reset_function(vdev->pdev);
> up_write(&vdev->memory_lock);
>
> + vfio_pci_dev_migration_reset_state(vdev);
> +
only if the previous reset succeeds.
> @@ -2486,8 +2501,10 @@ static int vfio_pci_dev_set_hot_reset(struct
> vfio_device_set *dev_set,
>
> err_undo:
> list_for_each_entry_from_reverse(vdev, &dev_set->device_list,
> - vdev.dev_set_list)
> + vdev.dev_set_list) {
> up_write(&vdev->memory_lock);
> + vfio_pci_dev_migration_reset_state(vdev);
> + }
ditto
btw some reset paths are missed in drivers/vfio/pci/vfio_pci_config.c,
e.g. for vFLR emulation.
Powered by blists - more mailing lists