From: Eric Dumazet <eric.duma...@gmail.com> Date: Fri, 04 Mar 2016 16:08:30 -0800
> __inet_del_ifa() should probably take into account in_dev->dead (no > promotion, no list scan...) Indeed, that is the real problem: diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 8c3df2c..7412feb 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -334,6 +334,12 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, ASSERT_RTNL(); + /* None of these potentially quadratic scans matter if the + * device is being destroyed. + */ + if (in_dev->dead) + goto no_promotions; + /* 1. Deleting primary ifaddr forces deletion all secondaries * unless alias promotion is set **/ @@ -380,6 +386,7 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, fib_del_ifaddr(ifa, ifa1); } +no_promotions: /* 2. Unlink it */ *ifap = ifa1->ifa_next;