Netdev List
 help / color / mirror / Atom feed
* 1f324e3 ipv6: Don't depend on per socket memory for neighbour discovery messages
From: Stephen Warren @ 2013-08-30 19:46 UTC (permalink / raw)
  To: Thomas Graf, Eric Dumazet, Hannes Frederic Sowa, David S. Miller
  Cc: linux-next@vger.kernel.org, netdev@vger.kernel.org

Commit 1f324e3 "ipv6: Don't depend on per socket memory for neighbour
discovery messages" appears to cause issues for me. If I run
next-20130830, I see the issue, but if I then just revert that one
patch, I don't see any problem, and can use the network without issue.

The problem is: with a network device enabled (in my case, a USB
Ethernet dongle, although I don't know if the type is relevant), then
the system appears to hang soon after enabling the interface; neither
the serial console nor the framebuffer echo my typing, and the cursor on
the framebuffer stops flashing. After a short delay, I see the following
kernel spew:

> localhost login: [   14.390206] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
> [   14.409459] asix 1-1:1.0 eth0: link up, 100Mbps, full-duplex, lpa 0x41E1
> [   43.172240] INFO: rcu_preempt self-detected stall on CPU
> [   43.172256] INFO: rcu_preempt self-detected stall on CPU { 0}  (t=2100 jiffies g=262 c=261 q=1)
> [   43.172265] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.11.0-rc7-next-20130830-00020-gf47ee2e #152
> [   43.172305] [<c00165bc>] (unwind_backtrace+0x0/0x138) from [<c00122cc>] (show_stack+0x10/0x14)
> [   43.172329] [<c00122cc>] (show_stack+0x10/0x14) from [<c0569af8>] (dump_stack+0x80/0xc4)
> [   43.172350] [<c0569af8>] (dump_stack+0x80/0xc4) from [<c008997c>] (rcu_check_callbacks+0x35c/0x818)
> [   43.172367] [<c008997c>] (rcu_check_callbacks+0x35c/0x818) from [<c002fc20>] (update_process_times+0x38/0x64)
> [   43.172378] [<c002fc20>] (update_process_times+0x38/0x64) from [<c006bcc4>] (tick_sched_timer+0x44/0x74)
> [   43.172397] [<c006bcc4>] (tick_sched_timer+0x44/0x74) from [<c0042978>] (__run_hrtimer.isra.15+0x58/0x114)
> [   43.172409] [<c0042978>] (__run_hrtimer.isra.15+0x58/0x114) from [<c00432d0>] (hrtimer_interrupt+0x108/0x2c4)
> [   43.172420] [<c00432d0>] (hrtimer_interrupt+0x108/0x2c4) from [<c0015934>] (twd_handler+0x2c/0x40)
> [   43.172429] [<c0015934>] (twd_handler+0x2c/0x40) from [<c0084488>] (handle_percpu_devid_irq+0x68/0x84)
> [   43.172447] [<c0084488>] (handle_percpu_devid_irq+0x68/0x84) from [<c0080db8>] (generic_handle_irq+0x20/0x30)
> [   43.172460] [<c0080db8>] (generic_handle_irq+0x20/0x30) from [<c000f914>] (handle_IRQ+0x38/0x94)
> [   43.172470] [<c000f914>] (handle_IRQ+0x38/0x94) from [<c00086d8>] (gic_handle_irq+0x28/0x5c)
> [   43.172481] [<c00086d8>] (gic_handle_irq+0x28/0x5c) from [<c0012de0>] (__irq_svc+0x40/0x70)
> [   43.172485] Exception stack(0xc07c5d20 to 0xc07c5d68)
> [   43.172492] 5d20: eeb070c8 ee465838 00000303 80000001 eeb070c8 00000000 ee465828 eeb070c8
> [   43.172500] 5d40: ee465838 00000001 eeb07000 eeb7b480 ee465820 c07c5d68 c056fe34 c056fe5c
> [   43.172503] 5d60: 80000113 ffffffff
> [   43.172518] [<c0012de0>] (__irq_svc+0x40/0x70) from [<c056fe5c>] (_raw_read_lock_bh+0x34/0x44)
> [   43.172539] [<c056fe5c>] (_raw_read_lock_bh+0x34/0x44) from [<c04aa2f4>] (ipv6_chk_mcast_addr+0x2c/0x1b0)
> [   43.172555] [<c04aa2f4>] (ipv6_chk_mcast_addr+0x2c/0x1b0) from [<c048b130>] (ip6_finish_output2+0x240/0x4fc)
> [   43.172566] [<c048b130>] (ip6_finish_output2+0x240/0x4fc) from [<c049d724>] (ndisc_send_skb+0x1c8/0x2d8)
> [   43.172578] [<c049d724>] (ndisc_send_skb+0x1c8/0x2d8) from [<c0490f68>] (addrconf_rs_timer+0x108/0x134)
> [   43.172589] [<c0490f68>] (addrconf_rs_timer+0x108/0x134) from [<c002f0d4>] (call_timer_fn.isra.20+0x24/0x84)
> [   43.172598] [<c002f0d4>] (call_timer_fn.isra.20+0x24/0x84) from [<c002f2c8>] (run_timer_softirq+0x194/0x244)
> [   43.172616] [<c002f2c8>] (run_timer_softirq+0x194/0x244) from [<c0029818>] (__do_softirq+0xe8/0x1d0)
> [   43.172627] [<c0029818>] (__do_softirq+0xe8/0x1d0) from [<c0029c38>] (irq_exit+0x98/0xe4)
> [   43.172637] [<c0029c38>] (irq_exit+0x98/0xe4) from [<c000f918>] (handle_IRQ+0x3c/0x94)
> [   43.172646] [<c000f918>] (handle_IRQ+0x3c/0x94) from [<c00086d8>] (gic_handle_irq+0x28/0x5c)
> [   43.172655] [<c00086d8>] (gic_handle_irq+0x28/0x5c) from [<c0012de0>] (__irq_svc+0x40/0x70)
> [   43.172658] Exception stack(0xc07c5f28 to 0xc07c5f70)
> [   43.172664] 5f20:                   c07c5f70 3b9aca00 b665e400 00000004 b63d5530 00000004
> [   43.172671] 5f40: c10880e0 00000000 00000000 c07cc3d4 c0573354 00000000 00000015 c07c5f70
> [   43.172676] 5f60: c0063658 c038edac 60000113 ffffffff
> [   43.172696] [<c0012de0>] (__irq_svc+0x40/0x70) from [<c038edac>] (cpuidle_enter_state+0x50/0xe8)
> [   43.172709] [<c038edac>] (cpuidle_enter_state+0x50/0xe8) from [<c038eefc>] (cpuidle_idle_call+0xb8/0x168)
> [   43.172719] [<c038eefc>] (cpuidle_idle_call+0xb8/0x168) from [<c000fc60>] (arch_cpu_idle+0x8/0x38)
> [   43.172730] [<c000fc60>] (arch_cpu_idle+0x8/0x38) from [<c0062924>] (cpu_startup_entry+0x60/0x134)
> [   43.172750] [<c0062924>] (cpu_startup_entry+0x60/0x134) from [<c0789a28>] (start_kernel+0x2b8/0x30c)
> [   43.765722]  { 1}  (t=2159 jiffies g=262 c=261 q=1)
> [   43.778002] CPU: 1 PID: 539 Comm: NetworkManager Not tainted 3.11.0-rc7-next-20130830-00020-gf47ee2e #152
> [   43.795156] [<c00165bc>] (unwind_backtrace+0x0/0x138) from [<c00122cc>] (show_stack+0x10/0x14)
> [   43.811442] [<c00122cc>] (show_stack+0x10/0x14) from [<c0569af8>] (dump_stack+0x80/0xc4)
> [   43.827204] [<c0569af8>] (dump_stack+0x80/0xc4) from [<c008997c>] (rcu_check_callbacks+0x35c/0x818)
> [   43.843896] [<c008997c>] (rcu_check_callbacks+0x35c/0x818) from [<c002fc20>] (update_process_times+0x38/0x64)
> [   43.861541] [<c002fc20>] (update_process_times+0x38/0x64) from [<c006bcc4>] (tick_sched_timer+0x44/0x74)
> [   43.878779] [<c006bcc4>] (tick_sched_timer+0x44/0x74) from [<c0042978>] (__run_hrtimer.isra.15+0x58/0x114)
> [   43.896302] [<c0042978>] (__run_hrtimer.isra.15+0x58/0x114) from [<c00432d0>] (hrtimer_interrupt+0x108/0x2c4)
> [   43.914085] [<c00432d0>] (hrtimer_interrupt+0x108/0x2c4) from [<c0015934>] (twd_handler+0x2c/0x40)
> [   43.930903] [<c0015934>] (twd_handler+0x2c/0x40) from [<c0084488>] (handle_percpu_devid_irq+0x68/0x84)
> [   43.948107] [<c0084488>] (handle_percpu_devid_irq+0x68/0x84) from [<c0080db8>] (generic_handle_irq+0x20/0x30)
> [   43.966008] [<c0080db8>] (generic_handle_irq+0x20/0x30) from [<c000f914>] (handle_IRQ+0x38/0x94)
> [   43.982745] [<c000f914>] (handle_IRQ+0x38/0x94) from [<c00086d8>] (gic_handle_irq+0x28/0x5c)
> [   43.999123] [<c00086d8>] (gic_handle_irq+0x28/0x5c) from [<c0012de0>] (__irq_svc+0x40/0x70)
> [   44.015380] Exception stack(0xedc35be8 to 0xedc35c30)
> [   44.028267] 5be0:                   eeb070c8 00000000 00000201 80000001 eeb070c8 eeb070c8
> [   44.044329] 5c00: eeb07000 eeb071b4 ee4336c0 00000000 edc80a38 00000000 edc80b90 edc35c30
> [   44.060321] 5c20: c056fe34 c056fe5c 800f0013 ffffffff
> [   44.073089] [<c0012de0>] (__irq_svc+0x40/0x70) from [<c056fe5c>] (_raw_read_lock_bh+0x34/0x44)
> [   44.089495] [<c056fe5c>] (_raw_read_lock_bh+0x34/0x44) from [<c049037c>] (inet6_fill_ifla6_attrs+0x300/0x358)
> [   44.107263] [<c049037c>] (inet6_fill_ifla6_attrs+0x300/0x358) from [<c0490578>] (inet6_fill_ifinfo+0x178/0x1a0)
> [   44.125244] [<c0490578>] (inet6_fill_ifinfo+0x178/0x1a0) from [<c0490628>] (inet6_dump_ifinfo+0x88/0xe0)
> [   44.142605] [<c0490628>] (inet6_dump_ifinfo+0x88/0xe0) from [<c042f318>] (netlink_dump+0xa0/0x1d8)
> [   44.159411] [<c042f318>] (netlink_dump+0xa0/0x1d8) from [<c04300b4>] (__netlink_dump_start+0x100/0x158)
> [   44.176711] [<c04300b4>] (__netlink_dump_start+0x100/0x158) from [<c0425b90>] (rtnetlink_rcv_msg+0x110/0x1f4)
> [   44.194593] [<c0425b90>] (rtnetlink_rcv_msg+0x110/0x1f4) from [<c04318c4>] (netlink_rcv_skb+0xac/0xc0)
> [   44.211854] [<c04318c4>] (netlink_rcv_skb+0xac/0xc0) from [<c04248b8>] (rtnetlink_rcv+0x1c/0x24)
> [   44.228576] [<c04248b8>] (rtnetlink_rcv+0x1c/0x24) from [<c04312bc>] (netlink_unicast+0x158/0x1b8)
> [   44.245451] [<c04312bc>] (netlink_unicast+0x158/0x1b8) from [<c0431668>] (netlink_sendmsg+0x2ac/0x360)
> [   44.262719] [<c0431668>] (netlink_sendmsg+0x2ac/0x360) from [<c04018b4>] (sock_sendmsg+0x88/0xa8)
> [   44.279477] [<c04018b4>] (sock_sendmsg+0x88/0xa8) from [<c0401c7c>] (___sys_sendmsg+0x2a8/0x2c0)
> [   44.296134] [<c0401c7c>] (___sys_sendmsg+0x2a8/0x2c0) from [<c0403840>] (__sys_sendmsg+0x3c/0x68)
> [   44.312870] [<c0403840>] (__sys_sendmsg+0x3c/0x68) from [<c000f060>] (ret_fast_syscall+0x0/0x30)

This repeats every minute.

^ permalink raw reply

* Re: [PATCH v3] net/hsr: Add support for the High-availability Seamless Redundancy protocol (HSRv0)
From: David Miller @ 2013-08-30 19:54 UTC (permalink / raw)
  To: arvid.brodin; +Cc: netdev, shemminger, joe, jboticario, balferreira
In-Reply-To: <521504E1.5060309@xdin.com>

From: Arvid Brodin <arvid.brodin@xdin.com>
Date: Wed, 21 Aug 2013 20:20:17 +0200

> This is a patch against net-next (2013-08-21).

First of all, your email client corrupted the patch, chopping up long lines
and making whitespace changes to the content of the patch.  Please fix this
before resubmitting, and do so by first sending a test patch to yourself
and making sure you can apply the patch you receive in that email.  Do not
use attachments to deal with this issue.

> +	if (dev->operstate != transition) {
> +		write_lock_bh(&dev_base_lock);
> +		dev->operstate = transition;
> +		write_unlock_bh(&dev_base_lock);
> +		netdev_state_change(dev);
> +	}

This is racy.  And it appears that set_operstate() in net/core/rtnetlink.c
has the same bug, I guess that's what you used as a guide.

Any "test and set" sequence must be guarded completely by the lock, it
doesn't make any sense to only guard the change of the value.

^ permalink raw reply

* ipv4: warnings on sk_wmem_queued
From: Eric Wong @ 2013-08-30 19:56 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel

I noticed these warnings on stock 3.10.9 running stress tests on
cmogstored.git (git://bogomips.org/cmogstored.git) doing standard
HTTP server stuff between lo and tmpfs:

HTTP PUT requests hit: read(socket) + pwrite()
HTTP GET requests hit: send(MSG_MORE) + sendfile()

HTTP/1.1 persistent connections used for all GETs (using ab), but not
PUTs since I was lazy at curl scripting.

PUT requests are concurrent 100M uploads,
GET responses range from 110 bytes to 1GB

I'm doing a bunch of these requests in parallel with ab and curl so I
can't tell which caused the warning.  No errors bubbled up cmogstored.

This is fairly new hardware: Haswell E3-1230 v3 @ 3.30GHz on
NO_HZ_{FULL,_ALL}=y, PREEMPT=y

sysctl: tcp_low_latency=1, tcp_slow_start_after_idle=0
sockopts: TCP_NODELAY, SO_KEEPALIVE, SO_REUSEADDR

No changes to socket buffers anywhere, no TFO.

I was going to reboot into 3.10.10 before I looked at dmesg.  These
warnings happened after ~8 hours of stress tests, and those stress tests
are still running.

Aug 30 06:03:54 localhost kernel: ------------[ cut here ]------------
Aug 30 06:03:54 localhost kernel: WARNING: at net/core/stream.c:200 sk_stream_kill_queues+0x131/0x140()
Aug 30 06:03:54 localhost kernel: Modules linked in: fuse ufs minix ntfs vfat msdos fat libcrc32c reiserfs ext2 dm_mod binfmt_misc w83627ehf hwmon_vid lm63 loop snd_hda_codec_realtek coretemp kvm_intel kvm crc32c_intel aesni_intel aes_x86_64 lrw gf128mul glue_helper ablk_helper cryptd radeon cfbfillrect cfbimgblt cfbcopyarea sg ttm snd_hda_intel drm_kms_helper microcode snd_hda_codec drm snd_hwdep snd_pcm agpgart e1000e igb snd_page_alloc snd_timer snd sr_mod evdev firewire_core firmware_class i2c_algo_bit crc_itu_t ptp ehci_pci dca i2c_i801 cdrom pps_core ehci_hcd xhci_hcd fan video backlight thermal acpi_cpufreq mperf freq_table button processor [last unloaded: firewire_ohci]
Aug 30 06:03:54 localhost kernel: CPU: 5 PID: 8390 Comm: cmogstored Tainted: G        W    3.10.9meltdown2 #11
Aug 30 06:03:54 localhost kernel: Hardware name: Supermicro X10SAE/X10SAE, BIOS 1.00 05/03/2013
Aug 30 06:03:54 localhost kernel: 0000000000000009 ffff88083dd43a38 ffffffff814244c6 ffff88083dd43a78
Aug 30 06:03:54 localhost kernel: ffffffff81034720 0000000000000000 ffff8803addf2080 ffff8803addf21d8
Aug 30 06:03:54 localhost kernel: 0000000000000000 0000000000000000 00000000000002d1 ffff88083dd43a88
Aug 30 06:03:54 localhost kernel: Call Trace:
Aug 30 06:03:54 localhost kernel: <IRQ>  [<ffffffff814244c6>] dump_stack+0x19/0x1b
Aug 30 06:03:54 localhost kernel: [<ffffffff81034720>] warn_slowpath_common+0x70/0xa0
Aug 30 06:03:54 localhost kernel: [<ffffffff8103476a>] warn_slowpath_null+0x1a/0x20
Aug 30 06:03:54 localhost kernel: [<ffffffff81388c01>] sk_stream_kill_queues+0x131/0x140
Aug 30 06:03:54 localhost kernel: [<ffffffff813c5d1a>] inet_csk_destroy_sock+0x5a/0x140
Aug 30 06:03:54 localhost kernel: [<ffffffff813c8ef7>] tcp_done+0x67/0x90
Aug 30 06:03:54 localhost kernel: [<ffffffff813dfd94>] tcp_time_wait+0x74/0x1c0
Aug 30 06:03:54 localhost kernel: [<ffffffff813cdc24>] tcp_fin+0x114/0x1f0
Aug 30 06:03:54 localhost kernel: [<ffffffff813d1098>] tcp_data_queue+0x708/0xcb0
Aug 30 06:03:54 localhost kernel: [<ffffffff813d4b07>] tcp_rcv_state_process+0x6d7/0xc80
Aug 30 06:03:54 localhost kernel: [<ffffffff813d3ab6>] ? tcp_rcv_established+0x166/0x790
Aug 30 06:03:54 localhost kernel: [<ffffffff813db90f>] tcp_v4_do_rcv+0xcf/0x380
Aug 30 06:03:54 localhost kernel: [<ffffffff813debe1>] tcp_v4_rcv+0x691/0x800
Aug 30 06:03:54 localhost kernel: [<ffffffff81068565>] ? sched_clock_cpu+0xc5/0x120
Aug 30 06:03:54 localhost kernel: [<ffffffff813bb05e>] ip_local_deliver_finish+0xbe/0x220
Aug 30 06:03:54 localhost kernel: [<ffffffff813bb338>] ip_local_deliver+0x38/0x90
Aug 30 06:03:54 localhost kernel: [<ffffffff813bad99>] ip_rcv_finish+0x109/0x310
Aug 30 06:03:54 localhost kernel: [<ffffffff813bb561>] ip_rcv+0x1d1/0x300
Aug 30 06:03:54 localhost kernel: [<ffffffff8105a76d>] ? run_posix_cpu_timers+0x3d/0x830
Aug 30 06:03:54 localhost kernel: [<ffffffff8138c3b2>] __netif_receive_skb_core+0x4a2/0x610
Aug 30 06:03:54 localhost kernel: [<ffffffff8138f2c1>] __netif_receive_skb+0x21/0x70
Aug 30 06:03:54 localhost kernel: [<ffffffff8138f3ac>] process_backlog+0x9c/0x170
Aug 30 06:03:54 localhost kernel: [<ffffffff8138f77c>] net_rx_action+0xbc/0x200
Aug 30 06:03:54 localhost kernel: [<ffffffff8103c140>] __do_softirq+0xe0/0x280
Aug 30 06:03:54 localhost kernel: [<ffffffff8143173c>] call_softirq+0x1c/0x30
Aug 30 06:03:54 localhost kernel: <EOI>  [<ffffffff810039f5>] do_softirq+0x55/0x90
Aug 30 06:03:54 localhost kernel: [<ffffffff8103c057>] local_bh_enable+0xa7/0xb0
Aug 30 06:03:54 localhost kernel: [<ffffffff813bf1f4>] ip_finish_output+0x224/0x390
Aug 30 06:03:54 localhost kernel: [<ffffffff813c073e>] ip_output+0x4e/0x90
Aug 30 06:03:54 localhost kernel: [<ffffffff813bff19>] ip_local_out+0x29/0x30
Aug 30 06:03:54 localhost kernel: [<ffffffff813c0073>] ip_queue_xmit+0x153/0x3c0
Aug 30 06:03:54 localhost kernel: [<ffffffff813d6c25>] tcp_transmit_skb+0x3c5/0x820
Aug 30 06:03:54 localhost kernel: [<ffffffff813d72c1>] tcp_write_xmit+0x191/0xaa0
Aug 30 06:03:54 localhost kernel: [<ffffffff8138434c>] ? __kmalloc_reserve.isra.49+0x3c/0xa0
Aug 30 06:03:54 localhost kernel: [<ffffffff813d7c42>] __tcp_push_pending_frames+0x32/0xa0
Aug 30 06:03:54 localhost kernel: [<ffffffff813d8a8f>] tcp_send_fin+0x6f/0x190
Aug 30 06:03:54 localhost kernel: [<ffffffff813cc508>] tcp_close+0x378/0x410
Aug 30 06:03:54 localhost kernel: [<ffffffff813efe5a>] inet_release+0x5a/0xa0
Aug 30 06:03:54 localhost kernel: [<ffffffff8137a218>] sock_release+0x28/0x90
Aug 30 06:03:54 localhost kernel: [<ffffffff8137a5c2>] sock_close+0x12/0x20
Aug 30 06:03:54 localhost kernel: [<ffffffff81123def>] __fput+0xaf/0x240
Aug 30 06:03:54 localhost kernel: [<ffffffff8112403e>] ____fput+0xe/0x10
Aug 30 06:03:54 localhost kernel: [<ffffffff81054d47>] task_work_run+0xa7/0xe0
Aug 30 06:03:54 localhost kernel: [<ffffffff8100209c>] do_notify_resume+0x9c/0xb0
Aug 30 06:03:54 localhost kernel: [<ffffffff81430788>] int_signal+0x12/0x17
Aug 30 06:03:54 localhost kernel: ---[ end trace 1a0bb0997c6a8dcf ]---
Aug 30 06:03:54 localhost kernel: ------------[ cut here ]------------
Aug 30 06:03:54 localhost kernel: WARNING: at net/ipv4/af_inet.c:155 inet_sock_destruct+0x191/0x1e0()
Aug 30 06:03:54 localhost kernel: Modules linked in: fuse ufs minix ntfs vfat msdos fat libcrc32c reiserfs ext2 dm_mod binfmt_misc w83627ehf hwmon_vid lm63 loop snd_hda_codec_realtek coretemp kvm_intel kvm crc32c_intel aesni_intel aes_x86_64 lrw gf128mul glue_helper ablk_helper cryptd radeon cfbfillrect cfbimgblt cfbcopyarea sg ttm snd_hda_intel drm_kms_helper microcode snd_hda_codec drm snd_hwdep snd_pcm agpgart e1000e igb snd_page_alloc snd_timer snd sr_mod evdev firewire_core firmware_class i2c_algo_bit crc_itu_t ptp ehci_pci dca i2c_i801 cdrom pps_core ehci_hcd xhci_hcd fan video backlight thermal acpi_cpufreq mperf freq_table button processor [last unloaded: firewire_ohci]
Aug 30 06:03:54 localhost kernel: CPU: 5 PID: 8390 Comm: cmogstored Tainted: G        W    3.10.9meltdown2 #11
Aug 30 06:03:54 localhost kernel: Hardware name: Supermicro X10SAE/X10SAE, BIOS 1.00 05/03/2013
Aug 30 06:03:54 localhost kernel: 0000000000000009 ffff88083dd43bf8 ffffffff814244c6 ffff88083dd43c38
Aug 30 06:03:54 localhost kernel: ffffffff81034720 ffff8807e84147b0 ffff8803addf2080 ffff8803addf21d8
Aug 30 06:03:54 localhost kernel: ffff8803addf2080 ffff8805dd8150ac 0000000000004c1d ffff88083dd43c48
Aug 30 06:03:54 localhost kernel: Call Trace:
Aug 30 06:03:54 localhost kernel: <IRQ>  [<ffffffff814244c6>] dump_stack+0x19/0x1b
Aug 30 06:03:54 localhost kernel: [<ffffffff81034720>] warn_slowpath_common+0x70/0xa0
Aug 30 06:03:54 localhost kernel: [<ffffffff8103476a>] warn_slowpath_null+0x1a/0x20
Aug 30 06:03:54 localhost kernel: [<ffffffff813f01d1>] inet_sock_destruct+0x191/0x1e0
Aug 30 06:03:54 localhost kernel: [<ffffffff8137f2ed>] __sk_free+0x1d/0x110
Aug 30 06:03:54 localhost kernel: [<ffffffff8137f471>] sk_free+0x21/0x30
Aug 30 06:03:54 localhost kernel: [<ffffffff813dec07>] tcp_v4_rcv+0x6b7/0x800
Aug 30 06:03:54 localhost kernel: [<ffffffff81068565>] ? sched_clock_cpu+0xc5/0x120
Aug 30 06:03:54 localhost kernel: [<ffffffff813bb05e>] ip_local_deliver_finish+0xbe/0x220
Aug 30 06:03:54 localhost kernel: [<ffffffff813bb338>] ip_local_deliver+0x38/0x90
Aug 30 06:03:54 localhost kernel: [<ffffffff813bad99>] ip_rcv_finish+0x109/0x310
Aug 30 06:03:54 localhost kernel: [<ffffffff813bb561>] ip_rcv+0x1d1/0x300
Aug 30 06:03:54 localhost kernel: [<ffffffff8105a76d>] ? run_posix_cpu_timers+0x3d/0x830
Aug 30 06:03:54 localhost kernel: [<ffffffff8138c3b2>] __netif_receive_skb_core+0x4a2/0x610
Aug 30 06:03:54 localhost kernel: [<ffffffff8138f2c1>] __netif_receive_skb+0x21/0x70
Aug 30 06:03:54 localhost kernel: [<ffffffff8138f3ac>] process_backlog+0x9c/0x170
Aug 30 06:03:54 localhost kernel: [<ffffffff8138f77c>] net_rx_action+0xbc/0x200
Aug 30 06:03:54 localhost kernel: [<ffffffff8103c140>] __do_softirq+0xe0/0x280
Aug 30 06:03:54 localhost kernel: [<ffffffff8143173c>] call_softirq+0x1c/0x30
Aug 30 06:03:54 localhost kernel: <EOI>  [<ffffffff810039f5>] do_softirq+0x55/0x90
Aug 30 06:03:54 localhost kernel: [<ffffffff8103c057>] local_bh_enable+0xa7/0xb0
Aug 30 06:03:54 localhost kernel: [<ffffffff813bf1f4>] ip_finish_output+0x224/0x390
Aug 30 06:03:54 localhost kernel: [<ffffffff813c073e>] ip_output+0x4e/0x90
Aug 30 06:03:54 localhost kernel: [<ffffffff813bff19>] ip_local_out+0x29/0x30
Aug 30 06:03:54 localhost kernel: [<ffffffff813c0073>] ip_queue_xmit+0x153/0x3c0
Aug 30 06:03:54 localhost kernel: [<ffffffff813d6c25>] tcp_transmit_skb+0x3c5/0x820
Aug 30 06:03:54 localhost kernel: [<ffffffff813d72c1>] tcp_write_xmit+0x191/0xaa0
Aug 30 06:03:54 localhost kernel: [<ffffffff8138434c>] ? __kmalloc_reserve.isra.49+0x3c/0xa0
Aug 30 06:03:54 localhost kernel: [<ffffffff813d7c42>] __tcp_push_pending_frames+0x32/0xa0
Aug 30 06:03:54 localhost kernel: [<ffffffff813d8a8f>] tcp_send_fin+0x6f/0x190
Aug 30 06:03:54 localhost kernel: [<ffffffff813cc508>] tcp_close+0x378/0x410
Aug 30 06:03:54 localhost kernel: [<ffffffff813efe5a>] inet_release+0x5a/0xa0
Aug 30 06:03:54 localhost kernel: [<ffffffff8137a218>] sock_release+0x28/0x90
Aug 30 06:03:54 localhost kernel: [<ffffffff8137a5c2>] sock_close+0x12/0x20
Aug 30 06:03:54 localhost kernel: [<ffffffff81123def>] __fput+0xaf/0x240
Aug 30 06:03:54 localhost kernel: [<ffffffff8112403e>] ____fput+0xe/0x10
Aug 30 06:03:54 localhost kernel: [<ffffffff81054d47>] task_work_run+0xa7/0xe0
Aug 30 06:03:54 localhost kernel: [<ffffffff8100209c>] do_notify_resume+0x9c/0xb0
Aug 30 06:03:54 localhost kernel: [<ffffffff81430788>] int_signal+0x12/0x17
Aug 30 06:03:54 localhost kernel: ---[ end trace 1a0bb0997c6a8dd0 ]---

Thanks for reading!

^ permalink raw reply

* [PATCH net-next] be2net: set and query VEB/VEPA mode of the PF interface
From: Ajit Khaparde @ 2013-08-30 20:01 UTC (permalink / raw)
  To: davem; +Cc: netdev

SkyHawk-R can support VEB or VEPA mode.
This patch will allow the user to set/query this switch setting.

Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
---
 drivers/net/ethernet/emulex/benet/be_cmds.c |   27 ++++++++--
 drivers/net/ethernet/emulex/benet/be_cmds.h |   17 ++++--
 drivers/net/ethernet/emulex/benet/be_main.c |   77 +++++++++++++++++++++++++-
 3 files changed, 108 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 52c9085..1ab5dab 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -2876,7 +2876,7 @@ int be_cmd_set_mac(struct be_adapter *adapter, u8 *mac, int if_id, u32 dom)
 }
 
 int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
-			u32 domain, u16 intf_id)
+			  u32 domain, u16 intf_id, u16 hsw_mode)
 {
 	struct be_mcc_wrb *wrb;
 	struct be_cmd_req_set_hsw_config *req;
@@ -2903,6 +2903,13 @@ int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
 		AMAP_SET_BITS(struct amap_set_hsw_context, pvid_valid, ctxt, 1);
 		AMAP_SET_BITS(struct amap_set_hsw_context, pvid, ctxt, pvid);
 	}
