34d2964554
Fixes issues with RTL8156 2.5G USB adapters - # ethtool eth1 Settings for eth1: Supported ports: [ ] Supported link modes: Not reported Supported pause frame use: No Supports auto-negotiation: No Supported FEC modes: Not reported Advertised link modes: Not reported Advertised pause frame use: No Advertised auto-negotiation: No Advertised FEC modes: Not reported Speed: 2500Mb/s Duplex: Half Port: Twisted Pair PHYAD: 0 Transceiver: internal Auto-negotiation: off MDI-X: Unknown Current message level: 0x00000007 (7) drv probe link Link detected: yes - # - r8152: break the loop when the budget is exhausted - r8152: Block future register access if register access fails - r8152: Rename RTL8152_UNPLUG to RTL8152_INACCESSIBLE - r8152: add vendor/device ID pair for D-Link DUB-E250 - r8152: try to use a normal budget - r8152: set bp in bulk - r8152: adjust generic_ocp_write function - r8152: fix the autosuspend doesn't work - r8152: Add __GFP_NOWARN to big allocations - r8152: reduce the control transfer of rtl8152_get_version() - r8152: remove rtl_vendor_mode function - r8152: avoid to change cfg for all devices - r8152: add USB device driver for config selection - r8152: use napi_gro_frags - cdc_ether: no need to blacklist any r8152 devices - cdc_ether: add u-blox 0x1313 composition Build system: x86_64 Build-tested: bcm2711, rockchip, x86/64 Run-tested: bcm2711/RPi4B, rockchip/nanopi r2s, x86/64 Signed-off-by: Marty Jones <mj8263788@gmail.com>
84 lines
2.9 KiB
Diff
84 lines
2.9 KiB
Diff
From 66eee612a1ba39f9a76a9ace4a34d012044767fb Mon Sep 17 00:00:00 2001
|
|
From: Hayes Wang <hayeswang@realtek.com>
|
|
Date: Tue, 26 Sep 2023 19:17:13 +0800
|
|
Subject: [PATCH] r8152: break the loop when the budget is exhausted
|
|
|
|
[ Upstream commit 2cf51f931797d9a47e75d999d0993a68cbd2a560 ]
|
|
|
|
A bulk transfer of the USB may contain many packets. And, the total
|
|
number of the packets in the bulk transfer may be more than budget.
|
|
|
|
Originally, only budget packets would be handled by napi_gro_receive(),
|
|
and the other packets would be queued in the driver for next schedule.
|
|
|
|
This patch would break the loop about getting next bulk transfer, when
|
|
the budget is exhausted. That is, only the current bulk transfer would
|
|
be handled, and the other bulk transfers would be queued for next
|
|
schedule. Besides, the packets which are more than the budget in the
|
|
current bulk trasnfer would be still queued in the driver, as the
|
|
original method.
|
|
|
|
In addition, a bulk transfer wouldn't contain more than 400 packets, so
|
|
the check of queue length is unnecessary. Therefore, I replace it with
|
|
WARN_ON_ONCE().
|
|
|
|
Fixes: cf74eb5a5bc8 ("eth: r8152: try to use a normal budget")
|
|
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
|
|
Link: https://lore.kernel.org/r/20230926111714.9448-433-nic_swsd@realtek.com
|
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
Signed-off-by: Sasha Levin <sashal@kernel.org>
|
|
---
|
|
drivers/net/usb/r8152.c | 18 +++++++++++++-----
|
|
1 file changed, 13 insertions(+), 5 deletions(-)
|
|
|
|
--- a/drivers/net/usb/r8152.c
|
|
+++ b/drivers/net/usb/r8152.c
|
|
@@ -2542,7 +2542,7 @@ static int rx_bottom(struct r8152 *tp, i
|
|
}
|
|
}
|
|
|
|
- if (list_empty(&tp->rx_done))
|
|
+ if (list_empty(&tp->rx_done) || work_done >= budget)
|
|
goto out1;
|
|
|
|
clear_bit(RX_EPROTO, &tp->flags);
|
|
@@ -2558,6 +2558,15 @@ static int rx_bottom(struct r8152 *tp, i
|
|
struct urb *urb;
|
|
u8 *rx_data;
|
|
|
|
+ /* A bulk transfer of USB may contain may packets, so the
|
|
+ * total packets may more than the budget. Deal with all
|
|
+ * packets in current bulk transfer, and stop to handle the
|
|
+ * next bulk transfer until next schedule, if budget is
|
|
+ * exhausted.
|
|
+ */
|
|
+ if (work_done >= budget)
|
|
+ break;
|
|
+
|
|
list_del_init(cursor);
|
|
|
|
agg = list_entry(cursor, struct rx_agg, list);
|
|
@@ -2577,9 +2586,7 @@ static int rx_bottom(struct r8152 *tp, i
|
|
unsigned int pkt_len, rx_frag_head_sz;
|
|
struct sk_buff *skb;
|
|
|
|
- /* limit the skb numbers for rx_queue */
|
|
- if (unlikely(skb_queue_len(&tp->rx_queue) >= 1000))
|
|
- break;
|
|
+ WARN_ON_ONCE(skb_queue_len(&tp->rx_queue) >= 1000);
|
|
|
|
pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
|
|
if (pkt_len < ETH_ZLEN)
|
|
@@ -2657,9 +2664,10 @@ submit:
|
|
}
|
|
}
|
|
|
|
+ /* Splice the remained list back to rx_done for next schedule */
|
|
if (!list_empty(&rx_queue)) {
|
|
spin_lock_irqsave(&tp->rx_lock, flags);
|
|
- list_splice_tail(&rx_queue, &tp->rx_done);
|
|
+ list_splice(&rx_queue, &tp->rx_done);
|
|
spin_unlock_irqrestore(&tp->rx_lock, flags);
|
|
}
|
|
|