Skip to content

Commit

Permalink
net: hns3: delay ring buffer clearing during reset
Browse files Browse the repository at this point in the history
[ Upstream commit 3a30964 ]

The driver may not be able to disable the ring through firmware
when downing the netdev during reset process, which may cause
hardware accessing freed buffer problem.

This patch delays the ring buffer clearing to reset uninit
process because hardware will not access the ring buffer after
hardware reset is completed.

Fixes: bb6b94a ("net: hns3: Add reset interface implementation in client")
Signed-off-by: Yunsheng Lin <[email protected]>
Signed-off-by: Peng Li <[email protected]>
Signed-off-by: Huazhong Tan <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
  • Loading branch information
Yunsheng Lin authored and gregkh committed Jul 26, 2019
1 parent 648e4b6 commit 64db92d
Showing 1 changed file with 14 additions and 5 deletions.
19 changes: 14 additions & 5 deletions drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#define hns3_tx_bd_count(S) DIV_ROUND_UP(S, HNS3_MAX_BD_SIZE)

static void hns3_clear_all_ring(struct hnae3_handle *h);
static void hns3_force_clear_all_rx_ring(struct hnae3_handle *h);
static void hns3_force_clear_all_ring(struct hnae3_handle *h);
static void hns3_remove_hw_addr(struct net_device *netdev);

static const char hns3_driver_name[] = "hns3";
Expand Down Expand Up @@ -491,7 +491,12 @@ static void hns3_nic_net_down(struct net_device *netdev)
/* free irq resources */
hns3_nic_uninit_irq(priv);

hns3_clear_all_ring(priv->ae_handle);
/* delay ring buffer clearing to hns3_reset_notify_uninit_enet
* during reset process, because driver may not be able
* to disable the ring through firmware when downing the netdev.
*/
if (!hns3_nic_resetting(netdev))
hns3_clear_all_ring(priv->ae_handle);
}

static int hns3_nic_net_stop(struct net_device *netdev)
Expand Down Expand Up @@ -3883,7 +3888,7 @@ static void hns3_client_uninit(struct hnae3_handle *handle, bool reset)

hns3_del_all_fd_rules(netdev, true);

hns3_force_clear_all_rx_ring(handle);
hns3_force_clear_all_ring(handle);

hns3_uninit_phy(netdev);

Expand Down Expand Up @@ -4055,14 +4060,17 @@ static void hns3_force_clear_rx_ring(struct hns3_enet_ring *ring)
}
}

static void hns3_force_clear_all_rx_ring(struct hnae3_handle *h)
static void hns3_force_clear_all_ring(struct hnae3_handle *h)
{
struct net_device *ndev = h->kinfo.netdev;
struct hns3_nic_priv *priv = netdev_priv(ndev);
struct hns3_enet_ring *ring;
u32 i;

for (i = 0; i < h->kinfo.num_tqps; i++) {
ring = priv->ring_data[i].ring;
hns3_clear_tx_ring(ring);

ring = priv->ring_data[i + h->kinfo.num_tqps].ring;
hns3_force_clear_rx_ring(ring);
}
Expand Down Expand Up @@ -4297,7 +4305,8 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)
return 0;
}

hns3_force_clear_all_rx_ring(handle);
hns3_clear_all_ring(handle);
hns3_force_clear_all_ring(handle);

hns3_nic_uninit_vector_data(priv);

Expand Down

0 comments on commit 64db92d

Please sign in to comment.