+	if (!BEx_chip(adapter) && hsw_mode) {
+		AMAP_SET_BITS(struct amap_set_hsw_context, interface_id,
+			      ctxt, adapter->hba_port_num);
+		AMAP_SET_BITS(struct amap_set_hsw_context, pport, ctxt, 1);
+		AMAP_SET_BITS(struct amap_set_hsw_context, port_fwd_type,
+			      ctxt, hsw_mode);
+	}
 
 	be_dws_cpu_to_le(req->context, sizeof(req->context));
 	status = be_mcc_notify_wait(adapter);
@@ -2914,7 +2921,7 @@ err:
 
 /* Get Hyper switch config */
 int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
-			u32 domain, u16 intf_id)
+			  u32 domain, u16 intf_id, u8 *mode)
 {
 	struct be_mcc_wrb *wrb;
 	struct be_cmd_req_get_hsw_config *req;
@@ -2937,9 +2944,15 @@ int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
 			OPCODE_COMMON_GET_HSW_CONFIG, sizeof(*req), wrb, NULL);
 
 	req->hdr.domain = domain;
-	AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id, ctxt,
-								intf_id);
+	AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id,
+		      ctxt, intf_id);
 	AMAP_SET_BITS(struct amap_get_hsw_req_context, pvid_valid, ctxt, 1);
