Skip to content

Commit 41294e6

Browse files
hkallweitkuba-moo
authored andcommitted
r8169: improve rtl8169_start_xmit
Improve the following in rtl8169_start_xmit: - tp->cur_tx can be accessed in parallel by rtl_tx(), therefore annotate the race by using WRITE_ONCE - avoid checking stop_queue a second time by moving the doorbell check - netif_stop_queue() uses atomic operation set_bit() that includes a full memory barrier on some platforms, therefore use smp_mb__after_atomic to avoid overhead Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> Link: https://lore.kernel.org/r/80085451-3eaf-507a-c7c0-08d607c46fbc@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 0064c5c commit 41294e6

File tree

1 file changed

+6
-9
lines changed

1 file changed

+6
-9
lines changed

drivers/net/ethernet/realtek/r8169_main.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4226,7 +4226,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
42264226
/* rtl_tx needs to see descriptor changes before updated tp->cur_tx */
42274227
smp_wmb();
42284228

4229-
tp->cur_tx += frags + 1;
4229+
WRITE_ONCE(tp->cur_tx, tp->cur_tx + frags + 1);
42304230

42314231
stop_queue = !rtl_tx_slots_avail(tp, MAX_SKB_FRAGS);
42324232
if (unlikely(stop_queue)) {
@@ -4235,25 +4235,22 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
42354235
*/
42364236
smp_wmb();
42374237
netif_stop_queue(dev);
4238-
door_bell = true;
4239-
}
4240-
4241-
if (door_bell)
4242-
rtl8169_doorbell(tp);
4243-
4244-
if (unlikely(stop_queue)) {
42454238
/* Sync with rtl_tx:
42464239
* - publish queue status and cur_tx ring index (write barrier)
42474240
* - refresh dirty_tx ring index (read barrier).
42484241
* May the current thread have a pessimistic view of the ring
42494242
* status and forget to wake up queue, a racing rtl_tx thread
42504243
* can't.
42514244
*/
4252-
smp_mb();
4245+
smp_mb__after_atomic();
42534246
if (rtl_tx_slots_avail(tp, MAX_SKB_FRAGS))
42544247
netif_start_queue(dev);
4248+
door_bell = true;
42554249
}
42564250

4251+
if (door_bell)
4252+
rtl8169_doorbell(tp);
4253+
42574254
return NETDEV_TX_OK;
42584255

42594256
err_dma_1:

0 commit comments

Comments
 (0)