diff options
author | Yonglong Liu <liuyonglong@huawei.com> | 2018-12-15 06:53:25 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-01-13 11:51:01 +0300 |
commit | c8e78cbcde24a7bab0a5b1a897efa439b025f981 (patch) | |
tree | 1e5cd18607b60bce0510ceefa15e2f88735ac832 | |
parent | ac9ae1930a1b7136d9167373fb19c4c7d05c6c85 (diff) | |
download | linux-c8e78cbcde24a7bab0a5b1a897efa439b025f981.tar.xz |
net: hns: Free irq when exit from abnormal branch
[ Upstream commit c82bd077e1ba3dd586569c733dc6d3dd4b0e43cd ]
1.In "hns_nic_init_irq", if request irq fail at index i,
the function return directly without releasing irq resources
that already requested.
2.In "hns_nic_net_up" after "hns_nic_init_irq",
if exceptional branch occurs, irqs that already requested
are not release.
Signed-off-by: Yonglong Liu <liuyonglong@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns/hns_enet.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c index c9454c4784cb..03d959c7a39f 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c @@ -1284,6 +1284,22 @@ static int hns_nic_init_affinity_mask(int q_num, int ring_idx, return cpu; } +static void hns_nic_free_irq(int q_num, struct hns_nic_priv *priv) +{ + int i; + + for (i = 0; i < q_num * 2; i++) { + if (priv->ring_data[i].ring->irq_init_flag == RCB_IRQ_INITED) { + irq_set_affinity_hint(priv->ring_data[i].ring->irq, + NULL); + free_irq(priv->ring_data[i].ring->irq, + &priv->ring_data[i]); + priv->ring_data[i].ring->irq_init_flag = + RCB_IRQ_NOT_INITED; + } + } +} + static int hns_nic_init_irq(struct hns_nic_priv *priv) { struct hnae_handle *h = priv->ae_handle; @@ -1309,7 +1325,7 @@ static int hns_nic_init_irq(struct hns_nic_priv *priv) if (ret) { netdev_err(priv->netdev, "request irq(%d) fail\n", rd->ring->irq); - return ret; + goto out_free_irq; } disable_irq(rd->ring->irq); @@ -1324,6 +1340,10 @@ static int hns_nic_init_irq(struct hns_nic_priv *priv) } return 0; + +out_free_irq: + hns_nic_free_irq(h->q_num, priv); + return ret; } static int hns_nic_net_up(struct net_device *ndev) @@ -1371,6 +1391,7 @@ out_has_some_queues: for (j = i - 1; j >= 0; j--) hns_nic_ring_close(ndev, j); + hns_nic_free_irq(h->q_num, priv); set_bit(NIC_STATE_DOWN, &priv->state); return ret; |