+
+	if (!BEx_chip(adapter)) {
+		AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id,
+			      ctxt, adapter->hba_port_num);
+		AMAP_SET_BITS(struct amap_get_hsw_req_context, pport, ctxt, 1);
+	}
 	be_dws_cpu_to_le(req->context, sizeof(req->context));
 
 	status = be_mcc_notify_wait(adapter);
@@ -2950,7 +2963,11 @@ int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
 						sizeof(resp->context));
 		vid = AMAP_GET_BITS(struct amap_get_hsw_resp_context,
 							pvid, &resp->context);
-		*pvid = le16_to_cpu(vid);
+		if (pvid)
+			*pvid = le16_to_cpu(vid);
+		if (mode)
+			*mode = AMAP_GET_BITS(struct amap_get_hsw_resp_context,
+					      port_fwd_type, &resp->context);
 	}
 
 err:
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index 52f3d4c..d026226 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -1533,12 +1533,17 @@ struct be_cmd_req_set_mac_list {
 } __packed;
 
 /*********************** HSW Config ***********************/
+#define PORT_FWD_TYPE_VEPA		0x3
+#define PORT_FWD_TYPE_VEB		0x2
+
 struct amap_set_hsw_context {
 	u8 interface_id[16];
 	u8 rsvd0[14];
 	u8 pvid_valid;
-	u8 rsvd1;
-	u8 rsvd2[16];
+	u8 pport;
+	u8 rsvd1[6];
+	u8 port_fwd_type[3];
+	u8 rsvd2[7];
 	u8 pvid[16];
 	u8 rsvd3[32];
 	u8 rsvd4[32];
@@ -1563,7 +1568,9 @@ struct amap_get_hsw_req_context {
 } __packed;
 
 struct amap_get_hsw_resp_context {
-	u8 rsvd1[16];
+	u8 rsvd0[6];
+	u8 port_fwd_type[3];
+	u8 rsvd1[7];
 	u8 pvid[16];
 	u8 rsvd2[32];
 	u8 rsvd3[32];
@@ -1965,9 +1972,9 @@ extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array,
 extern int be_cmd_set_mac(struct be_adapter *adapter, u8 *mac, int if_id,
 			  u32 dom);
 extern int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
-			u32 domain, u16 intf_id);
+				 u32 domain, u16 intf_id, u16 hsw_mode);
 extern int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
