Resolve deadlock between epoch(9) and various network interface

SX-locks, during if_purgeaddrs(), by not allowing to hold the epoch
read lock over typical network IOCTL code paths. This is a regression
issue after r334305.

Reviewed by:		ae (network)
Differential revision:	https://reviews.freebsd.org/D17647
MFC after:		1 week
Sponsored by:		Mellanox Technologies
This commit is contained in:
Hans Petter Selasky 2018-10-22 13:25:26 +00:00
parent 27e4bd81f7
commit 88d57e9eac

View File

@ -964,12 +964,18 @@ if_attachdomain1(struct ifnet *ifp)
void
if_purgeaddrs(struct ifnet *ifp)
{
struct ifaddr *ifa, *next;
struct ifaddr *ifa;
NET_EPOCH_ENTER();
CK_STAILQ_FOREACH_SAFE(ifa, &ifp->if_addrhead, ifa_link, next) {
if (ifa->ifa_addr->sa_family == AF_LINK)
continue;
while (1) {
NET_EPOCH_ENTER();
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_LINK)
break;
}
NET_EPOCH_EXIT();
if (ifa == NULL)
break;
#ifdef INET
/* XXX: Ugly!! ad hoc just for INET */
if (ifa->ifa_addr->sa_family == AF_INET) {
@ -996,7 +1002,6 @@ if_purgeaddrs(struct ifnet *ifp)
IF_ADDR_WUNLOCK(ifp);
ifa_free(ifa);
}
NET_EPOCH_EXIT();
}
/*