Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: cdc_ncm: set reasonable padding limits

We pad frames larger than X to maximum size for devices which
don't need a ZLP after maximum sized frames. This allows the
device to optimize its transfers for one fixed buffer size.

X was arbitrarily set at 512 bytes regardless of real buffer
maximum, causing extreme overheads due to excessive padding of
larger tx buffers. Limit the padding to at most 3 full USB
packets, still allowing the overhead to payload ratio of 3/1.

Signed-off-by: Bjørn Mork <bjorn@mork.no>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Bjørn Mork and committed by
David S. Miller
43e4c6df 70559b89

+7 -2
+6 -2
drivers/net/usb/cdc_ncm.c
··· 213 213 214 214 /* max qlen depend on hard_mtu and rx_urb_size */ 215 215 usbnet_update_max_qlen(dev); 216 + 217 + /* never pad more than 3 full USB packets per transfer */ 218 + ctx->min_tx_pkt = clamp_t(u16, ctx->tx_max - 3 * usb_maxpacket(dev->udev, dev->out, 1), 219 + CDC_NCM_MIN_TX_PKT, ctx->tx_max); 216 220 } 217 221 218 222 /* helpers for NCM and MBIM differences */ ··· 951 947 /* variables will be reset at next call */ 952 948 } 953 949 954 - /* If collected data size is less or equal CDC_NCM_MIN_TX_PKT 950 + /* If collected data size is less or equal ctx->min_tx_pkt 955 951 * bytes, we send buffers as it is. If we get more data, it 956 952 * would be more efficient for USB HS mobile device with DMA 957 953 * engine to receive a full size NTB, than canceling DMA ··· 961 957 * a ZLP after full sized NTBs. 962 958 */ 963 959 if (!(dev->driver_info->flags & FLAG_SEND_ZLP) && 964 - skb_out->len > CDC_NCM_MIN_TX_PKT) 960 + skb_out->len > ctx->min_tx_pkt) 965 961 memset(skb_put(skb_out, ctx->tx_max - skb_out->len), 0, 966 962 ctx->tx_max - skb_out->len); 967 963 else if (skb_out->len < ctx->tx_max && (skb_out->len % dev->maxpacket) == 0)
+1
include/linux/usb/cdc_ncm.h
··· 115 115 u16 tx_seq; 116 116 u16 rx_seq; 117 117 u16 connected; 118 + u16 min_tx_pkt; 118 119 }; 119 120 120 121 u8 cdc_ncm_select_altsetting(struct usb_interface *intf);