diff options
author | Yonglong Liu <liuyonglong@huawei.com> | 2018-12-15 11:53:25 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-01-13 10:03:50 +0100 |
commit | 03b2d56bda1eaee55fd8f80e4308eb7f6a29b49d (patch) | |
tree | 086905dd3b95ef1899bfeccbb9539064c94b0b10 /drivers/net/ethernet | |
parent | c2a11c3dc459e5940eed4f2691b90bd9276051cf (diff) |
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>
Diffstat (limited to 'drivers/net/ethernet')
-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 d96a64bc1db8..63a14edd6a19 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c @@ -1195,6 +1195,22 @@ static void hns_set_irq_affinity(struct hns_nic_priv *priv) } } +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; @@ -1219,7 +1235,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); rd->ring->irq_init_flag = RCB_IRQ_INITED; @@ -1229,6 +1245,10 @@ static int hns_nic_init_irq(struct hns_nic_priv *priv) hns_set_irq_affinity(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) @@ -1276,6 +1296,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; |