-			u32 domain, u16 intf_id);
+				 u32 domain, u16 intf_id, u8 *mode);
 extern int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter);
 extern int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter,
 					  struct be_dma_mem *cmd);
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 50116f8..61f97dc 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -21,6 +21,7 @@
 #include "be_cmds.h"
 #include <asm/div64.h>
 #include <linux/aer.h>
+#include <linux/if_bridge.h>
 
 MODULE_VERSION(DRV_VER);
 MODULE_DEVICE_TABLE(pci, be_dev_ids);
@@ -1212,14 +1213,14 @@ static int be_set_vf_vlan(struct net_device *netdev,
 			adapter->vf_cfg[vf].vlan_tag = vlan;
 
 			status = be_cmd_set_hsw_config(adapter, vlan,
-				vf + 1, adapter->vf_cfg[vf].if_handle);
+				vf + 1, adapter->vf_cfg[vf].if_handle, 0);
 		}
 	} else {
 		/* Reset Transparent Vlan Tagging. */
 		adapter->vf_cfg[vf].vlan_tag = 0;
 		vlan = adapter->vf_cfg[vf].def_vid;
 		status = be_cmd_set_hsw_config(adapter, vlan, vf + 1,
-			adapter->vf_cfg[vf].if_handle);
+			adapter->vf_cfg[vf].if_handle, 0);
 	}
 
 
@@ -2917,7 +2918,7 @@ static int be_vf_setup(struct be_adapter *adapter)
 			vf_cfg->tx_rate = lnk_speed;
 
 		status = be_cmd_get_hsw_config(adapter, &def_vlan,
-					       vf + 1, vf_cfg->if_handle);
+					       vf + 1, vf_cfg->if_handle, NULL);
 		if (status)
 			goto err;
 		vf_cfg->def_vid = def_vlan;
@@ -3795,6 +3796,74 @@ fw_exit:
 	return status;
 }
 
+static int be_ndo_bridge_setlink(struct net_device *dev,
+				    struct nlmsghdr *nlh)
+{
+	struct be_adapter *adapter = netdev_priv(dev);
+	struct nlattr *attr, *br_spec;
+	int rem;
+	int status = 0;
+	u16 mode = 0;
+
+	if (!sriov_enabled(adapter))
+		return -EOPNOTSUPP;
+
+	br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
+
+	nla_for_each_nested(attr, br_spec, rem) {
+		if (nla_type(attr) != IFLA_BRIDGE_MODE)
+			continue;
+
+		mode = nla_get_u16(attr);
+		if (mode != BRIDGE_MODE_VEPA && mode != BRIDGE_MODE_VEB)
+			return -EINVAL;
+
+		status = be_cmd_set_hsw_config(adapter, 0, 0,
+					       adapter->if_handle,
+					       mode == BRIDGE_MODE_VEPA ?
+					       PORT_FWD_TYPE_VEPA :
+					       PORT_FWD_TYPE_VEB);
+		if (status)
+			goto err;
+
+		dev_info(&adapter->pdev->dev, "enabled switch mode: %s\n",
+			 mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB");
+
+		return status;
+	}
+err:
+	dev_err(&adapter->pdev->dev, "Failed to set switch mode %s\n",
+		mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB");
+
+	return status;
+}
+
+static int be_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
+				    struct net_device *dev,
+				    u32 filter_mask)
+{
+	struct be_adapter *adapter = netdev_priv(dev);
+	int status = 0;
+	u8 hsw_mode;
+
+	if (!sriov_enabled(adapter))
+		return 0;
+
+	/* BE and Lancer chips support VEB mode only */
+	if (BEx_chip(adapter) || lancer_chip(adapter)) {
+		hsw_mode = PORT_FWD_TYPE_VEB;
+	} else {
+		status = be_cmd_get_hsw_config(adapter, NULL, 0,
+					       adapter->if_handle, &hsw_mode);
+		if (status)
+			return 0;
+	}
+
+	return ndo_dflt_bridge_getlink(skb, pid, seq, dev,
+				       hsw_mode == PORT_FWD_TYPE_VEPA ?
+				       BRIDGE_MODE_VEPA : BRIDGE_MODE_VEB);
+}
+
 static const struct net_device_ops be_netdev_ops = {
 	.ndo_open		= be_open,
 	.ndo_stop		= be_close,
@@ -3813,6 +3882,8 @@ static const struct net_device_ops be_netdev_ops = {
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= be_netpoll,
 #endif
+	.ndo_bridge_setlink	= be_ndo_bridge_setlink,
+	.ndo_bridge_getlink	= be_ndo_bridge_getlink,
 };
 
 static void be_netdev_init(struct net_device *netdev)
-- 
1.7.1

^ permalink raw reply related

* Re: [PATCH] tcp: tcp_make_synack() should use sock_wmalloc
From: David Miller @ 2013-08-30 20:03 UTC (permalink / raw)
  To: kernel; +Cc: netdev, netfilter-devel, eric.dumazet, pablo
In-Reply-To: <20130827234140.GA3301@linuxace.com>

From: Phil Oester <kernel@linuxace.com>
Date: Tue, 27 Aug 2013 16:41:40 -0700

> In commit 90ba9b19 (tcp: tcp_make_synack() can use alloc_skb()), Eric changed
> the call to sock_wmalloc in tcp_make_synack to alloc_skb.  In doing so,
> the netfilter owner match lost its ability to block the SYNACK packet on
> outbound listening sockets.  Revert the change, restoring the owner match
> functionality.
> 
> This closes netfilter bugzilla #847.
> 
> Signed-off-by: Phil Oester <kernel@linuxace.com>

Applied and queued up for -stable, thanks.

Eric, I guess if you really want to get rid of the wmem atomics you
can just attach the socket and make a special destructor.  Maybe it
is not even worth it at that point however.

^ permalink raw reply

* Re: [PATCH v2] tipc: set sk_err correctly when connection fails
From: David Miller @ 2013-08-30 20:07 UTC (permalink / raw)
  To: paul.gortmaker
  Cc: erik.hugne, netdev, ying.xue, jon.maloy, tipc-discussion,
	nhan.tt.vo
In-Reply-To: <521F62AE.40101@windriver.com>

From: Paul Gortmaker <paul.gortmaker@windriver.com>
Date: Thu, 29 Aug 2013 11:03:10 -0400

> On 13-08-28 03:29 AM, erik.hugne@ericsson.com wrote:
>> From: Erik Hugne <erik.hugne@ericsson.com>
>> 
>> Should a connect fail, if the publication/server is unavailable or
>> due to some other error, a positive value will be returned and errno
>> is never set. If the application code checks for an explicit zero
>> return from connect (success) or a negative return (failure), it
>> will not catch the error and subsequent send() calls will fail as
>> shown from the strace snippet below.
>> 
>> socket(0x1e /* PF_??? */, SOCK_SEQPACKET, 0) = 3
>> connect(3, {sa_family=0x1e /* AF_??? */, sa_data="\2\1\322\4\0\0\322\4\0\0\0\0\0\0"}, 16) = 111
>> sendto(3, "test", 4, 0, NULL, 0)        = -1 EPIPE (Broken pipe)
>> 
>> The reason for this behaviour is that TIPC wrongly inverts error
>> codes set in sk_err.
>> 
>> Signed-off-by: Erik Hugne <erik.hugne@ericsson.com>
>> ---
>> 
>> [v2: add more details to commit message]
> 
> Thanks -- this now conveys the required triplet: 1) user visible symptom,
> 2) underlying technical cause, and 3) the why and how of the fix.

Applied and queued up for -stable, thanks everyone.

^ permalink raw reply

* Re: [PATCH v2 06/11] net: calxedaxgmac: fix race with tx queue stop/wake
From: Ben Hutchings @ 2013-08-30 17:12 UTC (permalink / raw)
  To: Rob Herring; +Cc: netdev, Lennert Buytenhek, Rob Herring
In-Reply-To: <1377832428-18117-6-git-send-email-robherring2@gmail.com>

