mirror of
https://github.com/opnsense/src.git
synced 2026-06-05 14:54:21 -04:00
socket: Split up sosend_generic()
Factor out the bits that run with the sock I/O lock held into a separate function. In this implementation, we are doing a bit more work under the I/O lock than before. However, lock contention is only a problem when multiple threads are transmitting on the same socket, which is an unusual case that is not expected to perform well in any case. No functional change intended. Reviewed by: gallatin, glebius MFC after: 2 weeks Sponsored by: Klara, Inc. Sponsored by: Stormshield Differential Revision: https://reviews.freebsd.org/D46305
This commit is contained in:
parent
0a68f644dc
commit
fb901935f2
1 changed files with 29 additions and 18 deletions
|
|
@ -1656,8 +1656,8 @@ out:
|
|||
* counts if EINTR/ERESTART are returned. Data and control buffers are freed
|
||||
* on return.
|
||||
*/
|
||||
int
|
||||
sosend_generic(struct socket *so, struct sockaddr *addr, struct uio *uio,
|
||||
static int
|
||||
sosend_generic_locked(struct socket *so, struct sockaddr *addr, struct uio *uio,
|
||||
struct mbuf *top, struct mbuf *control, int flags, struct thread *td)
|
||||
{
|
||||
long space;
|
||||
|
|
@ -1673,6 +1673,9 @@ sosend_generic(struct socket *so, struct sockaddr *addr, struct uio *uio,
|
|||
tls = NULL;
|
||||
tls_rtype = TLS_RLTYPE_APP;
|
||||
#endif
|
||||
|
||||
SOCK_IO_SEND_ASSERT_LOCKED(so);
|
||||
|
||||
if (uio != NULL)
|
||||
resid = uio->uio_resid;
|
||||
else if ((top->m_flags & M_PKTHDR) != 0)
|
||||
|
|
@ -1702,10 +1705,6 @@ sosend_generic(struct socket *so, struct sockaddr *addr, struct uio *uio,
|
|||
if (control != NULL)
|
||||
clen = control->m_len;
|
||||
|
||||
error = SOCK_IO_SEND_LOCK(so, SBLOCKWAIT(flags));
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
#ifdef KERN_TLS
|
||||
tls_send_flag = 0;
|
||||
tls = ktls_hold(so->so_snd.sb_tls_info);
|
||||
|
|
@ -1728,7 +1727,7 @@ sosend_generic(struct socket *so, struct sockaddr *addr, struct uio *uio,
|
|||
|
||||
if (resid == 0 && !ktls_permit_empty_frames(tls)) {
|
||||
error = EINVAL;
|
||||
goto release;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1739,13 +1738,13 @@ restart:
|
|||
if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
|
||||
SOCKBUF_UNLOCK(&so->so_snd);
|
||||
error = EPIPE;
|
||||
goto release;
|
||||
goto out;
|
||||
}
|
||||
if (so->so_error) {
|
||||
error = so->so_error;
|
||||
so->so_error = 0;
|
||||
SOCKBUF_UNLOCK(&so->so_snd);
|
||||
goto release;
|
||||
goto out;
|
||||
}
|
||||
if ((so->so_state & SS_ISCONNECTED) == 0) {
|
||||
/*
|
||||
|
|
@ -1759,7 +1758,7 @@ restart:
|
|||
if (!(resid == 0 && clen != 0)) {
|
||||
SOCKBUF_UNLOCK(&so->so_snd);
|
||||
error = ENOTCONN;
|
||||
goto release;
|
||||
goto out;
|
||||
}
|
||||
} else if (addr == NULL) {
|
||||
SOCKBUF_UNLOCK(&so->so_snd);
|
||||
|
|
@ -1767,7 +1766,7 @@ restart:
|
|||
error = ENOTCONN;
|
||||
else
|
||||
error = EDESTADDRREQ;
|
||||
goto release;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
space = sbspace(&so->so_snd);
|
||||
|
|
@ -1777,7 +1776,7 @@ restart:
|
|||
clen > so->so_snd.sb_hiwat) {
|
||||
SOCKBUF_UNLOCK(&so->so_snd);
|
||||
error = EMSGSIZE;
|
||||
goto release;
|
||||
goto out;
|
||||
}
|
||||
if (space < resid + clen &&
|
||||
(atomic || space < so->so_snd.sb_lowat || space < clen)) {
|
||||
|
|
@ -1785,12 +1784,12 @@ restart:
|
|||
(flags & (MSG_NBIO | MSG_DONTWAIT)) != 0) {
|
||||
SOCKBUF_UNLOCK(&so->so_snd);
|
||||
error = EWOULDBLOCK;
|
||||
goto release;
|
||||
goto out;
|
||||
}
|
||||
error = sbwait(so, SO_SND);
|
||||
SOCKBUF_UNLOCK(&so->so_snd);
|
||||
if (error)
|
||||
goto release;
|
||||
goto out;
|
||||
goto restart;
|
||||
}
|
||||
SOCKBUF_UNLOCK(&so->so_snd);
|
||||
|
|
@ -1835,7 +1834,7 @@ restart:
|
|||
((flags & MSG_EOR) ? M_EOR : 0));
|
||||
if (top == NULL) {
|
||||
error = EFAULT; /* only possible error */
|
||||
goto release;
|
||||
goto out;
|
||||
}
|
||||
space -= resid - uio->uio_resid;
|
||||
resid = uio->uio_resid;
|
||||
|
|
@ -1899,12 +1898,10 @@ restart:
|
|||
control = NULL;
|
||||
top = NULL;
|
||||
if (error)
|
||||
goto release;
|
||||
goto out;
|
||||
} while (resid && space > 0);
|
||||
} while (resid);
|
||||
|
||||
release:
|
||||
SOCK_IO_SEND_UNLOCK(so);
|
||||
out:
|
||||
#ifdef KERN_TLS
|
||||
if (tls != NULL)
|
||||
|
|
@ -1917,6 +1914,20 @@ out:
|
|||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
sosend_generic(struct socket *so, struct sockaddr *addr, struct uio *uio,
|
||||
struct mbuf *top, struct mbuf *control, int flags, struct thread *td)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = SOCK_IO_SEND_LOCK(so, 0);
|
||||
if (error)
|
||||
return (error);
|
||||
error = sosend_generic_locked(so, addr, uio, top, control, flags, td);
|
||||
SOCK_IO_SEND_UNLOCK(so);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send to a socket from a kernel thread.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in a new issue