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: Huazhong Tan <tanhuazhong@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
6b9a97ee43
commit
862d969a3a
@ -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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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)
|
|||||||
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 @@ err_cmd_init:
|
|||||||
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 {
|
|||||||
/* 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,
|
||||||
|
Loading…
Reference in New Issue
Block a user