Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+19 −5
Original line number Diff line number Diff line
@@ -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");
+54 −3
Original line number Diff line number Diff line
@@ -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,18 +2169,23 @@ 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);

	if (test_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state)) {
		hclgevf_misc_irq_uninit(hdev);
	hclgevf_cmd_uninit(hdev);
		hclgevf_uninit_msi(hdev);
		hclgevf_pci_uninit(hdev);
	}

	hclgevf_cmd_uninit(hdev);
}

static int hclgevf_init_ae_dev(struct hnae3_ae_dev *ae_dev)
{
	struct pci_dev *pdev = ae_dev->pdev;
+1 −0
Original line number Diff line number Diff line
@@ -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,