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

Commit c8e78cbc authored by Yonglong Liu's avatar Yonglong Liu Committed by Greg Kroah-Hartman
Browse files

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: default avatarYonglong Liu <liuyonglong@huawei.com>
Signed-off-by: default avatarPeng Li <lipeng321@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent ac9ae193
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -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 @@ static int hns_nic_net_up(struct net_device *ndev)
	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;