alistair23-linux/net/ipv4
Eric Dumazet 9650388b5c ipv4: arp: fix a lockdep splat in arp_solicit()
Yan Burman reported following lockdep warning :

=============================================
[ INFO: possible recursive locking detected ]
3.7.0+ #24 Not tainted
---------------------------------------------
swapper/1/0 is trying to acquire lock:
  (&n->lock){++--..}, at: [<ffffffff8139f56e>] __neigh_event_send
+0x2e/0x2f0

but task is already holding lock:
  (&n->lock){++--..}, at: [<ffffffff813f63f4>] arp_solicit+0x1d4/0x280

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

        CPU0
        ----
   lock(&n->lock);
   lock(&n->lock);

  *** DEADLOCK ***

  May be due to missing lock nesting notation

4 locks held by swapper/1/0:
  #0:  (((&n->timer))){+.-...}, at: [<ffffffff8104b350>]
call_timer_fn+0x0/0x1c0
  #1:  (&n->lock){++--..}, at: [<ffffffff813f63f4>] arp_solicit
+0x1d4/0x280
  #2:  (rcu_read_lock_bh){.+....}, at: [<ffffffff81395400>]
dev_queue_xmit+0x0/0x5d0
  #3:  (rcu_read_lock_bh){.+....}, at: [<ffffffff813cb41e>]
ip_finish_output+0x13e/0x640

stack backtrace:
Pid: 0, comm: swapper/1 Not tainted 3.7.0+ #24
Call Trace:
  <IRQ>  [<ffffffff8108c7ac>] validate_chain+0xdcc/0x11f0
  [<ffffffff8108d570>] ? __lock_acquire+0x440/0xc30
  [<ffffffff81120565>] ? kmem_cache_free+0xe5/0x1c0
  [<ffffffff8108d570>] __lock_acquire+0x440/0xc30
  [<ffffffff813c3570>] ? inet_getpeer+0x40/0x600
  [<ffffffff8108d570>] ? __lock_acquire+0x440/0xc30
  [<ffffffff8139f56e>] ? __neigh_event_send+0x2e/0x2f0
  [<ffffffff8108ddf5>] lock_acquire+0x95/0x140
  [<ffffffff8139f56e>] ? __neigh_event_send+0x2e/0x2f0
  [<ffffffff8108d570>] ? __lock_acquire+0x440/0xc30
  [<ffffffff81448d4b>] _raw_write_lock_bh+0x3b/0x50
  [<ffffffff8139f56e>] ? __neigh_event_send+0x2e/0x2f0
  [<ffffffff8139f56e>] __neigh_event_send+0x2e/0x2f0
  [<ffffffff8139f99b>] neigh_resolve_output+0x16b/0x270
  [<ffffffff813cb62d>] ip_finish_output+0x34d/0x640
  [<ffffffff813cb41e>] ? ip_finish_output+0x13e/0x640
  [<ffffffffa046f146>] ? vxlan_xmit+0x556/0xbec [vxlan]
  [<ffffffff813cb9a0>] ip_output+0x80/0xf0
  [<ffffffff813ca368>] ip_local_out+0x28/0x80
  [<ffffffffa046f25a>] vxlan_xmit+0x66a/0xbec [vxlan]
  [<ffffffffa046f146>] ? vxlan_xmit+0x556/0xbec [vxlan]
  [<ffffffff81394a50>] ? skb_gso_segment+0x2b0/0x2b0
  [<ffffffff81449355>] ? _raw_spin_unlock_irqrestore+0x65/0x80
  [<ffffffff81394c57>] ? dev_queue_xmit_nit+0x207/0x270
  [<ffffffff813950c8>] dev_hard_start_xmit+0x298/0x5d0
  [<ffffffff813956f3>] dev_queue_xmit+0x2f3/0x5d0
  [<ffffffff81395400>] ? dev_hard_start_xmit+0x5d0/0x5d0
  [<ffffffff813f5788>] arp_xmit+0x58/0x60
  [<ffffffff813f59db>] arp_send+0x3b/0x40
  [<ffffffff813f6424>] arp_solicit+0x204/0x280
  [<ffffffff813a1a70>] ? neigh_add+0x310/0x310
  [<ffffffff8139f515>] neigh_probe+0x45/0x70
  [<ffffffff813a1c10>] neigh_timer_handler+0x1a0/0x2a0
  [<ffffffff8104b3cf>] call_timer_fn+0x7f/0x1c0
  [<ffffffff8104b350>] ? detach_if_pending+0x120/0x120
  [<ffffffff8104b748>] run_timer_softirq+0x238/0x2b0
  [<ffffffff813a1a70>] ? neigh_add+0x310/0x310
  [<ffffffff81043e51>] __do_softirq+0x101/0x280
  [<ffffffff814518cc>] call_softirq+0x1c/0x30
  [<ffffffff81003b65>] do_softirq+0x85/0xc0
  [<ffffffff81043a7e>] irq_exit+0x9e/0xc0
  [<ffffffff810264f8>] smp_apic_timer_interrupt+0x68/0xa0
  [<ffffffff8145122f>] apic_timer_interrupt+0x6f/0x80
  <EOI>  [<ffffffff8100a054>] ? mwait_idle+0xa4/0x1c0
  [<ffffffff8100a04b>] ? mwait_idle+0x9b/0x1c0
  [<ffffffff8100a6a9>] cpu_idle+0x89/0xe0
  [<ffffffff81441127>] start_secondary+0x1b2/0x1b6

