Skip to content

Commit

Permalink
net: hns3: do VF's pci re-initialization while PF doing FLR
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Huazhong Tan authored and David S. Miller committed Nov 10, 2018
1 parent 6b9a97e commit 862d969
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 8 deletions.
24 changes: 19 additions & 5 deletions drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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");
Expand Down
57 changes: 54 additions & 3 deletions drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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);
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 862d969

Please sign in to comment.