Skip to content

Commit d2187f8

Browse files
hayesorzdavem330
authored andcommitted
r8152: divide the tx and rx bottom functions
Move the tx bottom function from NAPI to a new tasklet. Then, for multi-cores, the bottom functions of tx and rx may be run at same time with different cores. This is used to improve performance. On x86, Tx/Rx 943/943 Mbits/sec -> 945/944. For arm platform, Tx/Rx: 917/917 Mbits/sec -> 933/933. Signed-off-by: Hayes Wang <hayeswang@realtek.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 932630f commit d2187f8

File tree

1 file changed

+26
-13
lines changed

1 file changed

+26
-13
lines changed

drivers/net/usb/r8152.c

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@ enum rtl8152_flags {
619619
RTL8152_LINK_CHG,
620620
SELECTIVE_SUSPEND,
621621
PHY_RESET,
622-
SCHEDULE_NAPI,
622+
SCHEDULE_TASKLET,
623623
GREEN_ETHERNET,
624624
DELL_TB_RX_AGG_BUG,
625625
};
@@ -733,6 +733,7 @@ struct r8152 {
733733
#ifdef CONFIG_PM_SLEEP
734734
struct notifier_block pm_notifier;
735735
#endif
736+
struct tasklet_struct tx_tl;
736737

737738
struct rtl_ops {
738739
void (*init)(struct r8152 *);
@@ -1401,7 +1402,7 @@ static void write_bulk_callback(struct urb *urb)
14011402
return;
14021403

14031404
if (!skb_queue_empty(&tp->tx_queue))
1404-
napi_schedule(&tp->napi);
1405+
tasklet_schedule(&tp->tx_tl);
14051406
}
14061407

14071408
static void intr_callback(struct urb *urb)
@@ -2179,8 +2180,12 @@ static void tx_bottom(struct r8152 *tp)
21792180
} while (res == 0);
21802181
}
21812182

2182-
static void bottom_half(struct r8152 *tp)
2183+
static void bottom_half(unsigned long data)
21832184
{
2185+
struct r8152 *tp;
2186+
2187+
tp = (struct r8152 *)data;
2188+
21842189
if (test_bit(RTL8152_UNPLUG, &tp->flags))
21852190
return;
21862191

@@ -2192,7 +2197,7 @@ static void bottom_half(struct r8152 *tp)
21922197
if (!netif_carrier_ok(tp->netdev))
21932198
return;
21942199

2195-
clear_bit(SCHEDULE_NAPI, &tp->flags);
2200+
clear_bit(SCHEDULE_TASKLET, &tp->flags);
21962201

21972202
tx_bottom(tp);
21982203
}
@@ -2203,16 +2208,12 @@ static int r8152_poll(struct napi_struct *napi, int budget)
22032208
int work_done;
22042209

22052210
work_done = rx_bottom(tp, budget);
2206-
bottom_half(tp);
22072211

22082212
if (work_done < budget) {
22092213
if (!napi_complete_done(napi, work_done))
22102214
goto out;
22112215
if (!list_empty(&tp->rx_done))
22122216
napi_schedule(napi);
2213-
else if (!skb_queue_empty(&tp->tx_queue) &&
2214-
!list_empty(&tp->tx_free))
2215-
napi_schedule(napi);
22162217
}
22172218

22182219
out:
@@ -2366,11 +2367,11 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,
23662367

23672368
if (!list_empty(&tp->tx_free)) {
23682369
if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
2369-
set_bit(SCHEDULE_NAPI, &tp->flags);
2370+
set_bit(SCHEDULE_TASKLET, &tp->flags);
23702371
schedule_delayed_work(&tp->schedule, 0);
23712372
} else {
23722373
usb_mark_last_busy(tp->udev);
2373-
napi_schedule(&tp->napi);
2374+
tasklet_schedule(&tp->tx_tl);
23742375
}
23752376
} else if (skb_queue_len(&tp->tx_queue) > tp->tx_qlen) {
23762377
netif_stop_queue(netdev);
@@ -4020,9 +4021,11 @@ static void set_carrier(struct r8152 *tp)
40204021
} else {
40214022
if (netif_carrier_ok(netdev)) {
40224023
netif_carrier_off(netdev);
4024+
tasklet_disable(&tp->tx_tl);
40234025
napi_disable(napi);
40244026
tp->rtl_ops.disable(tp);
40254027
napi_enable(napi);
4028+
tasklet_enable(&tp->tx_tl);
40264029
netif_info(tp, link, netdev, "carrier off\n");
40274030
}
40284031
}
@@ -4055,10 +4058,10 @@ static void rtl_work_func_t(struct work_struct *work)
40554058
if (test_and_clear_bit(RTL8152_SET_RX_MODE, &tp->flags))
40564059
_rtl8152_set_rx_mode(tp->netdev);
40574060

