summaryrefslogtreecommitdiffstats
path: root/sys/netinet/udp_usrreq.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2008-07-07 10:56:55 +0000
committerrwatson <rwatson@FreeBSD.org>2008-07-07 10:56:55 +0000
commitc32969ee867233aa0ad96b8ac428c34aa76ca7cf (patch)
tree0dad0efec6b9c17db37dd57b9da932da8f3a62fa /sys/netinet/udp_usrreq.c
parent00f0ab40d48c3094bbaaa6328309780f40481686 (diff)
downloadFreeBSD-src-c32969ee867233aa0ad96b8ac428c34aa76ca7cf.zip
FreeBSD-src-c32969ee867233aa0ad96b8ac428c34aa76ca7cf.tar.gz
First step towards parallel transmit in UDP: if neither a specific
source or a specific destination address is requested as part of a send on a UDP socket, read lock the inpcb rather than write lock it. This will allow fully parallel transmit down to the IP layer when sending simultaneously from multiple threads on a connected UDP socket. Parallel transmit for more complex cases, such as when sendto(2) is invoked with an address and there's already a local binding, will follow. MFC after: 1 month
Diffstat (limited to 'sys/netinet/udp_usrreq.c')
-rw-r--r--sys/netinet/udp_usrreq.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index f63fd0b..9422e7e 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -841,10 +841,12 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr,
if (src.sin_family == AF_INET || addr != NULL) {
INP_INFO_WLOCK(&udbinfo);
+ INP_WLOCK(inp);
unlock_udbinfo = 1;
- } else
+ } else {
unlock_udbinfo = 0;
- INP_WLOCK(inp);
+ INP_RLOCK(inp);
+ }
#ifdef MAC
mac_inpcb_create_mbuf(inp, m);
@@ -975,13 +977,18 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr,
INP_INFO_WUNLOCK(&udbinfo);
error = ip_output(m, inp->inp_options, NULL, ipflags,
inp->inp_moptions, inp);
- INP_WUNLOCK(inp);
+ if (unlock_udbinfo)
+ INP_WUNLOCK(inp);
+ else
+ INP_RUNLOCK(inp);
return (error);
release:
- INP_WUNLOCK(inp);
- if (unlock_udbinfo)
+ if (unlock_udbinfo) {
INP_INFO_WUNLOCK(&udbinfo);
+ INP_WUNLOCK(inp);
+ } else
+ INP_RUNLOCK(inp);
m_freem(m);
return (error);
}
OpenPOWER on IntegriCloud