On Thu, 2013-08-29 at 22:13 -0500, Rob Herring wrote:
> From: Rob Herring <rob.herring@calxeda.com>
> 
> Since the xgmac transmit start and completion work locklessly, it is
> possible for xgmac_xmit to stop the tx queue after the xgmac_tx_complete
> has run resulting in the tx queue never being woken up. Fix this by
> ensuring that ring buffer index updates are visible and recheck the ring
> space after stopping the queue.
> 
> The implementation used here was copied from
> drivers/net/ethernet/broadcom/tg3.c.
> 
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> ---
> v2:
> - drop netif_tx_lock
> - use netif_start_queue instead of netif_wake_queue
[...]
> @@ -1125,10 +1130,15 @@ static netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev)
>  
>  	priv->tx_head = dma_ring_incr(entry, DMA_TX_RING_SZ);
>  
> -	if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) <
> -	    MAX_SKB_FRAGS)
> +	/* Ensure tx_head update is visible to tx completion */
> +	smp_mb();
> +	if (unlikely(tx_dma_ring_space(priv) < MAX_SKB_FRAGS)) {
[...]

On re-reading, I see there's an off-by-one bug lingering here.  You use
up to 1 + MAX_SKB_FRAGS descriptors per skb.  So you must stop the queue
when the ring space is <= MAX_SKB_FRAGS.

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply

* Re: [PATCH net-next v10 11/11] ipv6: Add generic UDP Tunnel segmentation
From: Pravin Shelar @ 2013-08-30 21:14 UTC (permalink / raw)
  To: Cong Wang; +Cc: netdev, David S. Miller, Jesse Gross, Stephen Hemminger
In-Reply-To: <1377850563.2591.11.camel@cr0>

On Fri, Aug 30, 2013 at 1:16 AM, Cong Wang <amwang@redhat.com> wrote:
> On Wed, 2013-08-28 at 10:55 -0700, Pravin Shelar wrote:
>> On Tue, Aug 27, 2013 at 10:22 PM, Cong Wang <amwang@redhat.com> wrote:
>> > From: Cong Wang <amwang@redhat.com>
>> >
>> > Similar to commit 731362674580cb0c696cd1b1a03d8461a10cf90a
>> > (tunneling: Add generic Tunnel segmentation)
>> >
>> Can we factor out ipv4-udp-tunnel code so that there is no duplicating code?
>
> Probably we can, but it will make code review harder? Or you mean doing
> it in a separated patch? If you insist, I can do it in a separated
> patch.
>

I doubt it makes review any harder. But separate patch is also fine with me.

^ permalink raw reply

* Re: [PATCH] ipv4 tunnels: fix an oops when using ipip/sit with IPsec
From: David Miller @ 2013-08-30 21:14 UTC (permalink / raw)
  To: nicolas.dichtel; +Cc: netdev, pshelar, hongjun.li
In-Reply-To: <1377683690-4506-1-git-send-email-nicolas.dichtel@6wind.com>

From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Date: Wed, 28 Aug 2013 11:54:50 +0200

> From: Li Hongjun <hongjun.li@6wind.com>
> 
> Since commit 3d7b46cd20e3 (ip_tunnel: push generic protocol handling to
> ip_tunnel module.), an Oops is triggered when an xfrm policy is configured on
> an IPv4 over IPv4 tunnel.
> 
> xfrm4_policy_check() calls __xfrm_policy_check2(), which uses skb_dst(skb). But
> this field is NULL because iptunnel_pull_header() calls skb_dst_drop(skb).
> 
> Signed-off-by: Li Hongjun <hongjun.li@6wind.com>
> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>

Applied, thanks everyone.

^ permalink raw reply

* Re: 1f324e3 ipv6: Don't depend on per socket memory for neighbour discovery messages
From: Fabio Estevam @ 2013-08-30 21:19 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Thomas Graf, Eric Dumazet, Hannes Frederic Sowa, David S. Miller,
	linux-next@vger.kernel.org, netdev@vger.kernel.org
In-Reply-To: <5220F691.4020808@wwwdotorg.org>

On Fri, Aug 30, 2013 at 4:46 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> Commit 1f324e3 "ipv6: Don't depend on per socket memory for neighbour
> discovery messages" appears to cause issues for me. If I run
> next-20130830, I see the issue, but if I then just revert that one
> patch, I don't see any problem, and can use the network without issue.
>
> The problem is: with a network device enabled (in my case, a USB
> Ethernet dongle, although I don't know if the type is relevant), then
> the system appears to hang soon after enabling the interface; neither
> the serial console nor the framebuffer echo my typing, and the cursor on
> the framebuffer stops flashing. After a short delay, I see the following
> kernel spew:

I see the same problem on a ARM system (mx6 board) using the built-in
ethernet driver (fec).

^ permalink raw reply

* Re: [PATCH net-next] ipv6: Remove redundant sk variable
From: David Miller @ 2013-08-30 21:19 UTC (permalink / raw)
  To: tgraf; +Cc: netdev
In-Reply-To: <71fe125646ec6160be05138696d312c050e8b813.1377684285.git.tgraf@suug.ch>

From: Thomas Graf <tgraf@suug.ch>
Date: Wed, 28 Aug 2013 12:05:38 +0200

> A sk variable initialized to ndisc_sk is already available outside
> of the branch.
> 
> Signed-off-by: Thomas Graf <tgraf@suug.ch>

Applied, thanks.

^ permalink raw reply

* Re: [PATCH v5][net-next.git] driver:net:stmmac: Disable DMA store and forward mode if platform data force_thresh_dma_mode is set.
From: David Miller @ 2013-08-30 21:26 UTC (permalink / raw)
  To: peppe.cavallaro; +Cc: sonic.adi, netdev, adi-buildroot-devel, sonic.zhang
In-Reply-To: <521DE637.6030801@st.com>

From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
Date: Wed, 28 Aug 2013 13:59:51 +0200

> On 8/28/2013 12:55 PM, Sonic Zhang wrote:
>> From: Sonic Zhang <sonic.zhang@analog.com>
>>
>> Some synopsys ip implementation doesn't support DMA store and forward
>> mode,
>> such as BF60x. So, set force_thresh_dma_mode to use DMA thresholds
>> only.
>> Update document and devicetree as well.
>>
>> Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
> 
> Acked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>

Applied, thanks.

^ permalink raw reply

* Re: [PATCH] USB2NET : SR9700 : One Chip USB 1.1 USB2NET SR9700 Device Driver Support
From: David Miller @ 2013-08-30 21:30 UTC (permalink / raw)
  To: liujunliang_ljl
  Cc: horms, joe, romieu, gregkh, netdev, linux-usb, linux-kernel,
	sunhecheng
In-Reply-To: <1377746832-6201-1-git-send-email-liujunliang_ljl@163.com>


Please integrate the fixes Francois has proposed.

^ permalink raw reply

* Re: [PATCH] macvlan: fix typo in assignment
From: David Miller @ 2013-08-30 21:31 UTC (permalink / raw)
  To: ljaenicke; +Cc: netdev
In-Reply-To: <1377689671-28666-1-git-send-email-ljaenicke@innominate.com>

From: Lutz Jaenicke <ljaenicke@innominate.com>
Date: Wed, 28 Aug 2013 13:34:31 +0200

> commit 3b04ddde02cf1b6f14f2697da5c20eca5715017f
> "[NET]: Move hardware header operations out of netdevice."
> moved the handling into macvlan setup adding
>   dev->header_ops         = &macvlan_hard_header_ops,
> At the end of the line the ',' should have been a ';'
> 
> Signed-off-by: Lutz Jaenicke <ljaenicke@innominate.com>

This is a harmless error, because semantically it causes no bug.

So this is a cleanup and I've thus applied it to net-next, thanks.

^ permalink raw reply

* [PATCH v3 06/11] net: calxedaxgmac: fix race with tx queue stop/wake
From: Rob Herring @ 2013-08-30 21:35 UTC (permalink / raw)
  To: netdev; +Cc: Ben Hutchings, Lennert Buytenhek, Rob Herring
In-Reply-To: <1377832428-18117-6-git-send-email-robherring2@gmail.com>

From: Rob Herring <rob.herring@calxeda.com>

Since the xgmac transmit start and completion work locklessly, it is
possible for xgmac_xmit to stop the tx queue after the xgmac_tx_complete
has run resulting in the tx queue never being woken up. Fix this by
ensuring that ring buffer index updates are visible and recheck the ring
space after stopping the queue. Also fix an off-by-one bug where we need
to stop the queue when the ring buffer space is equal to MAX_SKB_FRAGS.

The implementation used here was copied from
drivers/net/ethernet/broadcom/tg3.c.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
v3:
- Fix off-by-one bug in queue stopping

v2:
- drop netif_tx_lock
- use netif_start_queue instead of netif_wake_queue

 drivers/net/ethernet/calxeda/xgmac.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index f630855..5d0b61a 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -410,6 +410,9 @@ struct xgmac_priv {
 #define dma_ring_space(h, t, s)	CIRC_SPACE(h, t, s)
 #define dma_ring_cnt(h, t, s)	CIRC_CNT(h, t, s)
 
+#define tx_dma_ring_space(p) \
+	dma_ring_space((p)->tx_head, (p)->tx_tail, DMA_TX_RING_SZ)
+
 /* XGMAC Descriptor Access Helpers */
 static inline void desc_set_buf_len(struct xgmac_dma_desc *p, u32 buf_sz)
 {
@@ -886,8 +889,10 @@ static void xgmac_tx_complete(struct xgmac_priv *priv)
 		priv->tx_tail = dma_ring_incr(entry, DMA_TX_RING_SZ);
 	}
 
-	if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) >
-	    MAX_SKB_FRAGS)
+	/* Ensure tx_tail is visible to xgmac_xmit */
+	smp_mb();
+	if (unlikely(netif_queue_stopped(priv->dev) &&
+	    (tx_dma_ring_space(priv) > MAX_SKB_FRAGS)))
 		netif_wake_queue(priv->dev);
 }
 
@@ -1125,10 +1130,15 @@ static netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	priv->tx_head = dma_ring_incr(entry, DMA_TX_RING_SZ);
 
-	if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) <
-	    MAX_SKB_FRAGS)
+	/* Ensure tx_head update is visible to tx completion */
+	smp_mb();
+	if (unlikely(tx_dma_ring_space(priv) <= MAX_SKB_FRAGS)) {
 		netif_stop_queue(dev);
-
+		/* Ensure netif_stop_queue is visible to tx completion */
+		smp_mb();
+		if (tx_dma_ring_space(priv) > MAX_SKB_FRAGS)
+			netif_start_queue(dev);
+	}
 	return NETDEV_TX_OK;
 }
 
-- 
1.8.1.2

^ permalink raw reply related

* Re: [PATCH v3 06/11] net: calxedaxgmac: fix race with tx queue stop/wake
From: David Miller @ 2013-08-30 21:41 UTC (permalink / raw)
  To: robherring2; +Cc: netdev, bhutchings, buytenh, rob.herring
In-Reply-To: <1377898533-12999-1-git-send-email-robherring2@gmail.com>


When you post a new version of a patch, you must repost the entire series,
not just the patch which is changing.

Thank you.

^ permalink raw reply

* Re: [PATCH 01/31] net: ax88796: use dev_get_platdata()
From: David Miller @ 2013-08-30 21:45 UTC (permalink / raw)
  To: jg1.han; +Cc: netdev
In-Reply-To: <003101cea53b$9fc95b30$df5c1190$%han@samsung.com>


I've applied all of the networking patchs of this series to net-next,
thanks.

^ permalink raw reply

* Re: [PATCH] net: revert 8728c544a9c ("net: dev_pick_tx() fix")
From: David Miller @ 2013-08-30 21:48 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev, alexander.h.duyck, xii, therbert, nuclearcat
In-Reply-To: <1377738643.8277.25.camel@edumazet-glaptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 28 Aug 2013 18:10:43 -0700

> From: Eric Dumazet <edumazet@google.com>
> 
> commit 8728c544a9cbdc ("net: dev_pick_tx() fix") and commit
> b6fe83e9525a ("bonding: refine IFF_XMIT_DST_RELEASE capability")
> are quite incompatible : Queue selection is disabled because skb
> dst was dropped before entering bonding device.
> 
> This causes major performance regression, mainly because TCP packets
> for a given flow can be sent to multiple queues.
> 
> This is particularly visible when using the new FQ packet scheduler
> with MQ + FQ setup on the slaves.
> 
> We can safely revert the first commit now that 416186fbf8c5b
> ("net: Split core bits of netdev_pick_tx into __netdev_pick_tx")
> properly caps the queue_index.
> 
> Reported-by: Xi Wang <xii@google.com>
> Diagnosed-by: Xi Wang <xii@google.com>
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Applied, thanks Eric.

^ permalink raw reply

* [PATCH v3 01/11] net: calxedaxgmac: remove NETIF_F_FRAGLIST setting
From: Rob Herring @ 2013-08-30 21:49 UTC (permalink / raw)
  To: netdev; +Cc: Ben Hutchings, Lennert Buytenhek, Rob Herring

