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) ...@@ -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 */ /* Carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev); netif_carrier_off(netdev);
ret = hns3_nic_alloc_vector_data(priv);
if (ret)
return ret;
hns3_restore_coal(priv); hns3_restore_coal(priv);
ret = hns3_nic_init_vector_data(priv); ret = hns3_nic_init_vector_data(priv);
if (ret) if (ret)
return ret; goto err_dealloc_vector;
ret = hns3_init_all_ring(priv); ret = hns3_init_all_ring(priv);
if (ret) { if (ret)
hns3_nic_uninit_vector_data(priv); goto err_uninit_vector;
priv->ring_data = NULL;
}
set_bit(HNS3_NIC_STATE_INITED, &priv->state); 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; return ret;
} }
...@@ -3886,6 +3896,10 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle) ...@@ -3886,6 +3896,10 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)
hns3_store_coal(priv); 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); ret = hns3_uninit_all_ring(priv);
if (ret) if (ret)
netdev_err(netdev, "uninit ring error\n"); netdev_err(netdev, "uninit ring error\n");
......
...@@ -1766,6 +1766,7 @@ static int hclgevf_init_msi(struct hclgevf_dev *hdev) ...@@ -1766,6 +1766,7 @@ static int hclgevf_init_msi(struct hclgevf_dev *hdev)
hdev->vector_irq = devm_kcalloc(&pdev->dev, hdev->num_msi, hdev->vector_irq = devm_kcalloc(&pdev->dev, hdev->num_msi,
sizeof(int), GFP_KERNEL); sizeof(int), GFP_KERNEL);
if (!hdev->vector_irq) { if (!hdev->vector_irq) {
devm_kfree(&pdev->dev, hdev->vector_status);
pci_free_irq_vectors(pdev); pci_free_irq_vectors(pdev);
return -ENOMEM; return -ENOMEM;
} }
...@@ -1777,6 +1778,8 @@ static void hclgevf_uninit_msi(struct hclgevf_dev *hdev) ...@@ -1777,6 +1778,8 @@ static void hclgevf_uninit_msi(struct hclgevf_dev *hdev)
{ {
struct pci_dev *pdev = hdev->pdev; 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); pci_free_irq_vectors(pdev);
} }
...@@ -2001,11 +2004,52 @@ static int hclgevf_query_vf_resource(struct hclgevf_dev *hdev) ...@@ -2001,11 +2004,52 @@ static int hclgevf_query_vf_resource(struct hclgevf_dev *hdev)
return 0; 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) static int hclgevf_reset_hdev(struct hclgevf_dev *hdev)
{ {
struct pci_dev *pdev = hdev->pdev; struct pci_dev *pdev = hdev->pdev;
int ret; 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); ret = hclgevf_cmd_init(hdev);
if (ret) { if (ret) {
dev_err(&pdev->dev, "cmd failed %d\n", ret); dev_err(&pdev->dev, "cmd failed %d\n", ret);
...@@ -2076,6 +2120,8 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) ...@@ -2076,6 +2120,8 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
goto err_misc_irq_init; goto err_misc_irq_init;
} }
set_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state);
ret = hclgevf_configure(hdev); ret = hclgevf_configure(hdev);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed(%d) to fetch configuration\n", 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) ...@@ -2123,16 +2169,21 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
hclgevf_cmd_uninit(hdev); hclgevf_cmd_uninit(hdev);
err_cmd_queue_init: err_cmd_queue_init:
hclgevf_pci_uninit(hdev); hclgevf_pci_uninit(hdev);
clear_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state);
return ret; return ret;
} }
static void hclgevf_uninit_hdev(struct hclgevf_dev *hdev) static void hclgevf_uninit_hdev(struct hclgevf_dev *hdev)
{ {
hclgevf_state_uninit(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_cmd_uninit(hdev);
hclgevf_uninit_msi(hdev);
hclgevf_pci_uninit(hdev);
} }
static int hclgevf_init_ae_dev(struct hnae3_ae_dev *ae_dev) static int hclgevf_init_ae_dev(struct hnae3_ae_dev *ae_dev)
......
...@@ -73,6 +73,7 @@ enum hclgevf_states { ...@@ -73,6 +73,7 @@ enum hclgevf_states {
/* device states */ /* device states */
HCLGEVF_STATE_DOWN, HCLGEVF_STATE_DOWN,
HCLGEVF_STATE_DISABLED, HCLGEVF_STATE_DISABLED,
HCLGEVF_STATE_IRQ_INITED,
/* task states */ /* task states */
HCLGEVF_STATE_SERVICE_SCHED, HCLGEVF_STATE_SERVICE_SCHED,
HCLGEVF_STATE_RST_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