diff mbox series

[net-next] ipv6: addrconf: fix a lockdep splat

Message ID 1510006409.2849.88.camel@edumazet-glaptop3.roam.corp.google.com
State Accepted, archived
Delegated to: David Miller
Headers show
Series [net-next] ipv6: addrconf: fix a lockdep splat | expand

Commit Message

Eric Dumazet Nov. 6, 2017, 10:13 p.m. UTC
From: Eric Dumazet <edumazet@google.com>

Fixes a case where GFP_ATOMIC allocation must be used instead of
GFP_KERNEL one.

[   54.891146]  lock_acquire+0xb3/0x2f0
[   54.891153]  ? fs_reclaim_acquire.part.60+0x5/0x30
[   54.891165]  fs_reclaim_acquire.part.60+0x29/0x30
[   54.891170]  ? fs_reclaim_acquire.part.60+0x5/0x30
[   54.891178]  kmem_cache_alloc_trace+0x3f/0x500
[   54.891186]  ? cyc2ns_read_end+0x1e/0x30
[   54.891196]  ipv6_add_addr+0x15a/0xc30
[   54.891217]  ? ipv6_create_tempaddr+0x2ea/0x5d0
[   54.891223]  ipv6_create_tempaddr+0x2ea/0x5d0
[   54.891238]  ? manage_tempaddrs+0x195/0x220
[   54.891249]  ? addrconf_prefix_rcv_add_addr+0x1c0/0x4f0
[   54.891255]  addrconf_prefix_rcv_add_addr+0x1c0/0x4f0
[   54.891268]  addrconf_prefix_rcv+0x2e5/0x9b0
[   54.891279]  ? neigh_update+0x446/0xb90
[   54.891298]  ? ndisc_router_discovery+0x5ab/0xf00
[   54.891303]  ndisc_router_discovery+0x5ab/0xf00
[   54.891311]  ? retint_kernel+0x2d/0x2d
[   54.891331]  ndisc_rcv+0x1b6/0x270
[   54.891340]  icmpv6_rcv+0x6aa/0x9f0
[   54.891345]  ? ipv6_chk_mcast_addr+0x176/0x530
[   54.891351]  ? do_csum+0x17b/0x260
[   54.891360]  ip6_input_finish+0x194/0xb20
[   54.891372]  ip6_input+0x5b/0x2c0
[   54.891380]  ? ip6_rcv_finish+0x320/0x320
[   54.891389]  ip6_mc_input+0x15a/0x250
[   54.891396]  ipv6_rcv+0x772/0x1050
[   54.891403]  ? consume_skb+0xbe/0x2d0
[   54.891412]  ? ip6_make_skb+0x2a0/0x2a0
[   54.891418]  ? ip6_input+0x2c0/0x2c0
[   54.891425]  __netif_receive_skb_core+0xa0f/0x1600
[   54.891436]  ? process_backlog+0xac/0x400
[   54.891441]  process_backlog+0xfa/0x400
[   54.891448]  ? net_rx_action+0x145/0x1130
[   54.891456]  net_rx_action+0x310/0x1130
[   54.891524]  ? RTUSBBulkReceive+0x11d/0x190 [mt7610u_sta]
[   54.891538]  __do_softirq+0x140/0xaba
[   54.891553]  irq_exit+0x10b/0x160
[   54.891561]  do_IRQ+0xbb/0x1b0

Fixes: f3d9832e56c4 ("ipv6: addrconf: cleanup locking in ipv6_add_addr")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Valdis Kletnieks <valdis.kletnieks@vt.edu>
---
 net/ipv6/addrconf.c |   12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

Comments

David Ahern Nov. 7, 2017, 12:50 a.m. UTC | #1
On 11/7/17 7:13 AM, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
> 
> Fixes a case where GFP_ATOMIC allocation must be used instead of
> GFP_KERNEL one.
> 
...
> 
> Fixes: f3d9832e56c4 ("ipv6: addrconf: cleanup locking in ipv6_add_addr")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Reported-by: Valdis Kletnieks <valdis.kletnieks@vt.edu>
> ---
>  net/ipv6/addrconf.c |   12 +++++++-----
>  1 file changed, 7 insertions(+), 5 deletions(-)
> 

Acked-by: David Ahern <dsahern@gmail.com>
Tested-by: David Ahern <dsahern@gmail.com>
David Miller Nov. 7, 2017, 1:52 a.m. UTC | #2
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Mon, 06 Nov 2017 14:13:29 -0800

> From: Eric Dumazet <edumazet@google.com>
> 
> Fixes a case where GFP_ATOMIC allocation must be used instead of
> GFP_KERNEL one.
 ...
> Fixes: f3d9832e56c4 ("ipv6: addrconf: cleanup locking in ipv6_add_addr")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Reported-by: Valdis Kletnieks <valdis.kletnieks@vt.edu>

Applied, thanks.
diff mbox series

Patch

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 66d8c3d912fdb3de8d1bc157e8e7fe3750fd9005..6233e06fa35cf2030ac7d7575b9a51f336f2bea4 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1267,7 +1267,9 @@  static void ipv6_del_addr(struct inet6_ifaddr *ifp)
 	in6_ifa_put(ifp);
 }
 
-static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *ift)
+static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp,
+				struct inet6_ifaddr *ift,
+				bool block)
 {
 	struct inet6_dev *idev = ifp->idev;
 	struct in6_addr addr, *tmpaddr;
@@ -1371,7 +1373,7 @@  static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i
 
 	ift = ipv6_add_addr(idev, &addr, NULL, tmp_plen,
 			    ipv6_addr_scope(&addr), addr_flags,
-			    tmp_valid_lft, tmp_prefered_lft, true, NULL);
+			    tmp_valid_lft, tmp_prefered_lft, block, NULL);
 	if (IS_ERR(ift)) {
 		in6_ifa_put(ifp);
 		in6_dev_put(idev);
@@ -1956,7 +1958,7 @@  static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed)
 		if (ifpub) {
 			in6_ifa_hold(ifpub);
 			spin_unlock_bh(&ifp->lock);
-			ipv6_create_tempaddr(ifpub, ifp);
+			ipv6_create_tempaddr(ifpub, ifp, true);
 			in6_ifa_put(ifpub);
 		} else {
 			spin_unlock_bh(&ifp->lock);
@@ -2456,7 +2458,7 @@  static void manage_tempaddrs(struct inet6_dev *idev,
 		 * no temporary address currently exists.
 		 */
 		read_unlock_bh(&idev->lock);
-		ipv6_create_tempaddr(ifp, NULL);
+		ipv6_create_tempaddr(ifp, NULL, false);
 	} else {
 		read_unlock_bh(&idev->lock);
 	}
@@ -4351,7 +4353,7 @@  static void addrconf_verify_rtnl(void)
 						spin_lock(&ifpub->lock);
 						ifpub->regen_count = 0;
 						spin_unlock(&ifpub->lock);
-						ipv6_create_tempaddr(ifpub, ifp);
+						ipv6_create_tempaddr(ifpub, ifp, true);
 						in6_ifa_put(ifpub);
 						in6_ifa_put(ifp);
 						goto restart;