4058-
/* don't schedule napi before linking */
4059-
if (test_and_clear_bit(SCHEDULE_NAPI, &tp->flags) &&
4061+
/* don't schedule tasket before linking */
4062+
if (test_and_clear_bit(SCHEDULE_TASKLET, &tp->flags) &&
40604063
netif_carrier_ok(tp->netdev))
4061-
napi_schedule(&tp->napi);
4064+
tasklet_schedule(&tp->tx_tl);
40624065

40634066
mutex_unlock(&tp->control);
40644067

@@ -4144,6 +4147,7 @@ static int rtl8152_open(struct net_device *netdev)
41444147
goto out_unlock;
41454148
}
41464149
napi_enable(&tp->napi);
4150+
tasklet_enable(&tp->tx_tl);
41474151

41484152
mutex_unlock(&tp->control);
41494153

@@ -4171,6 +4175,7 @@ static int rtl8152_close(struct net_device *netdev)
41714175
#ifdef CONFIG_PM_SLEEP
41724176
unregister_pm_notifier(&tp->pm_notifier);
41734177
#endif
4178+
tasklet_disable(&tp->tx_tl);
41744179
if (!test_bit(RTL8152_UNPLUG, &tp->flags))
41754180
napi_disable(&tp->napi);
41764181
clear_bit(WORK_ENABLE, &tp->flags);
@@ -4440,6 +4445,7 @@ static int rtl8152_pre_reset(struct usb_interface *intf)
44404445
return 0;
44414446

44424447
netif_stop_queue(netdev);
4448+
tasklet_disable(&tp->tx_tl);
44434449
napi_disable(&tp->napi);
44444450
clear_bit(WORK_ENABLE, &tp->flags);
44454451
usb_kill_urb(tp->intr_urb);
@@ -4483,6 +4489,7 @@ static int rtl8152_post_reset(struct usb_interface *intf)
44834489
}
44844490

44854491
napi_enable(&tp->napi);
4492+
tasklet_enable(&tp->tx_tl);
44864493
netif_wake_queue(netdev);
44874494
usb_submit_urb(tp->intr_urb, GFP_KERNEL);
44884495

@@ -4636,10 +4643,12 @@ static int rtl8152_system_suspend(struct r8152 *tp)
46364643

46374644
clear_bit(WORK_ENABLE, &tp->flags);
46384645
usb_kill_urb(tp->intr_urb);
4646+
tasklet_disable(&tp->tx_tl);
46394647
napi_disable(napi);
46404648
cancel_delayed_work_sync(&tp->schedule);
46414649
tp->rtl_ops.down(tp);
46424650
napi_enable(napi);
4651+
tasklet_enable(&tp->tx_tl);
46434652
}
46444653

46454654
return 0;
@@ -5499,6 +5508,8 @@ static int rtl8152_probe(struct usb_interface *intf,
54995508
mutex_init(&tp->control);
55005509
INIT_DELAYED_WORK(&tp->schedule, rtl_work_func_t);
55015510
INIT_DELAYED_WORK(&tp->hw_phy_work, rtl_hw_phy_work_func_t);
5511+
tasklet_init(&tp->tx_tl, bottom_half, (unsigned long)tp);
5512+
tasklet_disable(&tp->tx_tl);
55025513

55035514
netdev->netdev_ops = &rtl8152_netdev_ops;
55045515
netdev->watchdog_timeo = RTL8152_TX_TIMEOUT;
@@ -5585,6 +5596,7 @@ static int rtl8152_probe(struct usb_interface *intf,
55855596

55865597
out1:
55875598
netif_napi_del(&tp->napi);
5599+
tasklet_kill(&tp->tx_tl);
55885600
usb_set_intfdata(intf, NULL);
55895601
out:
55905602
free_netdev(netdev);
@@ -5601,6 +5613,7 @@ static void rtl8152_disconnect(struct usb_interface *intf)
56015613

56025614
netif_napi_del(&tp->napi);
56035615
unregister_netdev(tp->netdev);
5616+
tasklet_kill(&tp->tx_tl);
56045617
cancel_delayed_work_sync(&tp->hw_phy_work);
56055618
tp->rtl_ops.unload(tp);
56065619
free_netdev(tp->netdev);

0 commit comments

Comments
 (0)