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: Heiner Kallweit <hkallweit1@gmail.com> Reviewed-by: Alexander Duyck <alexanderduyck@fb.com> Link: https://lore.kernel.org/r/92369a92-dc32-4529-0509-11459ba0e391@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
62cd667995
commit
80c0576ef1
@ -576,6 +576,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
|
||||
};
|
||||
|
||||
@ -3931,7 +3932,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,
|
||||
@ -4525,6 +4526,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();
|
||||
|
||||
@ -4532,7 +4534,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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user