diff options
author | rwatson <rwatson@FreeBSD.org> | 2008-07-07 10:56:55 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2008-07-07 10:56:55 +0000 |
commit | c32969ee867233aa0ad96b8ac428c34aa76ca7cf (patch) | |
tree | 0dad0efec6b9c17db37dd57b9da932da8f3a62fa /sys/netinet | |
parent | 00f0ab40d48c3094bbaaa6328309780f40481686 (diff) | |
download | FreeBSD-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')
-rw-r--r-- | sys/netinet/udp_usrreq.c | 17 |
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); } |