crypto: qat - keep VFs enabled during reset

When a reset is triggered via sysfs, the PCI core invokes the
reset_prepare() callback while holding pci_dev_lock(), which includes
the PCI configuration space access semaphore. If reset_prepare() calls
adf_dev_down(), the call chain adf_dev_stop() -> adf_disable_sriov()
-> pci_disable_sriov() attempts to acquire the same semaphore,
resulting in a deadlock.

Avoid this by skipping pci_disable_sriov() when ADF_STATUS_RESTARTING
is set. During reset the PCI topology is preserved, so VF devices
remain valid and enumerated across the reset. VF notification and the
quiesce handshake via adf_pf2vf_notify_restarting() are still
performed unconditionally so that VFs stop submitting work before the
PF shuts down.

Correspondingly, skip pci_enable_sriov() in adf_enable_sriov() when
VFs are already present, since their PCI devices were preserved from
before the restart.

This is in preparation for adding reset_prepare() and reset_done()
callbacks in adf_aer.c.

Cc: stable@vger.kernel.org
Signed-off-by: Ahsan Atta <ahsan.atta@intel.com>
Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Reviewed-by: Damian Muszynski <damian.muszynski@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Ahsan Atta 2026-05-13 17:16:54 +02:00 committed by Herbert Xu
parent 277281c10c
commit 5751850005

View File

@ -91,6 +91,10 @@ static int adf_enable_sriov(struct adf_accel_dev *accel_dev)
/* Enable VF to PF interrupts for all VFs */
adf_enable_all_vf2pf_interrupts(accel_dev, totalvfs);
/* Do not enable SR-IOV if already enabled */
if (pci_num_vf(pdev))
return 0;
/*
* Due to the hardware design, when SR-IOV and the ring arbiter
* are enabled all the VFs supported in hardware must be enabled in
@ -260,7 +264,13 @@ void adf_disable_sriov(struct adf_accel_dev *accel_dev)
adf_pf2vf_notify_restarting(accel_dev);
adf_pf2vf_wait_for_restarting_complete(accel_dev);
pci_disable_sriov(accel_to_pci_dev(accel_dev));
/*
* When the device is restarting, preserve VF PCI devices across
* the reset by skipping pci_disable_sriov(). VFs are notified to
* quiesce regardless so the PF can safely shut down.
*/
if (!test_bit(ADF_STATUS_RESTARTING, &accel_dev->status))
pci_disable_sriov(accel_to_pci_dev(accel_dev));
/* Block VF2PF work and disable VF to PF interrupts */
adf_disable_all_vf2pf_interrupts(accel_dev);