Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netinet/udp_usrreq.c
Show First 20 Lines • Show All 1,252 Lines • ▼ Show 20 Lines | if (unlock_inp == UH_WLOCKED) | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
else | else | ||||
INP_RUNLOCK(inp); | INP_RUNLOCK(inp); | ||||
m_freem(m); | m_freem(m); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Depending on whether or not the application has bound or connected | * In the old days, depending on whether or not the application had | ||||
* the socket, we may have to do varying levels of work. The optimal | * bound or connected the socket, we had to do varying levels of work. | ||||
* case is for a connected UDP socket, as a global lock isn't | * The optimal case was for a connected UDP socket, as a global lock | ||||
* required at all. | * wasn't required at all. | ||||
* | * In order to decide which we need, we required stability of the | ||||
* In order to decide which we need, we require stability of the | * inpcb binding, which we ensured by acquiring a read lock on the | ||||
* inpcb binding, which we ensure by acquiring a read lock on the | * inpcb. This didn't strictly follow the lock order, so we played | ||||
* inpcb. This doesn't strictly follow the lock order, so we play | * the trylock and retry game. | ||||
* the trylock and retry game; note that we may end up with more | * With the re-introduction of the route-cache in some cases, we started | ||||
* conservative locks than required the second time around, so later | * to acquire an early inp wlock and a possible race during re-lock | ||||
* assertions have to accept that. Further analysis of the number of | * went away. With the introduction of epoch(9) some read locking | ||||
* misses under contention is required. | * became epoch(9) and the lock-order issues also went away. | ||||
* | * Due to route-cache we may now hold more conservative locks than | ||||
* XXXRW: Check that hash locking update here is correct. | * otherwise required and have split up the 2nd case in case 2 and 3 | ||||
* in order to keep the udpinfo lock level in sync with the inp one | |||||
* for the IP_SENDSRCADDR case below. | |||||
*/ | */ | ||||
pr = inp->inp_socket->so_proto->pr_protocol; | pr = inp->inp_socket->so_proto->pr_protocol; | ||||
pcbinfo = udp_get_inpcbinfo(pr); | pcbinfo = udp_get_inpcbinfo(pr); | ||||
if (sin != NULL && | if (sin != NULL && | ||||
(inp->inp_laddr.s_addr == INADDR_ANY && inp->inp_lport == 0)) { | (inp->inp_laddr.s_addr == INADDR_ANY && inp->inp_lport == 0)) { | ||||
INP_HASH_WLOCK(pcbinfo); | INP_HASH_WLOCK(pcbinfo); | ||||
unlock_udbinfo = UH_WLOCKED; | unlock_udbinfo = UH_WLOCKED; | ||||
} else if ((sin != NULL && | } else if (sin != NULL && | ||||
(sin->sin_addr.s_addr == INADDR_ANY || | (sin->sin_addr.s_addr == INADDR_ANY || | ||||
sin->sin_addr.s_addr == INADDR_BROADCAST || | sin->sin_addr.s_addr == INADDR_BROADCAST || | ||||
inp->inp_laddr.s_addr == INADDR_ANY || | inp->inp_laddr.s_addr == INADDR_ANY || | ||||
inp->inp_lport == 0)) || | inp->inp_lport == 0)) { | ||||
src.sin_family == AF_INET) { | |||||
INP_HASH_RLOCK_ET(pcbinfo, et); | INP_HASH_RLOCK_ET(pcbinfo, et); | ||||
unlock_udbinfo = UH_RLOCKED; | unlock_udbinfo = UH_RLOCKED; | ||||
} else if (src.sin_family == AF_INET) { | |||||
if (unlock_inp == UH_WLOCKED) { | |||||
INP_HASH_WLOCK(pcbinfo); | |||||
unlock_udbinfo = UH_WLOCKED; | |||||
} else { | |||||
INP_HASH_RLOCK_ET(pcbinfo, et); | |||||
unlock_udbinfo = UH_RLOCKED; | |||||
} | |||||
} else | } else | ||||
unlock_udbinfo = UH_UNLOCKED; | unlock_udbinfo = UH_UNLOCKED; | ||||
/* | /* | ||||
* If the IP_SENDSRCADDR control message was specified, override the | * If the IP_SENDSRCADDR control message was specified, override the | ||||
* source address for this datagram. Its use is invalidated if the | * source address for this datagram. Its use is invalidated if the | ||||
* address thus specified is incomplete or clobbers other inpcbs. | * address thus specified is incomplete or clobbers other inpcbs. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 526 Lines • Show Last 20 Lines |