diff mbox series

[1/1] Fix qmap header retrieval in qmimux_rx_fixup

Message ID 1545394043-22756-1-git-send-email-dnlplm@gmail.com
State Accepted, archived
Delegated to: David Miller
Headers show
Series [1/1] Fix qmap header retrieval in qmimux_rx_fixup | expand

Commit Message

Daniele Palmas Dec. 21, 2018, 12:07 p.m. UTC
This patch fixes qmap header retrieval when modem is configured for
dl data aggregation.

Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
---
Hi Bjørn and all,

I'm facing an issue when using qmi_wwan with modem configured with dl data aggregation and qmap multiplexing, e.g. something like

root@L2122:~# qmicli -d /dev/cdc-wdm0 --wda-set-data-format=link-layer-protocol=raw-ip,ul-protocol=qmap,dl-protocol=qmap,dl-max-datagrams=20
[/dev/cdc-wdm0] Successfully set data format
                        QoS flow header: no
                    Link layer protocol: 'raw-ip'
       Uplink data aggregation protocol: 'qmap'
     Downlink data aggregation protocol: 'qmap'
                          NDP signature: '0'
Downlink data aggregation max datagrams: '20'
     Downlink data aggregation max size: '16384'

The issue is related to qmap header retrieval in qmimux_rx_fixup: basically it seems to me that it is always taken the first qmap header. Maybe the patch below should fix this issue.

Note also that, by default, this won't be enough, since also rx_urb_size should be changed to the downlink data aggregation max size value: currently I'm just modifying the network interface MTU that changes also the
rx_urb_size.

Not sure if this makes sense, so I thought to share anyway this with you for confirmation.

Thanks,
Daniele
---
 drivers/net/usb/qmi_wwan.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

Comments

Bjørn Mork Dec. 21, 2018, 12:33 p.m. UTC | #1
Daniele Palmas <dnlplm@gmail.com> writes:

> This patch fixes qmap header retrieval when modem is configured for
> dl data aggregation.
>
> Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
> ---
> Hi Bjørn and all,
>
> I'm facing an issue when using qmi_wwan with modem configured with dl data aggregation and qmap multiplexing, e.g. something like
>
> root@L2122:~# qmicli -d /dev/cdc-wdm0 --wda-set-data-format=link-layer-protocol=raw-ip,ul-protocol=qmap,dl-protocol=qmap,dl-max-datagrams=20
> [/dev/cdc-wdm0] Successfully set data format
>                         QoS flow header: no
>                     Link layer protocol: 'raw-ip'
>        Uplink data aggregation protocol: 'qmap'
>      Downlink data aggregation protocol: 'qmap'
>                           NDP signature: '0'
> Downlink data aggregation max datagrams: '20'
>      Downlink data aggregation max size: '16384'
>
> The issue is related to qmap header retrieval in qmimux_rx_fixup: basically it seems to me that it is always taken the first qmap header. Maybe the patch below should fix this issue.
>
> Note also that, by default, this won't be enough, since also rx_urb_size should be changed to the downlink data aggregation max size value: currently I'm just modifying the network interface MTU that changes also the
> rx_urb_size.
>
> Not sure if this makes sense, so I thought to share anyway this with you for confirmation.

My personal opinion - take it for that and nothing else:

Aggregation adds buffer bloat, alignment issues, extra headers with
associated magic handling, and more.  It can make sense for some use
cases where each transmission adds significant overhead. The typical
example is radio networks. But I do not think this applies to USB.  We
are much better off sending each packet as a separate USB buffer, with a
queue that is just long enough for back-to-back transmission.  The
experience with aggregation in NCM/MBIM is not good.

So I've ignored aggregation in QMI, and will probably continue doing
so.  That doesn't mean that I am going to object to you or anyone else
implementing the support if you see a usecase. That's your problem ;-)





Bjørn
Daniele Palmas Dec. 21, 2018, 12:54 p.m. UTC | #2
Il giorno ven 21 dic 2018 alle ore 13:33 Bjørn Mork <bjorn@mork.no> ha scritto:
>
> Daniele Palmas <dnlplm@gmail.com> writes:
>
> > This patch fixes qmap header retrieval when modem is configured for
> > dl data aggregation.
> >
> > Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
> > ---
> > Hi Bjørn and all,
> >
> > I'm facing an issue when using qmi_wwan with modem configured with dl data aggregation and qmap multiplexing, e.g. something like
> >
> > root@L2122:~# qmicli -d /dev/cdc-wdm0 --wda-set-data-format=link-layer-protocol=raw-ip,ul-protocol=qmap,dl-protocol=qmap,dl-max-datagrams=20
> > [/dev/cdc-wdm0] Successfully set data format
> >                         QoS flow header: no
> >                     Link layer protocol: 'raw-ip'
> >        Uplink data aggregation protocol: 'qmap'
> >      Downlink data aggregation protocol: 'qmap'
> >                           NDP signature: '0'
> > Downlink data aggregation max datagrams: '20'
> >      Downlink data aggregation max size: '16384'
> >
> > The issue is related to qmap header retrieval in qmimux_rx_fixup: basically it seems to me that it is always taken the first qmap header. Maybe the patch below should fix this issue.
> >
> > Note also that, by default, this won't be enough, since also rx_urb_size should be changed to the downlink data aggregation max size value: currently I'm just modifying the network interface MTU that changes also the
> > rx_urb_size.
> >
> > Not sure if this makes sense, so I thought to share anyway this with you for confirmation.
>
> My personal opinion - take it for that and nothing else:
>
> Aggregation adds buffer bloat, alignment issues, extra headers with
> associated magic handling, and more.  It can make sense for some use
> cases where each transmission adds significant overhead. The typical
> example is radio networks. But I do not think this applies to USB.  We
> are much better off sending each packet as a separate USB buffer, with a
> queue that is just long enough for back-to-back transmission.  The
> experience with aggregation in NCM/MBIM is not good.
>
> So I've ignored aggregation in QMI, and will probably continue doing
> so.  That doesn't mean that I am going to object to you or anyone else
> implementing the support if you see a usecase. That's your problem ;-)
>

Thanks for the feedback!

Regards,
Daniele

>
>
>
>
> Bjørn
David Miller Dec. 21, 2018, 6:58 p.m. UTC | #3
From: Daniele Palmas <dnlplm@gmail.com>
Date: Fri, 21 Dec 2018 13:07:23 +0100

> This patch fixes qmap header retrieval when modem is configured for
> dl data aggregation.
> 
> Signed-off-by: Daniele Palmas <dnlplm@gmail.com>

Applied, thanks.
diff mbox series

Patch

diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index c8872dd..85cb4df 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -151,17 +151,18 @@  static bool qmimux_has_slaves(struct usbnet *dev)
 
 static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 {
-	unsigned int len, offset = sizeof(struct qmimux_hdr);
+	unsigned int len, offset = 0;
 	struct qmimux_hdr *hdr;
 	struct net_device *net;
 	struct sk_buff *skbn;
+	u8 qmimux_hdr_sz = sizeof(*hdr);
 
-	while (offset < skb->len) {
-		hdr = (struct qmimux_hdr *)skb->data;
+	while (offset + qmimux_hdr_sz < skb->len) {
+		hdr = (struct qmimux_hdr *)(skb->data + offset);
 		len = be16_to_cpu(hdr->pkt_len);
 
 		/* drop the packet, bogus length */
-		if (offset + len > skb->len)
+		if (offset + len + qmimux_hdr_sz > skb->len)
 			return 0;
 
 		/* control packet, we do not know what to do */
@@ -176,7 +177,7 @@  static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 			return 0;
 		skbn->dev = net;
 
-		switch (skb->data[offset] & 0xf0) {
+		switch (skb->data[offset + qmimux_hdr_sz] & 0xf0) {
 		case 0x40:
 			skbn->protocol = htons(ETH_P_IP);
 			break;
@@ -188,12 +189,12 @@  static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 			goto skip;
 		}
 
-		skb_put_data(skbn, skb->data + offset, len);
+		skb_put_data(skbn, skb->data + offset + qmimux_hdr_sz, len);
 		if (netif_rx(skbn) != NET_RX_SUCCESS)
 			return 0;
 
 skip:
-		offset += len + sizeof(struct qmimux_hdr);
+		offset += len + qmimux_hdr_sz;
 	}
 	return 1;
 }