net: hns3: re-organize vector handle

To prevent loss user's IRQ affinity configuration when DOWN,
this patch moves out release/request operation of the vector
handle from net DOWN/UP, just do it when vector resource changes.

Signed-off-by: Yonglong Liu <liuyonglong@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Yonglong Liu 2020-01-04 10:49:25 +08:00 committed by David S. Miller
parent 698a89541c
commit 08a100689d

View File

@ -161,6 +161,8 @@ static int hns3_nic_init_irq(struct hns3_nic_priv *priv)
return ret; return ret;
} }
disable_irq(tqp_vectors->vector_irq);
irq_set_affinity_hint(tqp_vectors->vector_irq, irq_set_affinity_hint(tqp_vectors->vector_irq,
&tqp_vectors->affinity_mask); &tqp_vectors->affinity_mask);
@ -179,6 +181,7 @@ static void hns3_mask_vector_irq(struct hns3_enet_tqp_vector *tqp_vector,
static void hns3_vector_enable(struct hns3_enet_tqp_vector *tqp_vector) static void hns3_vector_enable(struct hns3_enet_tqp_vector *tqp_vector)
{ {
napi_enable(&tqp_vector->napi); napi_enable(&tqp_vector->napi);
enable_irq(tqp_vector->vector_irq);
/* enable vector */ /* enable vector */
hns3_mask_vector_irq(tqp_vector, 1); hns3_mask_vector_irq(tqp_vector, 1);
@ -378,18 +381,6 @@ static int hns3_nic_net_up(struct net_device *netdev)
if (ret) if (ret)
return ret; return ret;
/* the device can work without cpu rmap, only aRFS needs it */
ret = hns3_set_rx_cpu_rmap(netdev);
if (ret)
netdev_warn(netdev, "set rx cpu rmap fail, ret=%d!\n", ret);
/* get irq resource for all vectors */
ret = hns3_nic_init_irq(priv);
if (ret) {
netdev_err(netdev, "init irq failed! ret=%d\n", ret);
goto free_rmap;
}
clear_bit(HNS3_NIC_STATE_DOWN, &priv->state); clear_bit(HNS3_NIC_STATE_DOWN, &priv->state);
/* enable the vectors */ /* enable the vectors */
@ -402,22 +393,15 @@ static int hns3_nic_net_up(struct net_device *netdev)
/* start the ae_dev */ /* start the ae_dev */
ret = h->ae_algo->ops->start ? h->ae_algo->ops->start(h) : 0; ret = h->ae_algo->ops->start ? h->ae_algo->ops->start(h) : 0;
if (ret) if (ret) {
goto out_start_err; set_bit(HNS3_NIC_STATE_DOWN, &priv->state);
while (j--)
hns3_tqp_disable(h->kinfo.tqp[j]);
return 0; for (j = i - 1; j >= 0; j--)
hns3_vector_disable(&priv->tqp_vector[j]);
}
out_start_err:
set_bit(HNS3_NIC_STATE_DOWN, &priv->state);
while (j--)
hns3_tqp_disable(h->kinfo.tqp[j]);
for (j = i - 1; j >= 0; j--)
hns3_vector_disable(&priv->tqp_vector[j]);
hns3_nic_uninit_irq(priv);
free_rmap:
hns3_free_rx_cpu_rmap(netdev);
return ret; return ret;
} }
@ -514,11 +498,6 @@ static void hns3_nic_net_down(struct net_device *netdev)
if (ops->stop) if (ops->stop)
ops->stop(priv->ae_handle); ops->stop(priv->ae_handle);
hns3_free_rx_cpu_rmap(netdev);
/* free irq resources */
hns3_nic_uninit_irq(priv);
/* delay ring buffer clearing to hns3_reset_notify_uninit_enet /* delay ring buffer clearing to hns3_reset_notify_uninit_enet
* during reset process, because driver may not be able * during reset process, because driver may not be able
* to disable the ring through firmware when downing the netdev. * to disable the ring through firmware when downing the netdev.
@ -3642,19 +3621,13 @@ static void hns3_nic_uninit_vector_data(struct hns3_nic_priv *priv)
hns3_free_vector_ring_chain(tqp_vector, &vector_ring_chain); hns3_free_vector_ring_chain(tqp_vector, &vector_ring_chain);
if (tqp_vector->irq_init_flag == HNS3_VECTOR_INITED) {
irq_set_affinity_hint(tqp_vector->vector_irq, NULL);
free_irq(tqp_vector->vector_irq, tqp_vector);
tqp_vector->irq_init_flag = HNS3_VECTOR_NOT_INITED;
}
hns3_clear_ring_group(&tqp_vector->rx_group); hns3_clear_ring_group(&tqp_vector->rx_group);
hns3_clear_ring_group(&tqp_vector->tx_group); hns3_clear_ring_group(&tqp_vector->tx_group);
netif_napi_del(&priv->tqp_vector[i].napi); netif_napi_del(&priv->tqp_vector[i].napi);
} }
} }
static int hns3_nic_dealloc_vector_data(struct hns3_nic_priv *priv) static void hns3_nic_dealloc_vector_data(struct hns3_nic_priv *priv)
{ {
struct hnae3_handle *h = priv->ae_handle; struct hnae3_handle *h = priv->ae_handle;
struct pci_dev *pdev = h->pdev; struct pci_dev *pdev = h->pdev;
@ -3666,11 +3639,10 @@ static int hns3_nic_dealloc_vector_data(struct hns3_nic_priv *priv)
tqp_vector = &priv->tqp_vector[i]; tqp_vector = &priv->tqp_vector[i];
ret = h->ae_algo->ops->put_vector(h, tqp_vector->vector_irq); ret = h->ae_algo->ops->put_vector(h, tqp_vector->vector_irq);
if (ret) if (ret)
return ret; return;
} }
devm_kfree(&pdev->dev, priv->tqp_vector); devm_kfree(&pdev->dev, priv->tqp_vector);
return 0;
} }
static void hns3_ring_get_cfg(struct hnae3_queue *q, struct hns3_nic_priv *priv, static void hns3_ring_get_cfg(struct hnae3_queue *q, struct hns3_nic_priv *priv,
@ -4069,6 +4041,18 @@ static int hns3_client_init(struct hnae3_handle *handle)
goto out_reg_netdev_fail; goto out_reg_netdev_fail;
} }
/* the device can work without cpu rmap, only aRFS needs it */
ret = hns3_set_rx_cpu_rmap(netdev);
if (ret)
dev_warn(priv->dev, "set rx cpu rmap fail, ret=%d\n", ret);
ret = hns3_nic_init_irq(priv);
if (ret) {
dev_err(priv->dev, "init irq failed! ret=%d\n", ret);
hns3_free_rx_cpu_rmap(netdev);
goto out_init_irq_fail;
}
ret = hns3_client_start(handle); ret = hns3_client_start(handle);
if (ret) { if (ret) {
dev_err(priv->dev, "hns3_client_start fail! ret=%d\n", ret); dev_err(priv->dev, "hns3_client_start fail! ret=%d\n", ret);
@ -4090,6 +4074,9 @@ static int hns3_client_init(struct hnae3_handle *handle)
return ret; return ret;
out_client_start: out_client_start:
hns3_free_rx_cpu_rmap(netdev);
hns3_nic_uninit_irq(priv);
out_init_irq_fail:
unregister_netdev(netdev); unregister_netdev(netdev);
out_reg_netdev_fail: out_reg_netdev_fail:
hns3_uninit_phy(netdev); hns3_uninit_phy(netdev);
@ -4127,15 +4114,17 @@ static void hns3_client_uninit(struct hnae3_handle *handle, bool reset)
goto out_netdev_free; goto out_netdev_free;
} }
hns3_free_rx_cpu_rmap(netdev);
hns3_nic_uninit_irq(priv);
hns3_del_all_fd_rules(netdev, true); hns3_del_all_fd_rules(netdev, true);
hns3_clear_all_ring(handle, true); hns3_clear_all_ring(handle, true);
hns3_nic_uninit_vector_data(priv); hns3_nic_uninit_vector_data(priv);
ret = hns3_nic_dealloc_vector_data(priv); 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)
@ -4462,17 +4451,32 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
if (ret) if (ret)
goto err_uninit_vector; goto err_uninit_vector;
/* the device can work without cpu rmap, only aRFS needs it */
ret = hns3_set_rx_cpu_rmap(netdev);
if (ret)
dev_warn(priv->dev, "set rx cpu rmap fail, ret=%d\n", ret);
ret = hns3_nic_init_irq(priv);
if (ret) {
dev_err(priv->dev, "init irq failed! ret=%d\n", ret);
hns3_free_rx_cpu_rmap(netdev);
goto err_init_irq_fail;
}
ret = hns3_client_start(handle); ret = hns3_client_start(handle);
if (ret) { if (ret) {
dev_err(priv->dev, "hns3_client_start fail! ret=%d\n", ret); dev_err(priv->dev, "hns3_client_start fail! ret=%d\n", ret);
goto err_uninit_ring; goto err_client_start_fail;
} }
set_bit(HNS3_NIC_STATE_INITED, &priv->state); set_bit(HNS3_NIC_STATE_INITED, &priv->state);
return ret; return ret;
err_uninit_ring: err_client_start_fail:
hns3_free_rx_cpu_rmap(netdev);
hns3_nic_uninit_irq(priv);
err_init_irq_fail:
hns3_uninit_all_ring(priv); hns3_uninit_all_ring(priv);
err_uninit_vector: err_uninit_vector:
hns3_nic_uninit_vector_data(priv); hns3_nic_uninit_vector_data(priv);
@ -4522,6 +4526,8 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)
return 0; return 0;
} }
hns3_free_rx_cpu_rmap(netdev);
hns3_nic_uninit_irq(priv);
hns3_clear_all_ring(handle, true); hns3_clear_all_ring(handle, true);
hns3_reset_tx_queue(priv->ae_handle); hns3_reset_tx_queue(priv->ae_handle);
@ -4529,9 +4535,7 @@ 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); 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)