Commit fc02bf35 authored by Heiner Kallweit's avatar Heiner Kallweit Committed by sanglipeng
Browse files

r8169: disable ASPM in case of tx timeout

stable inclusion
from stable-v5.10.203
commit b29e6055db1eae2ace70cbe75cbe36385754a958
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I9GXII

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=b29e6055db1eae2ace70cbe75cbe36385754a958



--------------------------------

[ Upstream commit 80c0576e ]

There are still single reports of systems where ASPM incompatibilities
cause tx timeouts. It's not clear whom to blame, so let's disable
ASPM in case of a tx timeout.

v2:
- add one-time warning for informing the user

Signed-off-by: default avatarHeiner Kallweit <hkallweit1@gmail.com>
Reviewed-by: default avatarAlexander Duyck <alexanderduyck@fb.com>
Link: https://lore.kernel.org/r/92369a92-dc32-4529-0509-11459ba0e391@gmail.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Stable-dep-of: 59d395ed606d ("r8169: fix deadlock on RTL8125 in jumbo mtu mode")
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarsanglipeng <sanglipeng1@jd.com>
parent 99ac6bae
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -582,6 +582,7 @@ struct rtl8169_tc_offsets {
enum rtl_flag {
	RTL_FLAG_TASK_ENABLED = 0,
	RTL_FLAG_TASK_RESET_PENDING,
	RTL_FLAG_TASK_TX_TIMEOUT,
	RTL_FLAG_MAX
};

@@ -4042,7 +4043,7 @@ static void rtl8169_tx_timeout(struct net_device *dev, unsigned int txqueue)
{
	struct rtl8169_private *tp = netdev_priv(dev);

	rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
	rtl_schedule_task(tp, RTL_FLAG_TASK_TX_TIMEOUT);
}

static int rtl8169_tx_map(struct rtl8169_private *tp, const u32 *opts, u32 len,
@@ -4662,6 +4663,7 @@ static void rtl_task(struct work_struct *work)
{
	struct rtl8169_private *tp =
		container_of(work, struct rtl8169_private, wk.work);
	int ret;

	rtnl_lock();

@@ -4669,7 +4671,17 @@ static void rtl_task(struct work_struct *work)
	    !test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
		goto out_unlock;

	if (test_and_clear_bit(RTL_FLAG_TASK_TX_TIMEOUT, tp->wk.flags)) {
		/* ASPM compatibility issues are a typical reason for tx timeouts */
		ret = pci_disable_link_state(tp->pci_dev, PCIE_LINK_STATE_L1 |
							  PCIE_LINK_STATE_L0S);
		if (!ret)
			netdev_warn_once(tp->dev, "ASPM disabled on Tx timeout\n");
		goto reset;
	}

	if (test_and_clear_bit(RTL_FLAG_TASK_RESET_PENDING, tp->wk.flags)) {
reset:
		rtl_reset_work(tp);
		netif_wake_queue(tp->dev);
	}