> On Mon, 2016-02-01 at 11:37 -0800, Eric Dumazet wrote: > >> I would rather try : >> >> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c >> index 38eeddedfc21..d6b7ab07f914 100644 >> --- a/net/ipv6/addrconf.c >> +++ b/net/ipv6/addrconf.c >> @@ -3538,6 +3538,7 @@ static void addrconf_dad_begin(struct inet6_ifaddr >> *ifp) >> { >> struct inet6_dev *idev = ifp->idev; >> struct net_device *dev = idev->dev; >> + bool notify = false; >> >> addrconf_join_solict(dev, &ifp->addr); >> >> @@ -3583,7 +3584,8 @@ static void addrconf_dad_begin(struct inet6_ifaddr >> *ifp) >> /* Because optimistic nodes can use this address, >> * notify listeners. If DAD fails, RTM_DELADDR is sent. >> */ >> - ipv6_ifa_notify(RTM_NEWADDR, ifp); >> + notify = true; >> + in6_ifa_hold(ifp); > > Actually the in6_ifa_hold() is not needed. > >> } >> } >> >> @@ -3591,6 +3593,10 @@ static void addrconf_dad_begin(struct >> inet6_ifaddr *ifp) >> out: >> spin_unlock(&ifp->lock); >> read_unlock_bh(&idev->lock); >> + if (notify) { >> + ipv6_ifa_notify(RTM_NEWADDR, ifp); >> + in6_ifa_put(ifp); > > And in6_ifa_put() not needed once in6_ifa_hold() is removed. > >> + } >> } >> >> static void addrconf_dad_start(struct inet6_ifaddr *ifp) >> >>
Thanks Eric. I tested the scenario with your suggestion and I don't see a RCU stall now. I will send out v2 of this patch.