kernel: backport fixes for realtek r8152
[openwrt/openwrt.git] / target / linux / generic / backport-6.1 / 795-v6.6-14-r8152-break-the-loop-when-the-budget-is-exhausted.patch
1 From 66eee612a1ba39f9a76a9ace4a34d012044767fb Mon Sep 17 00:00:00 2001
2 From: Hayes Wang <hayeswang@realtek.com>
3 Date: Tue, 26 Sep 2023 19:17:13 +0800
4 Subject: [PATCH] r8152: break the loop when the budget is exhausted
5
6 [ Upstream commit 2cf51f931797d9a47e75d999d0993a68cbd2a560 ]
7
8 A bulk transfer of the USB may contain many packets. And, the total
9 number of the packets in the bulk transfer may be more than budget.
10
11 Originally, only budget packets would be handled by napi_gro_receive(),
12 and the other packets would be queued in the driver for next schedule.
13
14 This patch would break the loop about getting next bulk transfer, when
15 the budget is exhausted. That is, only the current bulk transfer would
16 be handled, and the other bulk transfers would be queued for next
17 schedule. Besides, the packets which are more than the budget in the
18 current bulk trasnfer would be still queued in the driver, as the
19 original method.
20
21 In addition, a bulk transfer wouldn't contain more than 400 packets, so
22 the check of queue length is unnecessary. Therefore, I replace it with
23 WARN_ON_ONCE().
24
25 Fixes: cf74eb5a5bc8 ("eth: r8152: try to use a normal budget")
26 Signed-off-by: Hayes Wang <hayeswang@realtek.com>
27 Link: https://lore.kernel.org/r/20230926111714.9448-433-nic_swsd@realtek.com
28 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
29 Signed-off-by: Sasha Levin <sashal@kernel.org>
30 ---
31 drivers/net/usb/r8152.c | 18 +++++++++++++-----
32 1 file changed, 13 insertions(+), 5 deletions(-)
33
34 --- a/drivers/net/usb/r8152.c
35 +++ b/drivers/net/usb/r8152.c
36 @@ -2542,7 +2542,7 @@ static int rx_bottom(struct r8152 *tp, i
37 }
38 }
39
40 - if (list_empty(&tp->rx_done))
41 + if (list_empty(&tp->rx_done) || work_done >= budget)
42 goto out1;
43
44 clear_bit(RX_EPROTO, &tp->flags);
45 @@ -2558,6 +2558,15 @@ static int rx_bottom(struct r8152 *tp, i
46 struct urb *urb;
47 u8 *rx_data;
48
49 + /* A bulk transfer of USB may contain may packets, so the
50 + * total packets may more than the budget. Deal with all
51 + * packets in current bulk transfer, and stop to handle the
52 + * next bulk transfer until next schedule, if budget is
53 + * exhausted.
54 + */
55 + if (work_done >= budget)
56 + break;
57 +
58 list_del_init(cursor);
59
60 agg = list_entry(cursor, struct rx_agg, list);
61 @@ -2577,9 +2586,7 @@ static int rx_bottom(struct r8152 *tp, i
62 unsigned int pkt_len, rx_frag_head_sz;
63 struct sk_buff *skb;
64
65 - /* limit the skb numbers for rx_queue */
66 - if (unlikely(skb_queue_len(&tp->rx_queue) >= 1000))
67 - break;
68 + WARN_ON_ONCE(skb_queue_len(&tp->rx_queue) >= 1000);
69
70 pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
71 if (pkt_len < ETH_ZLEN)
72 @@ -2657,9 +2664,10 @@ submit:
73 }
74 }
75
76 + /* Splice the remained list back to rx_done for next schedule */
77 if (!list_empty(&rx_queue)) {
78 spin_lock_irqsave(&tp->rx_lock, flags);
79 - list_splice_tail(&rx_queue, &tp->rx_done);
80 + list_splice(&rx_queue, &tp->rx_done);
81 spin_unlock_irqrestore(&tp->rx_lock, flags);
82 }
83