diff options
| author | Yonglong Liu <liuyonglong@huawei.com> | 2018-12-14 22:53:25 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2018-12-16 15:07:32 -0500 |
| commit | c82bd077e1ba3dd586569c733dc6d3dd4b0e43cd (patch) | |
| tree | 01e7bd4b1a99fb6f4481d34aad6dfdfbe8f69ed4 | |
| parent | 31f6b61d810654fb3ef43f4d8afda0f44b142fad (diff) | |
net: hns: Free irq when exit from abnormal branch
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>
| -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, | |||
| 1284 | return cpu; | 1284 | return cpu; |
| 1285 | } | 1285 | } |
| 1286 | 1286 | ||
| 1287 | static void hns_nic_free_irq(int q_num, struct hns_nic_priv *priv) | ||
| 1288 | { | ||
| 1289 | int i; | ||
| 1290 | |||
| 1291 | for (i = 0; i < q_num * 2; i++) { | ||
| 1292 | if (priv->ring_data[i].ring->irq_init_flag == RCB_IRQ_INITED) { | ||
| 1293 | irq_set_affinity_hint(priv->ring_data[i].ring->irq, | ||
| 1294 | NULL); | ||
| 1295 | free_irq(priv->ring_data[i].ring->irq, | ||
| 1296 | &priv->ring_data[i]); | ||
| 1297 | priv->ring_data[i].ring->irq_init_flag = | ||
| 1298 | RCB_IRQ_NOT_INITED; | ||
| 1299 | } | ||
| 1300 | } | ||
| 1301 | } | ||
| 1302 | |||
| 1287 | static int hns_nic_init_irq(struct hns_nic_priv *priv) | 1303 | static int hns_nic_init_irq(struct hns_nic_priv *priv) |
| 1288 | { | 1304 | { |
| 1289 | struct hnae_handle *h = priv->ae_handle; | 1305 | struct hnae_handle *h = priv->ae_handle; |
| @@ -1309,7 +1325,7 @@ static int hns_nic_init_irq(struct hns_nic_priv *priv) | |||
| 1309 | if (ret) { | 1325 | if (ret) { |
| 1310 | netdev_err(priv->netdev, "request irq(%d) fail\n", | 1326 | netdev_err(priv->netdev, "request irq(%d) fail\n", |
| 1311 | rd->ring->irq); | 1327 | rd->ring->irq); |
| 1312 | return ret; | 1328 | goto out_free_irq; |
| 1313 | } | 1329 | } |
| 1314 | disable_irq(rd->ring->irq); | 1330 | disable_irq(rd->ring->irq); |
| 1315 | 1331 | ||
| @@ -1324,6 +1340,10 @@ static int hns_nic_init_irq(struct hns_nic_priv *priv) | |||
| 1324 | } | 1340 | } |
| 1325 | 1341 | ||
| 1326 | return 0; | 1342 | return 0; |
| 1343 | |||
| 1344 | out_free_irq: | ||
| 1345 | hns_nic_free_irq(h->q_num, priv); | ||
| 1346 | return ret; | ||
| 1327 | } | 1347 | } |
| 1328 | 1348 | ||
| 1329 | static int hns_nic_net_up(struct net_device *ndev) | 1349 | static int hns_nic_net_up(struct net_device *ndev) |
| @@ -1371,6 +1391,7 @@ out_has_some_queues: | |||
| 1371 | for (j = i - 1; j >= 0; j--) | 1391 | for (j = i - 1; j >= 0; j--) |
| 1372 | hns_nic_ring_close(ndev, j); | 1392 | hns_nic_ring_close(ndev, j); |
| 1373 | 1393 | ||
| 1394 | hns_nic_free_irq(h->q_num, priv); | ||
| 1374 | set_bit(NIC_STATE_DOWN, &priv->state); | 1395 | set_bit(NIC_STATE_DOWN, &priv->state); |
| 1375 | 1396 | ||
| 1376 | return ret; | 1397 | return ret; |
