[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <e9e7c7e188f941fca362bbe012014eec@AcuMS.aculab.com>
Date: Tue, 21 Jun 2022 08:29:36 +0000
From: David Laight <David.Laight@...LAB.COM>
To: 'Jose Alonso' <joalonsof@...il.com>,
"netdev@...r.kernel.org" <netdev@...r.kernel.org>
CC: 'Eric Dumazet' <edumazet@...gle.com>
Subject: RE: [PATCH v2] net: usb: ax88179_178a: ax88179_rx_fixup corrections
From: Jose Alonso
> Sent: 21 June 2022 02:19
>
>
> On Mon, 2022-06-20 at 03:45 +0000, David Laight wrote:
> >
> > > - ax_skb->truesize = pkt_len + sizeof(struct sk_buff);
> >
> > You've 'lost' this lie.
> > IIRC the 'skb' are allocated with 64k buffer space.
> > I'm not at all sure how the buffer space of skb that are cloned
> > into multiple rx buffers are supposed to be accounted for.
> >
> > Does this driver ever copy the data for short frames?
>
> The driver receives a skb with a URB (dev->rx_urb_size=24576)
> with N packets and do skb->clone for the N-1 first packets and
> for the last return the skb received.
> The usb transfer uses bulk io of 512 bytes (dev->maxpacket).
> skb_clone creates a new sk_buff sharing the same skb->data avoiding
> extra copy of the packets and the URB area will be released when
> all packets were processed (reference count = 0).
> The length of rx queue is setted by usbnet:
> #define MAX_QUEUE_MEMORY (60 * 1518)
> ...
> case USB_SPEED_HIGH:
> dev->rx_qlen = MAX_QUEUE_MEMORY / dev->rx_urb_size;
> dev->tx_qlen = MAX_QUEUE_MEMORY / dev->hard_mtu;
> break;
> case USB_SPEED_SUPER:
> case USB_SPEED_SUPER_PLUS:
> ...
> dev->rx_qlen = 5 * MAX_QUEUE_MEMORY / dev->rx_urb_size;
> dev->tx_qlen = 5 * MAX_QUEUE_MEMORY / dev->hard_mtu;
>
That's about what I remember it doing when I looked a few years back.
It is horrid....
I also ended up finding quite a few bugs in the xhci driver.
So what actually happens is a 91080 byte linear skb is allocated.
This has a 'truesize' that depends on the allocator, probably 96k.
The usb data (a sequence of 1k packets on USB3) is copied into
the skb buffer area, moving to the next buffer if a short USB
buffer is received.
Each time the skb is cloned each copy still has the original 'truesize'.
So when queued on a socket each use 96k+ of the receive buffer size.
This is absolutely right when only a single ethernet frame is in
the USB packet - even if it contains one character of a terminal session.
However it will definitely break the user expectations.
Setting ax_skb->truesize to a short length fixes the 'user expectation'
but really bloats kernel memory use.
Most ethernet drivers now put buffers (not skb) into the receive ring
and will copy short (<100 byte) frames so that the buffers can be
reused.
With 90k skb copying everything (except a big GRO packet) is
probably the only sane way to account for kernel memory.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
Powered by blists - more mailing lists