Commit 80c0576e authored by Heiner Kallweit's avatar Heiner Kallweit Committed by Jakub Kicinski

r8169: disable ASPM in case of tx timeout

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.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 62cd6679
...@@ -576,6 +576,7 @@ struct rtl8169_tc_offsets { ...@@ -576,6 +576,7 @@ struct rtl8169_tc_offsets {
enum rtl_flag { enum rtl_flag {
RTL_FLAG_TASK_ENABLED = 0, RTL_FLAG_TASK_ENABLED = 0,
RTL_FLAG_TASK_RESET_PENDING, RTL_FLAG_TASK_RESET_PENDING,
RTL_FLAG_TASK_TX_TIMEOUT,
RTL_FLAG_MAX RTL_FLAG_MAX
}; };
...@@ -3931,7 +3932,7 @@ static void rtl8169_tx_timeout(struct net_device *dev, unsigned int txqueue) ...@@ -3931,7 +3932,7 @@ static void rtl8169_tx_timeout(struct net_device *dev, unsigned int txqueue)
{ {
struct rtl8169_private *tp = netdev_priv(dev); 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, static int rtl8169_tx_map(struct rtl8169_private *tp, const u32 *opts, u32 len,
...@@ -4525,6 +4526,7 @@ static void rtl_task(struct work_struct *work) ...@@ -4525,6 +4526,7 @@ static void rtl_task(struct work_struct *work)
{ {
struct rtl8169_private *tp = struct rtl8169_private *tp =
container_of(work, struct rtl8169_private, wk.work); container_of(work, struct rtl8169_private, wk.work);
int ret;
rtnl_lock(); rtnl_lock();
...@@ -4532,7 +4534,17 @@ static void rtl_task(struct work_struct *work) ...@@ -4532,7 +4534,17 @@ static void rtl_task(struct work_struct *work)
!test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags)) !test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
goto out_unlock; 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)) { if (test_and_clear_bit(RTL_FLAG_TASK_RESET_PENDING, tp->wk.flags)) {
reset:
rtl_reset_work(tp); rtl_reset_work(tp);
netif_wake_queue(tp->dev); netif_wake_queue(tp->dev);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment