Commit c92d6089 authored by Mathieu Othacehe's avatar Mathieu Othacehe Committed by Jakub Kicinski
Browse files

net: cadence: macb: Fix a possible deadlock in macb_halt_tx.



There is a situation where after THALT is set high, TGO stays high as
well. Because jiffies are never updated, as we are in a context with
interrupts disabled, we never exit that loop and have a deadlock.

That deadlock was noticed on a sama5d4 device that stayed locked for days.

Use retries instead of jiffies so that the timeout really works and we do
not have a deadlock anymore.

Fixes: e86cd53a ("net/macb: better manage tx errors")
Signed-off-by: default avatarMathieu Othacehe <othacehe@gnu.org>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250509121935.16282-1-othacehe@gnu.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 4d64321c
Loading
Loading
Loading
Loading
+6 −13
Original line number Diff line number Diff line
@@ -997,22 +997,15 @@ static void macb_update_stats(struct macb *bp)

static int macb_halt_tx(struct macb *bp)
{
	unsigned long	halt_time, timeout;
	u32 status;

	macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(THALT));

	timeout = jiffies + usecs_to_jiffies(MACB_HALT_TIMEOUT);
	do {
		halt_time = jiffies;
		status = macb_readl(bp, TSR);
		if (!(status & MACB_BIT(TGO)))
			return 0;

		udelay(250);
	} while (time_before(halt_time, timeout));

	return -ETIMEDOUT;
	/* Poll TSR until TGO is cleared or timeout. */
	return read_poll_timeout_atomic(macb_readl, status,
					!(status & MACB_BIT(TGO)),
					250, MACB_HALT_TIMEOUT, false,
					bp, TSR);
}

static void macb_tx_unmap(struct macb *bp, struct macb_tx_skb *tx_skb, int budget)