After h->ae_algo->ops->get_vector() has acquired MSI-X vectors, a subsequent devm_kcalloc failure for priv->tqp_vector jumps to 'out' and returns without calling put_vector() to release them. The underlying hclge/hclgevf bookkeeping (num_msi_used, num_msi_left, vector_status[]) is left inconsistent: the vectors are marked as in use but hns3_enet never tracks or releases them. On the reset path this leak accumulates across failed reset attempts, steadily reducing num_msi_left until get_vector() can no longer satisfy the requested count, at which point the interface fails to recover. Call put_vector() for every vector acquired by get_vector() before returning an error, and reset priv->vector_num so the dealloc path cannot dereference a NULL priv->tqp_vector. Fixes: dd38c72604dc ("net: hns3: fix for coalesce configuration lost during reset") Signed-off-by: Jijie Shao --- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 47788be64be6..2f3aeade558c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -4854,7 +4854,7 @@ static int hns3_nic_alloc_vector_data(struct hns3_nic_priv *priv) GFP_KERNEL); if (!priv->tqp_vector) { ret = -ENOMEM; - goto out; + goto err_put_vector; } for (i = 0; i < priv->vector_num; i++) { @@ -4865,7 +4865,13 @@ static int hns3_nic_alloc_vector_data(struct hns3_nic_priv *priv) hns3_vector_coalesce_init(tqp_vector, priv); } -out: + devm_kfree(&pdev->dev, vector); + return 0; + +err_put_vector: + for (i = 0; i < vector_num; i++) + h->ae_algo->ops->put_vector(h, vector[i].vector); + priv->vector_num = 0; devm_kfree(&pdev->dev, vector); return ret; } -- 2.43.0