From: Rob Herring <rob.herring@calxeda.com>

The xgmac does not actually handle frag lists, so this option should not
be set. It does not appear to have had any impact though.

Reported-by: Lennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 drivers/net/ethernet/calxeda/xgmac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index 7cb148c..71f6720 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -1759,7 +1759,7 @@ static int xgmac_probe(struct platform_device *pdev)
 	if (device_can_wakeup(priv->device))
 		priv->wolopts = WAKE_MAGIC;	/* Magic Frame as default */
 
-	ndev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA;
+	ndev->hw_features = NETIF_F_SG | NETIF_F_HIGHDMA;
 	if (readl(priv->base + XGMAC_DMA_HW_FEATURE) & DMA_HW_FEAT_TXCOESEL)
 		ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
 				     NETIF_F_RXCSUM;
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH v3 02/11] net: calxedaxgmac: read correct field in xgmac_desc_get_buf_len
From: Rob Herring @ 2013-08-30 21:49 UTC (permalink / raw)
  To: netdev; +Cc: Ben Hutchings, Lennert Buytenhek, Rob Herring
In-Reply-To: <1377899369-23252-1-git-send-email-robherring2@gmail.com>

From: Rob Herring <rob.herring@calxeda.com>

xgmac_desc_get_buf_len appears to have a copy/paste error. flags is the
wrong field to read. We should be reading buf_size field. cpu_to_le32
should also be le32_to_cpu. This never really mattered as this function
is only used for DMA mapping calls which happen to be nops with coherent
DMA.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 drivers/net/ethernet/calxeda/xgmac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index 71f6720..d41af68 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -421,7 +421,7 @@ static inline void desc_set_buf_len(struct xgmac_dma_desc *p, u32 buf_sz)
 
 static inline int desc_get_buf_len(struct xgmac_dma_desc *p)
 {
-	u32 len = cpu_to_le32(p->flags);
+	u32 len = le32_to_cpu(p->buf_size);
 	return (len & DESC_BUFFER1_SZ_MASK) +
 		((len & DESC_BUFFER2_SZ_MASK) >> DESC_BUFFER2_SZ_OFFSET);
 }
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH v3 03/11] net: calxedaxgmac: fix race between xgmac_tx_complete and xgmac_tx_err
From: Rob Herring @ 2013-08-30 21:49 UTC (permalink / raw)
  To: netdev; +Cc: Ben Hutchings, Lennert Buytenhek, Rob Herring
In-Reply-To: <1377899369-23252-1-git-send-email-robherring2@gmail.com>

From: Rob Herring <rob.herring@calxeda.com>

It is possible for the xgmac_tx_complete to run concurrently with
xgmac_tx_err since there are no locks. Fix this by moving the tx
error handling to a workqueue so we can disable napi while we reset
the transmitter.

Reported-by: Andreas Herrmann <andreas.herrmann@calxeda.com>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 drivers/net/ethernet/calxeda/xgmac.c | 38 +++++++++++++++++-------------------
 1 file changed, 18 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index d41af68..df7e3e2 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -393,6 +393,7 @@ struct xgmac_priv {
 	char rx_pause;
 	char tx_pause;
 	int wolopts;
+	struct work_struct tx_timeout_work;
 };
 
 /* XGMAC Configuration Settings */
@@ -897,21 +898,18 @@ static void xgmac_tx_complete(struct xgmac_priv *priv)
 		netif_wake_queue(priv->dev);
 }
 
-/**
- * xgmac_tx_err:
- * @priv: pointer to the private device structure
- * Description: it cleans the descriptors and restarts the transmission
- * in case of errors.
- */
-static void xgmac_tx_err(struct xgmac_priv *priv)
+static void xgmac_tx_timeout_work(struct work_struct *work)
 {
-	u32 reg, value, inten;
+	u32 reg, value;
+	struct xgmac_priv *priv =
+		container_of(work, struct xgmac_priv, tx_timeout_work);
 
-	netif_stop_queue(priv->dev);
+	napi_disable(&priv->napi);
 
-	inten = readl(priv->base + XGMAC_DMA_INTR_ENA);
 	writel(0, priv->base + XGMAC_DMA_INTR_ENA);
 
+	netif_tx_lock(priv->dev);
+
 	reg = readl(priv->base + XGMAC_DMA_CONTROL);
 	writel(reg & ~DMA_CONTROL_ST, priv->base + XGMAC_DMA_CONTROL);
 	do {
@@ -927,9 +925,15 @@ static void xgmac_tx_err(struct xgmac_priv *priv)
 
 	writel(DMA_STATUS_TU | DMA_STATUS_TPS | DMA_STATUS_NIS | DMA_STATUS_AIS,
 		priv->base + XGMAC_DMA_STATUS);
-	writel(inten, priv->base + XGMAC_DMA_INTR_ENA);
 
+	netif_tx_unlock(priv->dev);
 	netif_wake_queue(priv->dev);
+
+	napi_enable(&priv->napi);
+
+	/* Enable interrupts */
+	writel(DMA_INTR_DEFAULT_MASK, priv->base + XGMAC_DMA_STATUS);
+	writel(DMA_INTR_DEFAULT_MASK, priv->base + XGMAC_DMA_INTR_ENA);
 }
 
 static int xgmac_hw_init(struct net_device *dev)
@@ -1225,9 +1229,7 @@ static int xgmac_poll(struct napi_struct *napi, int budget)
 static void xgmac_tx_timeout(struct net_device *dev)
 {
 	struct xgmac_priv *priv = netdev_priv(dev);
-
-	/* Clear Tx resources and restart transmitting again */
-	xgmac_tx_err(priv);
+	schedule_work(&priv->tx_timeout_work);
 }
 
 /**
@@ -1366,7 +1368,6 @@ static irqreturn_t xgmac_pmt_interrupt(int irq, void *dev_id)
 static irqreturn_t xgmac_interrupt(int irq, void *dev_id)
 {
 	u32 intr_status;
-	bool tx_err = false;
 	struct net_device *dev = (struct net_device *)dev_id;
 	struct xgmac_priv *priv = netdev_priv(dev);
 	struct xgmac_extra_stats *x = &priv->xstats;
@@ -1396,16 +1397,12 @@ static irqreturn_t xgmac_interrupt(int irq, void *dev_id)
 		if (intr_status & DMA_STATUS_TPS) {
 			netdev_err(priv->dev, "transmit process stopped\n");
 			x->tx_process_stopped++;
-			tx_err = true;
+			schedule_work(&priv->tx_timeout_work);
 		}
 		if (intr_status & DMA_STATUS_FBI) {
 			netdev_err(priv->dev, "fatal bus error\n");
 			x->fatal_bus_error++;
-			tx_err = true;
 		}
-
-		if (tx_err)
-			xgmac_tx_err(priv);
 	}
 
 	/* TX/RX NORMAL interrupts */
@@ -1708,6 +1705,7 @@ static int xgmac_probe(struct platform_device *pdev)
 	ndev->netdev_ops = &xgmac_netdev_ops;
 	SET_ETHTOOL_OPS(ndev, &xgmac_ethtool_ops);
 	spin_lock_init(&priv->stats_lock);
+	INIT_WORK(&priv->tx_timeout_work, xgmac_tx_timeout_work);
 
 	priv->device = &pdev->dev;
 	priv->dev = ndev;
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH v3 04/11] net: calxedaxgmac: fix possible skb free before tx complete
From: Rob Herring @ 2013-08-30 21:49 UTC (permalink / raw)
  To: netdev; +Cc: Ben Hutchings, Lennert Buytenhek, Rob Herring
In-Reply-To: <1377899369-23252-1-git-send-email-robherring2@gmail.com>

From: Rob Herring <rob.herring@calxeda.com>

The TX completion code may have freed an skb before the entire sg list
was transmitted. The DMA unmap calls for the fragments could also get
skipped. Now set the skb pointer on every entry in the ring, not just
the head of the sg list. We then use the FS (first segment) bit in the
descriptors to determine skb head vs. fragment.

This also fixes similar bug in xgmac_free_tx_skbufs where clean-up of
a sg list that wraps at the end of the ring buffer would not get
unmapped.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 drivers/net/ethernet/calxeda/xgmac.c | 55 ++++++++++++++++--------------------
 1 file changed, 24 insertions(+), 31 deletions(-)

diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index df7e3e2..64854ad 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -470,6 +470,11 @@ static inline int desc_get_tx_ls(struct xgmac_dma_desc *p)
 	return le32_to_cpu(p->flags) & TXDESC_LAST_SEG;
 }
 
