linux/net/ipv6
Ben Hutchings f9b6caca04 ipv6: addrconf: Avoid calling netdevice notifiers with RCU read-side lock
[ Upstream commit 4acd4945cd ]

Cong Wang reports that lockdep detected suspicious RCU usage while
enabling IPV6 forwarding:

 [ 1123.310275] ===============================
 [ 1123.442202] [ INFO: suspicious RCU usage. ]
 [ 1123.558207] 3.6.0-rc1+ #109 Not tainted
 [ 1123.665204] -------------------------------
 [ 1123.768254] include/linux/rcupdate.h:430 Illegal context switch in RCU read-side critical section!
 [ 1123.992320]
 [ 1123.992320] other info that might help us debug this:
 [ 1123.992320]
 [ 1124.307382]
 [ 1124.307382] rcu_scheduler_active = 1, debug_locks = 0
 [ 1124.522220] 2 locks held by sysctl/5710:
 [ 1124.648364]  #0:  (rtnl_mutex){+.+.+.}, at: [<ffffffff81768498>] rtnl_trylock+0x15/0x17
 [ 1124.882211]  #1:  (rcu_read_lock){.+.+.+}, at: [<ffffffff81871df8>] rcu_lock_acquire+0x0/0x29
 [ 1125.085209]
 [ 1125.085209] stack backtrace:
 [ 1125.332213] Pid: 5710, comm: sysctl Not tainted 3.6.0-rc1+ #109
 [ 1125.441291] Call Trace:
 [ 1125.545281]  [<ffffffff8109d915>] lockdep_rcu_suspicious+0x109/0x112
 [ 1125.667212]  [<ffffffff8107c240>] rcu_preempt_sleep_check+0x45/0x47
 [ 1125.781838]  [<ffffffff8107c260>] __might_sleep+0x1e/0x19b
[...]
 [ 1127.445223]  [<ffffffff81757ac5>] call_netdevice_notifiers+0x4a/0x4f
[...]
 [ 1127.772188]  [<ffffffff8175e125>] dev_disable_lro+0x32/0x6b
 [ 1127.885174]  [<ffffffff81872d26>] dev_forward_change+0x30/0xcb
 [ 1128.013214]  [<ffffffff818738c4>] addrconf_forward_change+0x85/0xc5
[...]

addrconf_forward_change() uses RCU iteration over the netdev list,
which is unnecessary since it already holds the RTNL lock.  We also
cannot reasonably require netdevice notifier functions not to sleep.

Reported-by: Cong Wang <amwang@redhat.com>
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-10-02 09:47:05 -07:00
..
netfilter netfilter: fix looped (broad|multi)cast's MAC handling 2011-06-16 17:27:04 +02:00
addrconf_core.c
addrconf.c ipv6: addrconf: Avoid calling netdevice notifiers with RCU read-side lock 2012-10-02 09:47:05 -07:00
addrlabel.c
af_inet6.c ipv6: make fragment identifications less predictable 2011-08-15 18:31:37 -07:00
ah6.c ah: Don't return NET_XMIT_DROP on input. 2012-02-03 09:18:54 -08:00
anycast.c inet: constify ip headers and in6_addr 2011-04-22 11:04:14 -07:00
datagram.c net: Put fl6_* macros to struct flowi6 and use them again. 2011-03-12 15:08:55 -08:00
esp6.c xfrm: take net hdr len into account for esp payload size calculation 2012-06-10 00:33:03 +09:00
exthdrs_core.c
exthdrs.c ipv6: Convert to use flowi6 where applicable. 2011-03-12 15:08:54 -08:00
fib6_rules.c ipv6: Convert to use flowi6 where applicable. 2011-03-12 15:08:54 -08:00
icmp.c inet: constify ip headers and in6_addr 2011-04-22 11:04:14 -07:00
inet6_connection_sock.c inet: Pass flowi to ->queue_xmit(). 2011-05-08 15:28:28 -07:00
inet6_hashtables.c net: Compute protocol sequence numbers and fragment IDs using MD5. 2011-08-15 18:31:35 -07:00
ip6_fib.c net: fix NULL dereferences in check_peer_redir() 2012-02-13 11:06:13 -08:00
ip6_flowlabel.c ipv6: Convert to use flowi6 where applicable. 2011-03-12 15:08:54 -08:00
ip6_input.c inet: constify ip headers and in6_addr 2011-04-22 11:04:14 -07:00
ip6_output.c ipv6: fix incorrect ipsec fragment 2012-06-10 00:33:02 +09:00
ip6_tunnel.c ip6_tunnel: copy parms.name after register_netdevice 2011-11-26 09:09:55 -08:00
ip6mr.c ipv6-multicast: Fix memory leak in IPv6 multicast. 2012-02-29 16:33:51 -08:00
ipcomp6.c inet: constify ip headers and in6_addr 2011-04-22 11:04:14 -07:00
ipv6_sockglue.c ipv6: Fix ipv6_getsockopt for IPV6_2292PKTOPTIONS 2011-10-03 11:40:52 -07:00
Kconfig
Makefile
mcast.c ipv6: fix array index in ip6_mc_add_src() 2012-04-27 09:51:19 -07:00
mip6.c inet: constify ip headers and in6_addr 2011-04-22 11:04:14 -07:00
ndisc.c net: fix NULL dereferences in check_peer_redir() 2012-02-13 11:06:13 -08:00
netfilter.c inet: constify ip headers and in6_addr 2011-04-22 11:04:14 -07:00
proc.c ipv6: reduce per device ICMP mib sizes 2011-05-19 16:21:22 -04:00
protocol.c
raw.c net: convert %p usage to %pK 2011-05-24 01:13:12 -04:00
reassembly.c inet: constify ip headers and in6_addr 2011-04-22 11:04:14 -07:00
route.c ipv6: Move ipv6 proc file registration to end of init order 2012-07-16 08:47:37 -07:00
sit.c net: fix NULL dereferences in check_peer_redir() 2012-02-13 11:06:13 -08:00
syncookies.c tcp: initialize variable ecn_ok in syncookies path 2011-10-03 11:40:54 -07:00
sysctl_net_ipv6.c net ipv6: Fix duplicate /proc/sys/net/ipv6/neigh directory entries. 2011-03-21 18:23:34 -07:00
tcp_ipv6.c tcp: fix TCP_MAXSEG for established IPv6 passive sockets 2012-04-27 09:51:21 -07:00
tunnel6.c
udp_impl.h
udp.c ipv6: fix NULL dereference in udp6_ufo_fragment() 2011-10-16 14:14:54 -07:00
udplite.c
xfrm6_input.c
xfrm6_mode_beet.c ipsec: be careful of non existing mac headers 2012-03-19 08:57:45 -07:00
xfrm6_mode_ro.c
xfrm6_mode_transport.c
xfrm6_mode_tunnel.c ipsec: be careful of non existing mac headers 2012-03-19 08:57:45 -07:00
xfrm6_output.c xfrm: Assign the inner mode output function to the dst entry 2011-05-10 15:03:34 -07:00
xfrm6_policy.c inet: constify ip headers and in6_addr 2011-04-22 11:04:14 -07:00
xfrm6_state.c xfrm: Assign the inner mode output function to the dst entry 2011-05-10 15:03:34 -07:00
xfrm6_tunnel.c ipv6: Fix return of xfrm6_tunnel_rcv() 2011-05-24 01:11:51 -04:00