Commit 8138fc46 authored by Paolo Abeni's avatar Paolo Abeni
Browse files

Merge branch 'introduce-and-use-netif_xmit_timeout_ms-helper'

Tariq Toukan says:

====================
Introduce and use netif_xmit_timeout_ms() helper

This is V2, find V1 here:
https://lore.kernel.org/all/1764054776-1308696-1-git-send-email-tariqt@nvidia.com/

This series by Shahar introduces a new helper function
netif_xmit_timeout_ms() to check if a TX queue has timed out and report
the timeout duration.
It also encapsulates the check for whether the TX queue is stopped.

Replace duplicated open-coded timeout check in hns3 driver with the new
helper.

For mlx5e, refine the TX timeout recovery flow to act only on SQs whose
transmit timestamp indicates an actual timeout, as determined by the
helper. This prevents unnecessary channel reopen events caused by
attempting recovery on queues that are merely stopped but not truly
timed out.
====================

Link: https://patch.msgid.link/1768209383-1546791-1-git-send-email-tariqt@nvidia.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents cc75d437 b0ba7345
Loading
Loading
Loading
Loading
+5 −7
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <net/tcp.h>
#include <net/vxlan.h>
#include <net/geneve.h>
#include <net/netdev_queues.h>

#include "hnae3.h"
#include "hns3_enet.h"
@@ -2807,14 +2808,12 @@ static int hns3_get_timeout_queue(struct net_device *ndev)

	/* Find the stopped queue the same way the stack does */
	for (i = 0; i < ndev->num_tx_queues; i++) {
		unsigned int timedout_ms;
		struct netdev_queue *q;
		unsigned long trans_start;

		q = netdev_get_tx_queue(ndev, i);
		trans_start = READ_ONCE(q->trans_start);
		if (netif_xmit_stopped(q) &&
		    time_after(jiffies,
			       (trans_start + ndev->watchdog_timeo))) {
		timedout_ms = netif_xmit_timeout_ms(q);
		if (timedout_ms) {
#ifdef CONFIG_BQL
			struct dql *dql = &q->dql;

@@ -2823,8 +2822,7 @@ static int hns3_get_timeout_queue(struct net_device *ndev)
				    dql->adj_limit, dql->num_completed);
#endif
			netdev_info(ndev, "queue state: 0x%lx, delta msecs: %u\n",
				    q->state,
				    jiffies_to_msecs(jiffies - trans_start));
				    q->state, timedout_ms);
			break;
		}
	}
+1 −1
Original line number Diff line number Diff line
@@ -5137,7 +5137,7 @@ static void mlx5e_tx_timeout_work(struct work_struct *work)
			netdev_get_tx_queue(netdev, i);
		struct mlx5e_txqsq *sq = priv->txq2sq[i];

		if (!netif_xmit_stopped(dev_queue))
		if (!netif_xmit_timeout_ms(dev_queue))
			continue;

		if (mlx5e_reporter_tx_timeout(sq))
+11 −0
Original line number Diff line number Diff line
@@ -310,6 +310,17 @@ static inline void netif_subqueue_sent(const struct net_device *dev,
	netdev_tx_sent_queue(txq, bytes);
}

static inline unsigned int netif_xmit_timeout_ms(struct netdev_queue *txq)
{
	unsigned long trans_start = READ_ONCE(txq->trans_start);

	if (netif_xmit_stopped(txq) &&
	    time_after(jiffies, trans_start + txq->dev->watchdog_timeo))
		return jiffies_to_msecs(jiffies - trans_start);

	return 0;
}

#define netif_subqueue_maybe_stop(dev, idx, get_desc, stop_thrs, start_thrs) \
	({								\
		struct netdev_queue *_txq;				\