diff options
author | Ahsan Atta <ahsan.atta@intel.com> | 2021-08-12 23:21:27 +0300 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2021-08-21 10:44:56 +0300 |
commit | 8af4a436e665201872348aa2ba6e7033d4c17823 (patch) | |
tree | 5455dbf2ee0207a38bca1762200920bda5e050df /drivers/crypto/qat/qat_c3xxxvf/adf_drv.c | |
parent | e6dac5ea6f8e68c1d4fda7ffb6903c33161b3b4e (diff) | |
download | linux-8af4a436e665201872348aa2ba6e7033d4c17823.tar.xz |
crypto: qat - flush vf workqueue at driver removal
There is a race condition during shutdown in adf_disable_sriov() where
both the PF and the VF drivers are loaded on the host system.
The PF notifies a VF with a "RESTARTING" message due to which the VF
starts an asynchronous worker to stop and shutdown itself.
At the same time the PF calls pci_disable_sriov() which invokes the
remove() routine on the VF device driver triggering the shutdown flow
again.
This change fixes the problem by ensuring that the VF flushes the worker
that performs stop()/shutdown() before these two functions are called in
the remove(). To make sure that no additional PV/VF messages are
processed by the VF, interrupts are disabled before flushing the
workqueue.
Signed-off-by: Ahsan Atta <ahsan.atta@intel.com>
Co-developed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Reviewed-by: Fiona Trahe <fiona.trahe@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/qat/qat_c3xxxvf/adf_drv.c')
-rw-r--r-- | drivers/crypto/qat/qat_c3xxxvf/adf_drv.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/crypto/qat/qat_c3xxxvf/adf_drv.c b/drivers/crypto/qat/qat_c3xxxvf/adf_drv.c index 7ef5a5185d29..1df1b868978d 100644 --- a/drivers/crypto/qat/qat_c3xxxvf/adf_drv.c +++ b/drivers/crypto/qat/qat_c3xxxvf/adf_drv.c @@ -211,6 +211,7 @@ static void adf_remove(struct pci_dev *pdev) pr_err("QAT: Driver removal failed\n"); return; } + adf_flush_vf_wq(accel_dev); adf_dev_stop(accel_dev); adf_dev_shutdown(accel_dev); adf_cleanup_accel(accel_dev); |