net: usbnet: Add mechanism to throttle usb0 RX traffic in USB SS
ECM traffic is non-aggregated which makes it send huge number of packets in high throughput usecases. This causes the CPU to dedicate majority of the cycles to ISR context and the softIRQ contexts stay suspended. The rx_complete (hardIRQ) keeps adding SKBs to the 'done' list. The usbnet_bh (tasklet) is supposed to dequeue SKBs from 'done' list and provide them to NW stack so that they can be consumed. Because of the above issue, the 'done' list keeps increasing and the system eventually runs out of memory. When the WD_pet task also does not get a chance to run because of hardIRQ storm, WD bite is also observed. Introduce a mechanism to balance the time between hardIRQ and softIRQ contexts. Add module parameter 'usb0_rx_skb_threshold' to stop the submission of URBs to HW from the ISR. This will allow the usbnet_bh to run and consume SKBs, thereby avoiding the OOM scenario and the WD_pet task also gets a chance to pet the WD. The default value of this threshold is 500, which can be changed runtime to suit the requirements according to CPU load. Since in the failing case, ASIX AX88179/178A USB 3.0/2.0 to Gigabit Ethernet adapters are being used, throttle handling has been added in that driver. Usage: echo <threshold> > /sys/module/usbnet/parameters/usb0_rx_skb_threshold Change-Id: I4667f0ad67d5605b132a0e6062be27e01ef75a08 Signed-off-by: Ajay Agarwal <ajaya@codeaurora.org> Signed-off-by: Krishna Kurapati <quic_kriskura@quicinc.com>
This commit is contained in:
parent
9927b09f7f
commit
6da027eb3a
@ -1698,7 +1698,7 @@ static const struct driver_info ax88179_info = {
|
||||
.link_reset = ax88179_link_reset,
|
||||
.reset = ax88179_reset,
|
||||
.stop = ax88179_stop,
|
||||
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
|
||||
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP | FLAG_THROTTLE_RX,
|
||||
.rx_fixup = ax88179_rx_fixup,
|
||||
.tx_fixup = ax88179_tx_fixup,
|
||||
};
|
||||
@ -1711,7 +1711,7 @@ static const struct driver_info ax88178a_info = {
|
||||
.link_reset = ax88179_link_reset,
|
||||
.reset = ax88179_reset,
|
||||
.stop = ax88179_stop,
|
||||
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
|
||||
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP | FLAG_THROTTLE_RX,
|
||||
.rx_fixup = ax88179_rx_fixup,
|
||||
.tx_fixup = ax88179_tx_fixup,
|
||||
};
|
||||
@ -1724,7 +1724,7 @@ static const struct driver_info cypress_GX3_info = {
|
||||
.link_reset = ax88179_link_reset,
|
||||
.reset = ax88179_reset,
|
||||
.stop = ax88179_stop,
|
||||
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
|
||||
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP | FLAG_THROTTLE_RX,
|
||||
.rx_fixup = ax88179_rx_fixup,
|
||||
.tx_fixup = ax88179_tx_fixup,
|
||||
};
|
||||
@ -1737,7 +1737,7 @@ static const struct driver_info dlink_dub1312_info = {
|
||||
.link_reset = ax88179_link_reset,
|
||||
.reset = ax88179_reset,
|
||||
.stop = ax88179_stop,
|
||||
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
|
||||
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP | FLAG_THROTTLE_RX,
|
||||
.rx_fixup = ax88179_rx_fixup,
|
||||
.tx_fixup = ax88179_tx_fixup,
|
||||
};
|
||||
@ -1750,7 +1750,7 @@ static const struct driver_info sitecom_info = {
|
||||
.link_reset = ax88179_link_reset,
|
||||
.reset = ax88179_reset,
|
||||
.stop = ax88179_stop,
|
||||
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
|
||||
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP | FLAG_THROTTLE_RX,
|
||||
.rx_fixup = ax88179_rx_fixup,
|
||||
.tx_fixup = ax88179_tx_fixup,
|
||||
};
|
||||
@ -1763,7 +1763,7 @@ static const struct driver_info samsung_info = {
|
||||
.link_reset = ax88179_link_reset,
|
||||
.reset = ax88179_reset,
|
||||
.stop = ax88179_stop,
|
||||
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
|
||||
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP | FLAG_THROTTLE_RX,
|
||||
.rx_fixup = ax88179_rx_fixup,
|
||||
.tx_fixup = ax88179_tx_fixup,
|
||||
};
|
||||
@ -1776,7 +1776,7 @@ static const struct driver_info lenovo_info = {
|
||||
.link_reset = ax88179_link_reset,
|
||||
.reset = ax88179_reset,
|
||||
.stop = ax88179_stop,
|
||||
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
|
||||
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP | FLAG_THROTTLE_RX,
|
||||
.rx_fixup = ax88179_rx_fixup,
|
||||
.tx_fixup = ax88179_tx_fixup,
|
||||
};
|
||||
@ -1789,7 +1789,7 @@ static const struct driver_info belkin_info = {
|
||||
.link_reset = ax88179_link_reset,
|
||||
.reset = ax88179_reset,
|
||||
.stop = ax88179_stop,
|
||||
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
|
||||
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP | FLAG_THROTTLE_RX,
|
||||
.rx_fixup = ax88179_rx_fixup,
|
||||
.tx_fixup = ax88179_tx_fixup,
|
||||
};
|
||||
|
@ -75,6 +75,10 @@ static int msg_level = -1;
|
||||
module_param (msg_level, int, 0);
|
||||
MODULE_PARM_DESC (msg_level, "Override default message level");
|
||||
|
||||
static int usb0_rx_skb_threshold = 500;
|
||||
module_param(usb0_rx_skb_threshold, int, 0644);
|
||||
MODULE_PARM_DESC(usb0_rx_skb_threshold, "Throttle rx traffic in USB3");
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* handles CDC Ethernet and many other network "bulk data" interfaces */
|
||||
@ -654,9 +658,13 @@ block:
|
||||
if (netif_running (dev->net) &&
|
||||
!test_bit (EVENT_RX_HALT, &dev->flags) &&
|
||||
state != unlink_start) {
|
||||
rx_submit (dev, urb, GFP_ATOMIC);
|
||||
usb_mark_last_busy(dev->udev);
|
||||
return;
|
||||
if ((!(dev->driver_info->flags & FLAG_THROTTLE_RX)) ||
|
||||
((dev->driver_info->flags & FLAG_THROTTLE_RX) &&
|
||||
(dev->done.qlen < usb0_rx_skb_threshold))) {
|
||||
rx_submit(dev, urb, GFP_ATOMIC);
|
||||
usb_mark_last_busy(dev->udev);
|
||||
return;
|
||||
}
|
||||
}
|
||||
usb_free_urb (urb);
|
||||
}
|
||||
|
@ -129,6 +129,7 @@ struct driver_info {
|
||||
#define FLAG_MULTI_PACKET 0x2000
|
||||
#define FLAG_RX_ASSEMBLE 0x4000 /* rx packets may span >1 frames */
|
||||
#define FLAG_NOARP 0x8000 /* device can't do ARP */
|
||||
#define FLAG_THROTTLE_RX 0x10000 /* Throttle RX traffic in USB SS */
|
||||
|
||||
/* init device ... can sleep, or cause probe() failure */
|
||||
int (*bind)(struct usbnet *, struct usb_interface *);
|
||||
|
Loading…
Reference in New Issue
Block a user