Bug is from arp_solicit(), releasing the neigh lock after arp_send()
In case of vxlan, we eventually need to write lock a neigh lock later.

Its a false positive, but we can get rid of it without lockdep
annotations.

We can instead use neigh_ha_snapshot() helper.

Reported-by: Yan Burman <yanb@mellanox.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2012-12-21 13:14:07 -08:00
..
netfilter net: remove obsolete simple_strto<foo> 2012-12-10 14:09:00 -05:00
af_inet.c net: Make CAP_NET_BIND_SERVICE per user namespace 2012-11-18 20:33:37 -05:00
ah4.c
arp.c ipv4: arp: fix a lockdep splat in arp_solicit() 2012-12-21 13:14:07 -08:00
cipso_ipv4.c
datagram.c
devinet.c netconf: advertise mc_forwarding status 2012-12-04 13:08:10 -05:00
esp4.c
fib_frontend.c net: Enable a userns root rtnl calls that are safe for unprivilged users 2012-11-18 20:33:36 -05:00
fib_lookup.h
fib_rules.c sections: fix section conflicts in net 2012-10-06 03:04:45 +09:00
fib_semantics.c ipv4: 16 slots in initial fib_info hash table 2012-10-22 14:29:06 -04:00
fib_trie.c ipv4/route: arg delay is useless in rt_cache_flush() 2012-09-18 15:44:34 -04:00
gre.c
icmp.c ipv4: avoid passing NULL to inet_putpeer() in icmpv4_xrlim_allow() 2012-11-26 17:24:41 -05:00
igmp.c igmp: export symbol ip_mc_leave_group 2012-10-01 18:39:44 -04:00
inet_connection_sock.c inet: Fix kmemleak in tcp_v4/6_syn_recv_sock and dccp_v4/6_request_recv_sock 2012-12-14 13:14:07 -05:00
inet_diag.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2012-12-12 18:07:07 -08:00
inet_fragment.c ipv6: unify fragment thresh handling code 2012-09-19 17:23:28 -04:00
inet_hashtables.c net: move inet_dport/inet_num in sock_common 2012-11-30 15:02:56 -05:00
inet_lro.c
inet_timewait_sock.c
inetpeer.c Merge branch 'for-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq 2012-10-02 09:54:49 -07:00
ip_forward.c ipv4: introduce rt_uses_gateway 2012-10-08 17:42:36 -04:00
ip_fragment.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2012-12-12 18:07:07 -08:00
ip_gre.c ip_gre: fix possible use after free 2012-12-21 13:14:01 -08:00
ip_input.c net: TCP early demux cleanup 2012-07-30 14:53:21 -07:00
ip_options.c net: Allow userns root to control ipv4 2012-11-18 20:32:45 -05:00
ip_output.c net: Handle encapsulated offloads before fragmentation or handing to lower dev 2012-12-09 00:20:28 -05:00
ip_sockglue.c net: Allow userns root to control ipv4 2012-11-18 20:32:45 -05:00
ip_vti.c net: Allow userns root to control ipv4 2012-11-18 20:32:45 -05:00
ipcomp.c
ipconfig.c net/ipv4/ipconfig: add device address to a KERN_INFO message 2012-10-31 13:23:00 -04:00
ipip.c net: Allow userns root to control ipv4 2012-11-18 20:32:45 -05:00
ipmr.c ipmr: advertise new mfc entries via rtnl 2012-12-04 13:08:11 -05:00
Kconfig
Makefile memcg: rename config variables 2012-07-31 18:42:43 -07:00
netfilter.c netfilter: properly annotate ipv4_netfilter_{init,fini}() 2012-09-03 13:56:04 +02:00
ping.c userns: Use kgids for sysctl_ping_group_range 2012-08-14 21:49:10 -07:00
proc.c tcp: TCP Fast Open Server - header & support functions 2012-08-31 20:02:18 -04:00
protocol.c net: Add net protocol offload registration infrustructure 2012-11-15 17:36:17 -05:00
raw.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace 2012-10-02 11:11:09 -07:00
route.c ipv4/route/rtnl: get mcast attributes when dst is multicast 2012-12-07 12:24:33 -05:00
syncookies.c tcp: better retrans tracking for defer-accept 2012-11-03 14:45:00 -04:00
sysctl_net_ipv4.c net: Don't export sysctls to unprivileged users 2012-11-18 20:30:55 -05:00
tcp.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2012-12-12 18:07:07 -08:00
tcp_bic.c
tcp_cong.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2012-12-13 12:00:02 -08:00
tcp_cubic.c
tcp_diag.c
tcp_fastopen.c tcp: TCP Fast Open Server - header & support functions 2012-08-31 20:02:18 -04:00
tcp_highspeed.c
tcp_htcp.c
tcp_hybla.c
tcp_illinois.c net: fix divide by zero in tcp algorithm illinois 2012-11-01 11:55:59 -04:00
tcp_input.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2012-12-12 18:07:07 -08:00
tcp_ipv4.c inet: Fix kmemleak in tcp_v4/6_syn_recv_sock and dccp_v4/6_request_recv_sock 2012-12-14 13:14:07 -05:00
tcp_lp.c
tcp_memcontrol.c
tcp_metrics.c tcp: handle tcp_net_metrics_init() order-5 memory allocation failures 2012-11-16 13:36:27 -05:00
tcp_minisocks.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2012-11-10 18:32:51 -05:00
tcp_output.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2012-12-12 18:07:07 -08:00
tcp_probe.c
tcp_scalable.c
tcp_timer.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2012-11-10 18:32:51 -05:00
tcp_vegas.c
tcp_vegas.h
tcp_veno.c
tcp_westwood.c
tcp_yeah.c
tunnel4.c
udp.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace 2012-10-02 11:11:09 -07:00
udp_diag.c netlink: Rename pid to portid to avoid confusion 2012-09-10 15:30:41 -04:00
udp_impl.h
udplite.c
xfrm4_input.c ipv4: Fix input route performance regression. 2012-07-26 15:50:39 -07:00
xfrm4_mode_beet.c
xfrm4_mode_transport.c
xfrm4_mode_tunnel.c
xfrm4_output.c
xfrm4_policy.c xfrm: Fix the gc threshold value for ipv4 2012-11-13 09:15:07 +01:00
xfrm4_state.c
xfrm4_tunnel.c