+static inline int desc_get_tx_fs(struct xgmac_dma_desc *p)
+{
+	return le32_to_cpu(p->flags) & TXDESC_FIRST_SEG;
+}
+
 static inline u32 desc_get_buf_addr(struct xgmac_dma_desc *p)
 {
 	return le32_to_cpu(p->buf1_addr);
@@ -796,7 +801,7 @@ static void xgmac_free_rx_skbufs(struct xgmac_priv *priv)
 
 static void xgmac_free_tx_skbufs(struct xgmac_priv *priv)
 {
-	int i, f;
+	int i;
 	struct xgmac_dma_desc *p;
 
 	if (!priv->tx_skbuff)
@@ -807,16 +812,15 @@ static void xgmac_free_tx_skbufs(struct xgmac_priv *priv)
 			continue;
 
 		p = priv->dma_tx + i;
-		dma_unmap_single(priv->device, desc_get_buf_addr(p),
-				 desc_get_buf_len(p), DMA_TO_DEVICE);
-
-		for (f = 0; f < skb_shinfo(priv->tx_skbuff[i])->nr_frags; f++) {
-			p = priv->dma_tx + i++;
+		if (desc_get_tx_fs(p))
+			dma_unmap_single(priv->device, desc_get_buf_addr(p),
+					 desc_get_buf_len(p), DMA_TO_DEVICE);
+		else
 			dma_unmap_page(priv->device, desc_get_buf_addr(p),
 				       desc_get_buf_len(p), DMA_TO_DEVICE);
-		}
 
-		dev_kfree_skb_any(priv->tx_skbuff[i]);
+		if (desc_get_tx_ls(p))
+			dev_kfree_skb_any(priv->tx_skbuff[i]);
 		priv->tx_skbuff[i] = NULL;
 	}
 }
@@ -853,8 +857,6 @@ static void xgmac_free_dma_desc_rings(struct xgmac_priv *priv)
  */
 static void xgmac_tx_complete(struct xgmac_priv *priv)
 {
-	int i;
-
 	while (dma_ring_cnt(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ)) {
 		unsigned int entry = priv->tx_tail;
 		struct sk_buff *skb = priv->tx_skbuff[entry];
@@ -864,33 +866,24 @@ static void xgmac_tx_complete(struct xgmac_priv *priv)
 		if (desc_get_owner(p))
 			break;
 
-		/* Verify tx error by looking at the last segment */
-		if (desc_get_tx_ls(p))
-			desc_get_tx_status(priv, p);
-
 		netdev_dbg(priv->dev, "tx ring: curr %d, dirty %d\n",
 			priv->tx_head, priv->tx_tail);
 
-		dma_unmap_single(priv->device, desc_get_buf_addr(p),
-				 desc_get_buf_len(p), DMA_TO_DEVICE);
-
-		priv->tx_skbuff[entry] = NULL;
-		priv->tx_tail = dma_ring_incr(entry, DMA_TX_RING_SZ);
-
-		if (!skb) {
-			continue;
-		}
-
-		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-			entry = priv->tx_tail = dma_ring_incr(priv->tx_tail,
-							      DMA_TX_RING_SZ);
-			p = priv->dma_tx + priv->tx_tail;
-
+		if (desc_get_tx_fs(p))
+			dma_unmap_single(priv->device, desc_get_buf_addr(p),
+					 desc_get_buf_len(p), DMA_TO_DEVICE);
+		else
 			dma_unmap_page(priv->device, desc_get_buf_addr(p),
 				       desc_get_buf_len(p), DMA_TO_DEVICE);
+
+		/* Check tx error on the last segment */
+		if (desc_get_tx_ls(p)) {
+			desc_get_tx_status(priv, p);
+			dev_kfree_skb(skb);
 		}
 
-		dev_kfree_skb(skb);
+		priv->tx_skbuff[entry] = NULL;
+		priv->tx_tail = dma_ring_incr(entry, DMA_TX_RING_SZ);
 	}
 
 	if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) >
@@ -1110,7 +1103,7 @@ static netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev)
 
 		entry = dma_ring_incr(entry, DMA_TX_RING_SZ);
 		desc = priv->dma_tx + entry;
-		priv->tx_skbuff[entry] = NULL;
+		priv->tx_skbuff[entry] = skb;
 
 		desc_set_buf_addr_and_size(desc, paddr, len);
 		if (i < (nfrags - 1))
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH v3 06/11] net: calxedaxgmac: fix race with tx queue stop/wake
From: Rob Herring @ 2013-08-30 21:49 UTC (permalink / raw)
  To: netdev; +Cc: Ben Hutchings, Lennert Buytenhek, Rob Herring
In-Reply-To: <1377899369-23252-1-git-send-email-robherring2@gmail.com>

From: Rob Herring <rob.herring@calxeda.com>

Since the xgmac transmit start and completion work locklessly, it is
possible for xgmac_xmit to stop the tx queue after the xgmac_tx_complete
has run resulting in the tx queue never being woken up. Fix this by
ensuring that ring buffer index updates are visible and recheck the ring
space after stopping the queue. Also fix an off-by-one bug where we need
to stop the queue when the ring buffer space is equal to MAX_SKB_FRAGS.

The implementation used here was copied from
drivers/net/ethernet/broadcom/tg3.c.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
v3:
- Fix off-by-one bug in queue stopping

v2:
- drop netif_tx_lock
- use netif_start_queue instead of netif_wake_queue

 drivers/net/ethernet/calxeda/xgmac.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index f630855..5d0b61a 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -410,6 +410,9 @@ struct xgmac_priv {
 #define dma_ring_space(h, t, s)	CIRC_SPACE(h, t, s)
 #define dma_ring_cnt(h, t, s)	CIRC_CNT(h, t, s)
 
+#define tx_dma_ring_space(p) \
+	dma_ring_space((p)->tx_head, (p)->tx_tail, DMA_TX_RING_SZ)
+
 /* XGMAC Descriptor Access Helpers */
 static inline void desc_set_buf_len(struct xgmac_dma_desc *p, u32 buf_sz)
 {
@@ -886,8 +889,10 @@ static void xgmac_tx_complete(struct xgmac_priv *priv)
 		priv->tx_tail = dma_ring_incr(entry, DMA_TX_RING_SZ);
 	}
 
-	if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) >
-	    MAX_SKB_FRAGS)
+	/* Ensure tx_tail is visible to xgmac_xmit */
+	smp_mb();
+	if (unlikely(netif_queue_stopped(priv->dev) &&
+	    (tx_dma_ring_space(priv) > MAX_SKB_FRAGS)))
 		netif_wake_queue(priv->dev);
 }
 
@@ -1125,10 +1130,15 @@ static netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	priv->tx_head = dma_ring_incr(entry, DMA_TX_RING_SZ);
 
-	if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) <
-	    MAX_SKB_FRAGS)
+	/* Ensure tx_head update is visible to tx completion */
+	smp_mb();
+	if (unlikely(tx_dma_ring_space(priv) <= MAX_SKB_FRAGS)) {
 		netif_stop_queue(dev);
-
+		/* Ensure netif_stop_queue is visible to tx completion */
+		smp_mb();
+		if (tx_dma_ring_space(priv) > MAX_SKB_FRAGS)
+			netif_start_queue(dev);
+	}
 	return NETDEV_TX_OK;
 }
 
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH v3 05/11] net: calxedaxgmac: update ring buffer tx_head after barriers
From: Rob Herring @ 2013-08-30 21:49 UTC (permalink / raw)
  To: netdev; +Cc: Ben Hutchings, Lennert Buytenhek, Rob Herring
In-Reply-To: <1377899369-23252-1-git-send-email-robherring2@gmail.com>

From: Rob Herring <rob.herring@calxeda.com>

Ensure that the descriptor writes are visible before the ring buffer head
is updated. Since writel is a barrier, we can simply update the head after
the writel.

Reported-by: Lennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 drivers/net/ethernet/calxeda/xgmac.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index 64854ad..f630855 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -1121,9 +1121,10 @@ static netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev)
 	wmb();
 	desc_set_tx_owner(first, desc_flags | TXDESC_FIRST_SEG);
 
+	writel(1, priv->base + XGMAC_DMA_TX_POLL);
+
 	priv->tx_head = dma_ring_incr(entry, DMA_TX_RING_SZ);
 
-	writel(1, priv->base + XGMAC_DMA_TX_POLL);
 	if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) <
 	    MAX_SKB_FRAGS)
 		netif_stop_queue(dev);
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH v3 07/11] net: calxedaxgmac: enable interrupts after napi_enable
From: Rob Herring @ 2013-08-30 21:49 UTC (permalink / raw)
  To: netdev; +Cc: Ben Hutchings, Lennert Buytenhek, Rob Herring
In-Reply-To: <1377899369-23252-1-git-send-email-robherring2@gmail.com>

From: Rob Herring <rob.herring@calxeda.com>

Fix a race condition where the interrupt handler may have called
napi_schedule before napi_enable is called. This would disable interrupts
and never actually schedule napi to run.

Reported-by: Lennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 drivers/net/ethernet/calxeda/xgmac.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index 5d0b61a..73d3f83 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -959,9 +959,7 @@ static int xgmac_hw_init(struct net_device *dev)
 		DMA_BUS_MODE_FB | DMA_BUS_MODE_ATDS | DMA_BUS_MODE_AAL;
 	writel(value, ioaddr + XGMAC_DMA_BUS_MODE);
 
-	/* Enable interrupts */
-	writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_STATUS);
-	writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_INTR_ENA);
+	writel(0, ioaddr + XGMAC_DMA_INTR_ENA);
 
 	/* Mask power mgt interrupt */
 	writel(XGMAC_INT_STAT_PMTIM, ioaddr + XGMAC_INT_STAT);
@@ -1029,6 +1027,10 @@ static int xgmac_open(struct net_device *dev)
 	napi_enable(&priv->napi);
 	netif_start_queue(dev);
 
+	/* Enable interrupts */
+	writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_STATUS);
+	writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_INTR_ENA);
+
 	return 0;
 }
 
-- 
1.8.1.2

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox