2011-06-04 16:40:13

by Karel Gardas

[permalink] [raw]
Subject: ETH over USB: NFS state (seeking ARM platform for NFS-based builds)

Hello,

while searching for ARMv7/NEON platform for my own hacking I've found
this interesting issue:

[ 2945.114135] cc1: page allocation failure. order:3, mode:0x4020
[ 2945.114196] [<c005a420>] (unwind_backtrace+0x0/0xe0) from
[<c0107e98>] (__alloc_pages_nodemask+0x5a0/0x6b4)
[ 2945.114227] [<c0107e98>] (__alloc_pages_nodemask+0x5a0/0x6b4) from
[<c0107fbc>] (__get_free_pages+0x10/0x24)
[ 2945.114257] [<c0107fbc>] (__get_free_pages+0x10/0x24) from
[<c012f494>] (kmalloc_order_trace+0x20/0xc8)
[ 2945.114288] [<c012f494>] (kmalloc_order_trace+0x20/0xc8) from
[<c04882fc>] (__alloc_skb+0x50/0xe0)
[ 2945.114318] [<c04882fc>] (__alloc_skb+0x50/0xe0) from [<c038b2ec>]
(rx_submit+0x24/0x1cc)
[ 2945.114349] [<c038b2ec>] (rx_submit+0x24/0x1cc) from [<c0395524>]
(usb_hcd_giveback_urb+0xa0/0xec)
[ 2945.114379] [<c0395524>] (usb_hcd_giveback_urb+0xa0/0xec) from
[<c03a1650>] (ehci_urb_done+0xa8/0xb4)
[ 2945.114410] [<c03a1650>] (ehci_urb_done+0xa8/0xb4) from [<c03a5488>]
(qh_completions+0xb4/0x3d8)
[ 2945.114440] [<c03a5488>] (qh_completions+0xb4/0x3d8) from
[<c03a5d94>] (scan_async+0x90/0x144)
[ 2945.114440] [<c03a5d94>] (scan_async+0x90/0x144) from [<c03a6504>]
(ehci_work+0x30/0x88)
[ 2945.114471] [<c03a6504>] (ehci_work+0x30/0x88) from [<c03a83f0>]
(ehci_irq+0x2f4/0x35c)
[ 2945.114471] [<c03a83f0>] (ehci_irq+0x2f4/0x35c) from [<c0394e90>]
(usb_hcd_irq+0x38/0x7c)
[ 2945.114501] [<c0394e90>] (usb_hcd_irq+0x38/0x7c) from [<c00d89b4>]
(handle_IRQ_event+0x9c/0x1b4)
[ 2945.114532] [<c00d89b4>] (handle_IRQ_event+0x9c/0x1b4) from
[<c00da5dc>] (handle_level_irq+0xdc/0x160)
[ 2945.114562] [<c00da5dc>] (handle_level_irq+0xdc/0x160) from
[<c004e088>] (asm_do_IRQ+0x88/0xc8)
[ 2945.114593] [<c004e088>] (asm_do_IRQ+0x88/0xc8) from [<c05bb128>]
(__irq_usr+0x48/0x120)


which is reported here:
https://bugs.launchpad.net/ubuntu/+source/linux-ti-omap4/+bug/690370 and
which happens during the NFS usage over ETH over USB. Also the issue
seems to be more discussed here:

http://marc.info/?t=130406641000006&r=1&w=2
http://marc.info/?t=130471082300010&r=1&w=2

but as Oliver Neukum wrote me in a private reply, this issue is still
unsolved and Ming Lei two weeks ago also noted this in the bug report
above. Now, my question is: is this really true, i.e. people with ARM
boards which are using ETH over USB are either not using NFS or while
using NFS they get kernel crash? I'm curious and hence asking since
majority of low-cost ARM boards for hobby developers are using ETH over
USB. So far I've found just board with Marvell Armada 510 and with
Tegra2 which are using some kind of sane ethernet either implemented
on-chip (Armada 510) or by PCIe hooked realtek (tegra2 in trimslice).
All other popular platforms like OMAP3/4 (Beagle/Panda boards), just to
be released ST-Ericsson Snowball, Samsung Origen (this does not provide
ETH at all, so hooking ETH to USB is the only option here) all are using
ETH over USB.

So are all those popular and low-cost boards really out of question for
building/porting free software to ARM and yet using NFS for build
directories?

Any reports of first-hand experiences with this are highly appreciated
here as I'm going to use this on my hardware decision.

Thanks a lot,
Karel


2011-06-05 05:13:31

by Ming Lei

[permalink] [raw]
Subject: Re: ETH over USB: NFS state (seeking ARM platform for NFS-based builds)

Hi,

2011/6/5 Karel Gardas <[email protected]>:
> Hello,
>
> while searching for ARMv7/NEON platform for my own hacking I've found this
> interesting issue:
>
> [ 2945.114135] cc1: page allocation failure. order:3, mode:0x4020

Maybe the patch below can fix the issue, please try it:

diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 9ab439d..f16e448 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -324,12 +324,20 @@ static int rx_submit (struct usbnet *dev, struct
urb *urb, gfp_t flags)
unsigned long lockflags;
size_t size = dev->rx_urb_size;

- if ((skb = alloc_skb (size + NET_IP_ALIGN, flags)) == NULL) {
- netif_dbg(dev, rx_err, dev->net, "no rx skb\n");
+ if (atomic_read(&dev->rx_skb_on_fly) > MAX_RX_SKB_ON_FLY &&
+ flags == GFP_ATOMIC) {
+ netif_dbg(dev, rx_err, dev->net, "too many rx skbs on the fly\n");
+fail_rx_memory:
usbnet_defer_kevent (dev, EVENT_RX_MEMORY);
usb_free_urb (urb);
return -ENOMEM;
}
+
+ if ((skb = alloc_skb (size + NET_IP_ALIGN, flags)) == NULL) {
+ netif_dbg(dev, rx_err, dev->net, "no rx skb\n");
+ goto fail_rx_memory;
+ }
+ atomic_inc(&dev->rx_skb_on_fly);
skb_reserve (skb, NET_IP_ALIGN);

entry = (struct skb_data *) skb->cb;
@@ -375,6 +383,7 @@ static int rx_submit (struct usbnet *dev, struct
urb *urb, gfp_t flags)
}
spin_unlock_irqrestore (&dev->rxq.lock, lockflags);
if (retval) {
+ atomic_dec(&dev->rx_skb_on_fly);
dev_kfree_skb_any (skb);
usb_free_urb (urb);
}
@@ -1177,8 +1186,9 @@ static void usbnet_bh (unsigned long param)
entry->state = rx_cleanup;
rx_process (dev, skb);
continue;
- case tx_done:
case rx_cleanup:
+ atomic_dec(&dev->rx_skb_on_fly);
+ case tx_done:
usb_free_urb (entry->urb);
dev_kfree_skb (skb);
continue;
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 605b0aa..1dace0d 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -33,6 +33,8 @@ struct usbnet {
wait_queue_head_t *wait;
struct mutex phy_mutex;
unsigned char suspend_count;
+ atomic_t rx_skb_on_fly;
+# define MAX_RX_SKB_ON_FLY 2048

/* i/o info: pipes etc */
unsigned in, out;


thanks,
--
Ming Lei