Patch "asix: Fix offset calculation in asix_rx_fixup() causing slow transmissions" has been added to the 4.6-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
asix: Fix offset calculation in asix_rx_fixup() causing slow transmissions
to the 4.6-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
asix-fix-offset-calculation-in-asix_rx_fixup-causing-slow-transmissions.patch
and it can be found in the queue-4.6 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
cd9e2e5d3ff148be9ea210f622ce3e8e8292fcd6Mon Sep 17 00:00:00 2001
From: John Stultz <[email protected]>
Date: Mon, 16 May 2016 20:36:15 -0700
Subject: asix: Fix offset calculation in asix_rx_fixup() causing slow transmissions
From: John Stultz <[email protected]>
commit cd9e2e5d3ff148be9ea210f622ce3e8e8292fcd6 upstream.
In testing with HiKey, we found that since
commit 3f30b158eba5 ("asix: On RX avoid creating bad Ethernet frames"),
we're seeing lots of noise during network transfers:
[ 239.027993] asix 1-1.1:1.0 eth0: asix_rx_fixup() Data Header synchronisation was lost, remaining 988 [ 239.037310] asix 1-1.1:1.0 eth0: asix_rx_fixup() Bad Header Length 0x54ebb5ec, offset 4 [ 239.045519] asix 1-1.1:1.0 eth0: asix_rx_fixup() Bad Header Length 0xcdffe7a2, offset 4 [ 239.275044] asix 1-1.1:1.0 eth0: asix_rx_fixup() Data Header synchronisation was lost, remaining 988 [ 239.284355] asix 1-1.1:1.0 eth0: asix_rx_fixup() Bad Header Length 0x1d36f59d, offset 4 [ 239.292541] asix 1-1.1:1.0 eth0: asix_rx_fixup() Bad Header Length 0xaef3c1e9, offset 4 [ 239.518996] asix 1-1.1:1.0 eth0: asix_rx_fixup() Data Header synchronisation was lost, remaining 988 [ 239.528300] asix 1-1.1:1.0 eth0: asix_rx_fixup() Bad Header Length 0x2881912, offset 4 [ 239.536413] asix 1-1.1:1.0 eth0: asix_rx_fixup() Bad Header Length 0x5638f7e2, offset 4
And network throughput ends up being pretty bursty and slow with a overall throughput of at best ~30kB/s (where as previously we got 1.1MB/s with the slower USB1.1 "full speed" host).
We found the issue also was reproducible on a x86_64 system, using a "high-speed" USB2.0 port but the throughput did not measurably drop (possibly due to the scp transfer being cpu bound on my slow test hardware).
After lots of debugging, I found the check added in the problematic commit seems to be calculating the offset incorrectly.
In the normal case, in the main loop of the function, we do:
(where offset is zero, or set to "offset += (copy_length + 1) & 0xfffe" in the previous loop)
rx->header = get_unaligned_le32(skb->data +
offset);
offset += sizeof(u32);But the problematic patch calculates:
offset = ((rx->remaining + 1) & 0xfffe) + sizeof(u32);
rx->header = get_unaligned_le32(skb->data + offset);Adding some debug logic to check those offset calculation used to find rx->header, the one in problematic code is always too large by sizeof(u32).
Thus, this patch removes the incorrect " + sizeof(u32)" addition in the problematic calculation, and resolves the issue.
--- drivers/net/usb/asix_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/usb/asix_common.c +1 -1
@@ -66,7 +66,7 @@ int asix_rx_fixup_internal(struct usbnet* buffer. */ if (rx->remaining && (rx->remaining +sizeof (u32) <= skb->len)) { - offset = ((rx->remaining +1 ) &0xfffe ) +sizeof (u32); + offset = ((rx->remaining +1 ) &0xfffe ); rx->header =get_unaligned_le32 (skb->data + offset); offset =0 ;
Patches currently in stable-queue which might be from [email protected] are
queue-4.6/asix-fix-offset-calculation-in-asix_rx_fixup-causing-slow-transmissions.patch