Commit 862d969a authored by Huazhong Tan's avatar Huazhong Tan Committed by David S. Miller

net: hns3: do VF's pci re-initialization while PF doing FLR

While doing PF FLR, VF's PCIe configuration space will be cleared, so
the pci and vector of VF should be re-initialized in the VF's reset
process while PF doing FLR.

Also, this patch fixes some memory not freed problem when pci
re-initialization is done during reset process.
Signed-off-by: default avatarHuazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6b9a97ee
......@@ -3848,20 +3848,30 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
/* Carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev);
ret = hns3_nic_alloc_vector_data(priv);
if (ret)
return ret;
hns3_restore_coal(priv);
ret = hns3_nic_init_vector_data(priv);
if (ret)
return ret;
goto err_dealloc_vector;
ret = hns3_init_all_ring(priv);
if (ret) {
hns3_nic_uninit_vector_data(priv);
priv->ring_data = NULL;
}
if (ret)
goto err_uninit_vector;
set_bit(HNS3_NIC_STATE_INITED, &priv->state);
return ret;
err_uninit_vector:
hns3_nic_uninit_vector_data(priv);
priv->ring_data = NULL;
err_dealloc_vector:
hns3_nic_dealloc_vector_data(priv);
return ret;
}
......@@ -3886,6 +3896,10 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)
hns3_store_coal(priv);
ret = hns3_nic_dealloc_vector_data(priv);
if (ret)
netdev_err(netdev, "dealloc vector error\n");
ret = hns3_uninit_all_ring(priv);
if (ret)
netdev_err(netdev, "uninit ring error\n");
......
......@@ -1766,6 +1766,7 @@ static int hclgevf_init_msi(struct hclgevf_dev *hdev)
hdev->vector_irq = devm_kcalloc(&pdev->dev, hdev->num_msi,
sizeof(int), GFP_KERNEL);
if (!hdev->vector_irq) {
devm_kfree(&pdev->dev, hdev->vector_status);
pci_free_irq_vectors(pdev);
return -ENOMEM;
}
......@@ -1777,6 +1778,8 @@ static void hclgevf_uninit_msi(struct hclgevf_dev *hdev)
{
struct pci_dev *pdev = hdev->pdev;
devm_kfree(&pdev->dev, hdev->vector_status);
devm_kfree(&pdev->dev, hdev->vector_irq);
pci_free_irq_vectors(pdev);
}
......@@ -2001,11 +2004,52 @@ static int hclgevf_query_vf_resource(struct hclgevf_dev *hdev)
return 0;
}
static int hclgevf_pci_reset(struct hclgevf_dev *hdev)
{
struct pci_dev *pdev = hdev->pdev;
int ret = 0;
if (hdev->reset_type == HNAE3_VF_FULL_RESET &&
test_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state)) {
hclgevf_misc_irq_uninit(hdev);
hclgevf_uninit_msi(hdev);
clear_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state);
}
if (!test_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state)) {
pci_set_master(pdev);
ret = hclgevf_init_msi(hdev);
if (ret) {
dev_err(&pdev->dev,
"failed(%d) to init MSI/MSI-X\n", ret);
return ret;
}
ret = hclgevf_misc_irq_init(hdev);
if (ret) {
hclgevf_uninit_msi(hdev);
dev_err(&pdev->dev, "failed(%d) to init Misc IRQ(vector0)\n",
ret);
return ret;
}
set_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state);
}
return ret;
}
static int hclgevf_reset_hdev(struct hclgevf_dev *hdev)
{
struct pci_dev *pdev = hdev->pdev;
int ret;
ret = hclgevf_pci_reset(hdev);
if (ret) {
dev_err(&pdev->dev, "pci reset failed %d\n", ret);
return ret;
}
ret = hclgevf_cmd_init(hdev);
if (ret) {
dev_err(&pdev->dev, "cmd failed %d\n", ret);
......@@ -2076,6 +2120,8 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
goto err_misc_irq_init;
}
set_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state);
ret = hclgevf_configure(hdev);
if (ret) {
dev_err(&pdev->dev, "failed(%d) to fetch configuration\n", ret);
......@@ -2123,16 +2169,21 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
hclgevf_cmd_uninit(hdev);
err_cmd_queue_init:
hclgevf_pci_uninit(hdev);
clear_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state);
return ret;
}
static void hclgevf_uninit_hdev(struct hclgevf_dev *hdev)
{
hclgevf_state_uninit(hdev);
hclgevf_misc_irq_uninit(hdev);
if (test_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state)) {
hclgevf_misc_irq_uninit(hdev);
hclgevf_uninit_msi(hdev);
hclgevf_pci_uninit(hdev);
}
hclgevf_cmd_uninit(hdev);
hclgevf_uninit_msi(hdev);
hclgevf_pci_uninit(hdev);
}
static int hclgevf_init_ae_dev(struct hnae3_ae_dev *ae_dev)
......
......@@ -73,6 +73,7 @@ enum hclgevf_states {
/* device states */
HCLGEVF_STATE_DOWN,
HCLGEVF_STATE_DISABLED,
HCLGEVF_STATE_IRQ_INITED,
/* task states */
HCLGEVF_STATE_SERVICE_SCHED,
HCLGEVF_STATE_RST_SERVICE_SCHED,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment