Skip to content

Update ax88179_178a USB ethernet driver and improve USB ethernet speeds for ODROID-XU3 #166

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 27, 2016

Conversation

ddcc
Copy link

@ddcc ddcc commented Mar 5, 2016

For the ODROID-XU3, the original implementation of the ax88179_178a driver in ce49d2c was not from the upstream kernel, but from another repository which is now out-of-date. Along the way, modifications were made in e9bd5c8 to this driver to enable TCP Segment Offload (TSO) and Scatter Gather (SG), but this can cause instability with xHCI host controllers.

This patch restores the implementation of ax88179_178a to the latest version (95ff886) in the master branch of torvalds/linux, plus some USB ethernet queue optimizations from upstream in a88c32a and 452c447.

Ming Lei and others added 3 commits March 5, 2016 02:05
This patch centralizes computing of max rx/tx qlen, because:

- RX_QLEN()/TX_QLEN() is called in hot path
- computing depends on device's usb speed, now we have ls/fs, hs, ss,
so more checks need to be involved
- in fact, max rx/tx qlen should not only depend on device USB
speed, but also depend on ethernet link speed, so we need to
consider that in future.
- if SG support is done, max tx qlen may need change too

Generally, hard_mtu and rx_urb_size are changed in bind(), reset()
and link_reset() callback, and change mtu network operation, this
patches introduces the API of usbnet_update_max_qlen(), and calls
it in above path.

Signed-off-by: Ming Lei <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
The default RX_QLEN()/TX_QLEN() didn't consider super speed
USB device, so only max 4 URBs are scheduled at the same time
for tx/rx, then USB3 NIC can't perform very well.

With this patch, both rx and tx thoughput are increased more than
100Mbps when doing iperf test on ax88179_178a USB 3.0 NIC.

Signed-off-by: Ming Lei <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
…178a.

Among other things, this disables TCP Segment Offload (TSO) and Scatter
Gather (SG), which can cause instability with XHCI devices.
See: https://lkml.org/lkml/2014/3/6/284
@ddcc ddcc force-pushed the odroidxu3-3.10.y branch from 4e4187f to 0e55338 Compare March 5, 2016 08:14
@ddcc ddcc changed the title Update ax88179_178a USB ethernet driver for ODROID-XU3 Update ax88179_178a USB ethernet driver and improve USB ethernet speeds for ODROID-XU3 Mar 5, 2016
@Obihoernchen
Copy link

Did you have a look at the newest driver from ASIX (1.14.4)? http://www.asix.com.tw/FrootAttach/driver/AX88179_178A_LINUX_DRIVER_v1.14.4_SOURCE.zip

@Obihoernchen
Copy link

nevermind just compared v1.13.0 (ce49d2c) to v1.14.4 there is no real difference (ignoring whitespace changes):

51c51
< #define DRV_VERSION   "1.13.0"
---
> #define DRV_VERSION   "1.14.4"
55c55
<       " " __TIME__ " " __DATE__ "\n"
---
> //    " " __TIME__ " " __DATE__ "\n"
1282a1283
>                       #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)
1283a1285,1287
>                       #else
>                               devdbg(dev, "Failed to read MAC address from EEPROM: %d\n", ret);
>                       #endif
1301a1306
>       u8 default_mac_178a[6] = {0, 0x0e, 0xc6, 0x81, 0x78, 0x01};
1305c1310,1311
<           !memcmp(dev->net->dev_addr, default_mac, ETH_ALEN)) {
---
>           !memcmp(dev->net->dev_addr, default_mac, ETH_ALEN) ||
>           !memcmp(dev->net->dev_addr, default_mac_178a, ETH_ALEN)) {
1318a1325
> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
1319a1327
> #endif
2109a2118,2151
> static const struct driver_info dlink_info = {
>       .description = "DUB-1312/1332 USB3.0 to Gigabit Ethernet Adapter",
>       .bind   = ax88179_bind,
>       .unbind = ax88179_unbind,
>       .status = ax88179_status,
>       .link_reset = ax88179_link_reset,
>       .reset  = ax88179_reset,
> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
>       .stop   = ax88179_stop,
>       .flags  = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_AVOID_UNLINK_URBS,
> #else
>       .flags  = FLAG_ETHER | FLAG_FRAMING_AX,
> #endif
>       .rx_fixup = ax88179_rx_fixup,
>       .tx_fixup = ax88179_tx_fixup,
> };
>
> static const struct driver_info mct_info = {
>         .description = "USB 3.0 to Gigabit Ethernet Adapter",
>         .bind   = ax88179_bind,
>         .unbind = ax88179_unbind,
>         .status = ax88179_status,
>         .link_reset = ax88179_link_reset,
>         .reset  = ax88179_reset,
> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
>         .stop   = ax88179_stop,
>         .flags  = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_AVOID_UNLINK_URBS,
> #else
>         .flags  = FLAG_ETHER | FLAG_FRAMING_AX,
> #endif
>         .rx_fixup = ax88179_rx_fixup,
>         .tx_fixup = ax88179_tx_fixup,
> };
>
2134a2177,2184
> }, {
>       /* D-Link DUB-13x2 Ethernet Adapter */
>       USB_DEVICE(0x2001, 0x4a00),
>       .driver_info = (unsigned long) &dlink_info,
> }, {
>       /* MCT USB 3.0 to Gigabit Ethernet Adapter */
>       USB_DEVICE(0x0711, 0x0179),
>       .driver_info = (unsigned long) &mct_info,

@Obihoernchen
Copy link

Using this for more than 3 weeks now without problems.

@mdrjr mdrjr merged commit 9d1cfd5 into hardkernel:odroidxu3-3.10.y Mar 27, 2016
mdrjr pushed a commit that referenced this pull request Oct 22, 2019
[ Upstream commit c784be4 ]

The calls to arch_add_memory()/arch_remove_memory() are always made
with the read-side cpu_hotplug_lock acquired via memory_hotplug_begin().
On pSeries, arch_add_memory()/arch_remove_memory() eventually call
resize_hpt() which in turn calls stop_machine() which acquires the
read-side cpu_hotplug_lock again, thereby resulting in the recursive
acquisition of this lock.

In the absence of CONFIG_PROVE_LOCKING, we hadn't observed a system
lockup during a memory hotplug operation because cpus_read_lock() is a
per-cpu rwsem read, which, in the fast-path (in the absence of the
writer, which in our case is a CPU-hotplug operation) simply
increments the read_count on the semaphore. Thus a recursive read in
the fast-path doesn't cause any problems.

However, we can hit this problem in practice if there is a concurrent
CPU-Hotplug operation in progress which is waiting to acquire the
write-side of the lock. This will cause the second recursive read to
block until the writer finishes. While the writer is blocked since the
first read holds the lock. Thus both the reader as well as the writers
fail to make any progress thereby blocking both CPU-Hotplug as well as
Memory Hotplug operations.

Memory-Hotplug				CPU-Hotplug
CPU 0					CPU 1
------                                  ------

1. down_read(cpu_hotplug_lock.rw_sem)
   [memory_hotplug_begin]
					2. down_write(cpu_hotplug_lock.rw_sem)
					[cpu_up/cpu_down]
3. down_read(cpu_hotplug_lock.rw_sem)
   [stop_machine()]

Lockdep complains as follows in these code-paths.

 swapper/0/1 is trying to acquire lock:
 (____ptrval____) (cpu_hotplug_lock.rw_sem){++++}, at: stop_machine+0x2c/0x60

but task is already holding lock:
(____ptrval____) (cpu_hotplug_lock.rw_sem){++++}, at: mem_hotplug_begin+0x20/0x50

 other info that might help us debug this:
  Possible unsafe locking scenario:

        CPU0
        ----
   lock(cpu_hotplug_lock.rw_sem);
   lock(cpu_hotplug_lock.rw_sem);

  *** DEADLOCK ***

  May be due to missing lock nesting notation

 3 locks held by swapper/0/1:
  #0: (____ptrval____) (&dev->mutex){....}, at: __driver_attach+0x12c/0x1b0
  #1: (____ptrval____) (cpu_hotplug_lock.rw_sem){++++}, at: mem_hotplug_begin+0x20/0x50
  #2: (____ptrval____) (mem_hotplug_lock.rw_sem){++++}, at: percpu_down_write+0x54/0x1a0

stack backtrace:
 CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.0.0-rc5-58373-gbc99402235f3-dirty #166
 Call Trace:
   dump_stack+0xe8/0x164 (unreliable)
   __lock_acquire+0x1110/0x1c70
   lock_acquire+0x240/0x290
   cpus_read_lock+0x64/0xf0
   stop_machine+0x2c/0x60
   pseries_lpar_resize_hpt+0x19c/0x2c0
   resize_hpt_for_hotplug+0x70/0xd0
   arch_add_memory+0x58/0xfc
   devm_memremap_pages+0x5e8/0x8f0
   pmem_attach_disk+0x764/0x830
   nvdimm_bus_probe+0x118/0x240
   really_probe+0x230/0x4b0
   driver_probe_device+0x16c/0x1e0
   __driver_attach+0x148/0x1b0
   bus_for_each_dev+0x90/0x130
   driver_attach+0x34/0x50
   bus_add_driver+0x1a8/0x360
   driver_register+0x108/0x170
   __nd_driver_register+0xd0/0xf0
   nd_pmem_driver_init+0x34/0x48
   do_one_initcall+0x1e0/0x45c
   kernel_init_freeable+0x540/0x64c
   kernel_init+0x2c/0x160
   ret_from_kernel_thread+0x5c/0x68

Fix this issue by
  1) Requiring all the calls to pseries_lpar_resize_hpt() be made
     with cpu_hotplug_lock held.

  2) In pseries_lpar_resize_hpt() invoke stop_machine_cpuslocked()
     as a consequence of 1)

  3) To satisfy 1), in hpt_order_set(), call mmu_hash_ops.resize_hpt()
     with cpu_hotplug_lock held.

Fixes: dbcf929 ("powerpc/pseries: Add support for hash table resizing")
Cc: [email protected] # v4.11+
Reported-by: Aneesh Kumar K.V <[email protected]>
Signed-off-by: Gautham R. Shenoy <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Sasha Levin <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants