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:
parent
27e4bd81f7
commit
88d57e9eac
17
sys/net/if.c
17
sys/net/if.c
@ -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();
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user