Skip to content

Commit f8fa222

Browse files
321lipengdavem330
authored andcommitted
net: hns3: Add timeout process in hns3_enet
This patch add timeout handler in hns3_enet.c to handle TX side timeout event, when TX timeout event occur, it will triger NIC driver into reset process. Signed-off-by: qumingguang <[email protected]> Signed-off-by: Lipeng <[email protected]> Signed-off-by: Yunsheng Lin <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 4ed340a commit f8fa222

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ static int hns3_nic_net_up(struct net_device *netdev)
258258

259259
static int hns3_nic_net_open(struct net_device *netdev)
260260
{
261+
struct hns3_nic_priv *priv = netdev_priv(netdev);
261262
int ret;
262263

263264
netif_carrier_off(netdev);
@@ -273,6 +274,7 @@ static int hns3_nic_net_open(struct net_device *netdev)
273274
return ret;
274275
}
275276

277+
priv->last_reset_time = jiffies;
276278
return 0;
277279
}
278280

@@ -1322,10 +1324,91 @@ static int hns3_nic_change_mtu(struct net_device *netdev, int new_mtu)
13221324
return ret;
13231325
}
13241326

1327+
static bool hns3_get_tx_timeo_queue_info(struct net_device *ndev)
1328+
{
1329+
struct hns3_nic_priv *priv = netdev_priv(ndev);
1330+
struct hns3_enet_ring *tx_ring = NULL;
1331+
int timeout_queue = 0;
1332+
int hw_head, hw_tail;
1333+
int i;
1334+
1335+
/* Find the stopped queue the same way the stack does */
1336+
for (i = 0; i < ndev->real_num_tx_queues; i++) {
1337+
struct netdev_queue *q;
1338+
unsigned long trans_start;
1339+
1340+
q = netdev_get_tx_queue(ndev, i);
1341+
trans_start = q->trans_start;
1342+
if (netif_xmit_stopped(q) &&
1343+
time_after(jiffies,
1344+
(trans_start + ndev->watchdog_timeo))) {
1345+
timeout_queue = i;
1346+
break;
1347+
}
1348+
}
1349+
1350+
if (i == ndev->num_tx_queues) {
1351+
netdev_info(ndev,
1352+
"no netdev TX timeout queue found, timeout count: %llu\n",
1353+
priv->tx_timeout_count);
1354+
return false;
1355+
}
1356+
1357+
tx_ring = priv->ring_data[timeout_queue].ring;
1358+
1359+
hw_head = readl_relaxed(tx_ring->tqp->io_base +
1360+
HNS3_RING_TX_RING_HEAD_REG);
1361+
hw_tail = readl_relaxed(tx_ring->tqp->io_base +
1362+
HNS3_RING_TX_RING_TAIL_REG);
1363+
netdev_info(ndev,
1364+
"tx_timeout count: %llu, queue id: %d, SW_NTU: 0x%x, SW_NTC: 0x%x, HW_HEAD: 0x%x, HW_TAIL: 0x%x, INT: 0x%x\n",
1365+
priv->tx_timeout_count,
1366+
timeout_queue,
1367+
tx_ring->next_to_use,
1368+
tx_ring->next_to_clean,
1369+
hw_head,
1370+
hw_tail,
1371+
readl(tx_ring->tqp_vector->mask_addr));
1372+
1373+
return true;
1374+
}
1375+
1376+
static void hns3_nic_net_timeout(struct net_device *ndev)
1377+
{
1378+
struct hns3_nic_priv *priv = netdev_priv(ndev);
1379+
unsigned long last_reset_time = priv->last_reset_time;
1380+
struct hnae3_handle *h = priv->ae_handle;
1381+
1382+
if (!hns3_get_tx_timeo_queue_info(ndev))
1383+
return;
1384+
1385+
priv->tx_timeout_count++;
1386+
1387+
/* This timeout is far away enough from last timeout,
1388+
* if timeout again,set the reset type to PF reset
1389+
*/
1390+
if (time_after(jiffies, (last_reset_time + 20 * HZ)))
1391+
priv->reset_level = HNAE3_FUNC_RESET;
1392+
1393+
/* Don't do any new action before the next timeout */
1394+
else if (time_before(jiffies, (last_reset_time + ndev->watchdog_timeo)))
1395+
return;
1396+
1397+
priv->last_reset_time = jiffies;
1398+
1399+
if (h->ae_algo->ops->reset_event)
1400+
h->ae_algo->ops->reset_event(h, priv->reset_level);
1401+
1402+
priv->reset_level++;
1403+
if (priv->reset_level > HNAE3_GLOBAL_RESET)
1404+
priv->reset_level = HNAE3_GLOBAL_RESET;
1405+
}
1406+
13251407
static const struct net_device_ops hns3_nic_netdev_ops = {
13261408
.ndo_open = hns3_nic_net_open,
13271409
.ndo_stop = hns3_nic_net_stop,
13281410
.ndo_start_xmit = hns3_nic_net_xmit,
1411+
.ndo_tx_timeout = hns3_nic_net_timeout,
13291412
.ndo_set_mac_address = hns3_nic_net_set_mac_address,
13301413
.ndo_change_mtu = hns3_nic_change_mtu,
13311414
.ndo_set_features = hns3_nic_set_features,
@@ -2763,6 +2846,9 @@ static int hns3_client_init(struct hnae3_handle *handle)
27632846
priv->dev = &pdev->dev;
27642847
priv->netdev = netdev;
27652848
priv->ae_handle = handle;
2849+
priv->last_reset_time = jiffies;
2850+
priv->reset_level = HNAE3_FUNC_RESET;
2851+
priv->tx_timeout_count = 0;
27662852

27672853
handle->kinfo.netdev = netdev;
27682854
handle->priv = (void *)priv;

drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,8 @@ struct hns3_nic_priv {
518518
/* The most recently read link state */
519519
int link;
520520
u64 tx_timeout_count;
521+
enum hnae3_reset_type reset_level;
522+
unsigned long last_reset_time;
521523

522524
unsigned long state;
523525

0 commit comments

Comments
 (0)