From: Weili Qian qianweili@huawei.com
[ Upstream commit 64b9642fc29a14e1fe67842be9c69c7b90a3bcd6 ]
When disabling SR-IOV, clear the configuration of each VF in the hardware. Do not exit the configuration clearing process due to the failure of a single VF. Additionally, Clear the VF configurations before decrementing the PM counter.
Signed-off-by: Weili Qian qianweili@huawei.com Signed-off-by: Chenghai Huang huangchenghai2@huawei.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
YES – this patch fixes a regression that leaves HiSilicon QM VFs configured in hardware after SR-IOV disable or an enable failure.
- `drivers/crypto/hisilicon/qm.c:4010` updates `qm->vfs_num` before `pci_enable_sriov()`, so if the enable step fails the rollback in `qm_clear_vft_config()` actually iterates the programmed VFs; after 13e21e0ba44f (“adjust the internal processing sequence…”) this value stayed 0 and the hardware VFT tables were left stale. - `drivers/crypto/hisilicon/qm.c:4051` now clears the VF entries while the device is still powered instead of zeroing `qm->vfs_num` and dropping the runtime-PM ref first, ensuring the SQC/CQC slots reserved for VFs are released back to the PF even on disable paths. - `drivers/crypto/hisilicon/qm.c:3663` clears every VF VFT slot and no longer aborts on the first error, avoiding partially-cleared configurations that keep some queues orphaned. - Without this fix, any failed SR-IOV enable attempt or VF disable leaves the PF unable to reclaim those queue pairs and can make subsequent enables misbehave, so users hit a functional regression; the change is small, driver-local, and restores the pre-regression clean-up semantics.
Recommendation: backport alongside (or after) 13e21e0ba44f5fad02a3b7b34987ff3845718198 in affected stable trees.
drivers/crypto/hisilicon/qm.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index 822202e0f11b6..f9bf102b2b37d 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -3646,19 +3646,19 @@ static int qm_vf_q_assign(struct hisi_qm *qm, u32 num_vfs) return 0; }
-static int qm_clear_vft_config(struct hisi_qm *qm) +static void qm_clear_vft_config(struct hisi_qm *qm) { - int ret; u32 i;
- for (i = 1; i <= qm->vfs_num; i++) { - ret = hisi_qm_set_vft(qm, i, 0, 0); - if (ret) - return ret; - } - qm->vfs_num = 0; + /* + * When disabling SR-IOV, clear the configuration of each VF in the hardware + * sequentially. Failure to clear a single VF should not affect the clearing + * operation of other VFs. + */ + for (i = 1; i <= qm->vfs_num; i++) + (void)hisi_qm_set_vft(qm, i, 0, 0);
- return 0; + qm->vfs_num = 0; }
static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) @@ -3993,13 +3993,13 @@ int hisi_qm_sriov_enable(struct pci_dev *pdev, int max_vfs) goto err_put_sync; }
+ qm->vfs_num = num_vfs; ret = pci_enable_sriov(pdev, num_vfs); if (ret) { pci_err(pdev, "Can't enable VF!\n"); qm_clear_vft_config(qm); goto err_put_sync; } - qm->vfs_num = num_vfs;
pci_info(pdev, "VF enabled, vfs_num(=%d)!\n", num_vfs);
@@ -4034,11 +4034,10 @@ int hisi_qm_sriov_disable(struct pci_dev *pdev, bool is_frozen) }
pci_disable_sriov(pdev); - - qm->vfs_num = 0; + qm_clear_vft_config(qm); qm_pm_put_sync(qm);
- return qm_clear_vft_config(qm); + return 0; } EXPORT_SYMBOL_GPL(hisi_qm_sriov_disable);