svn commit: r275333 - head/sys/netinet
Gleb Smirnoff
glebius at FreeBSD.org
Sun Nov 30 13:43:53 UTC 2014
Author: glebius
Date: Sun Nov 30 13:43:52 2014
New Revision: 275333
URL: https://svnweb.freebsd.org/changeset/base/275333
Log:
Merge from projects/sendfile:
- Provide pru_ready function for TCP.
- Don't call tcp_output() from tcp_usr_send() if no ready data was put
into the socket buffer.
- In case of dropped connection don't try to m_freem() not ready data.
Sponsored by: Nginx, Inc.
Sponsored by: Netflix
Modified:
head/sys/netinet/tcp_usrreq.c
Modified: head/sys/netinet/tcp_usrreq.c
==============================================================================
--- head/sys/netinet/tcp_usrreq.c Sun Nov 30 13:40:58 2014 (r275332)
+++ head/sys/netinet/tcp_usrreq.c Sun Nov 30 13:43:52 2014 (r275333)
@@ -821,7 +821,11 @@ tcp_usr_send(struct socket *so, int flag
if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
if (control)
m_freem(control);
- if (m)
+ /*
+ * In case of PRUS_NOTREADY, tcp_usr_ready() is responsible
+ * for freeing memory.
+ */
+ if (m && (flags & PRUS_NOTREADY) == 0)
m_freem(m);
error = ECONNRESET;
goto out;
@@ -875,7 +879,8 @@ tcp_usr_send(struct socket *so, int flag
socantsendmore(so);
tcp_usrclosed(tp);
}
- if (!(inp->inp_flags & INP_DROPPED)) {
+ if (!(inp->inp_flags & INP_DROPPED) &&
+ !(flags & PRUS_NOTREADY)) {
if (flags & PRUS_MORETOCOME)
tp->t_flags |= TF_MORETOCOME;
error = tcp_output(tp);
@@ -926,9 +931,11 @@ tcp_usr_send(struct socket *so, int flag
tcp_mss(tp, -1);
}
tp->snd_up = tp->snd_una + sbavail(&so->so_snd);
- tp->t_flags |= TF_FORCEDATA;
- error = tcp_output(tp);
- tp->t_flags &= ~TF_FORCEDATA;
+ if (!(flags & PRUS_NOTREADY)) {
+ tp->t_flags |= TF_FORCEDATA;
+ error = tcp_output(tp);
+ tp->t_flags &= ~TF_FORCEDATA;
+ }
}
out:
TCPDEBUG2((flags & PRUS_OOB) ? PRU_SENDOOB :
@@ -939,6 +946,33 @@ out:
return (error);
}
+static int
+tcp_usr_ready(struct socket *so, struct mbuf *m, int count)
+{
+ struct inpcb *inp;
+ struct tcpcb *tp;
+ int error;
+
+ inp = sotoinpcb(so);
+ INP_WLOCK(inp);
+ if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
+ INP_WUNLOCK(inp);
+ for (int i = 0; i < count; i++)
+ m = m_free(m);
+ return (ECONNRESET);
+ }
+ tp = intotcpcb(inp);
+
+ SOCKBUF_LOCK(&so->so_snd);
+ error = sbready(&so->so_snd, m, count);
+ SOCKBUF_UNLOCK(&so->so_snd);
+ if (error == 0)
+ error = tcp_output(tp);
+ INP_WUNLOCK(inp);
+
+ return (error);
+}
+
/*
* Abort the TCP. Drop the connection abruptly.
*/
@@ -1073,6 +1107,7 @@ struct pr_usrreqs tcp_usrreqs = {
.pru_rcvd = tcp_usr_rcvd,
.pru_rcvoob = tcp_usr_rcvoob,
.pru_send = tcp_usr_send,
+ .pru_ready = tcp_usr_ready,
.pru_shutdown = tcp_usr_shutdown,
.pru_sockaddr = in_getsockaddr,
.pru_sosetlabel = in_pcbsosetlabel,
@@ -1095,6 +1130,7 @@ struct pr_usrreqs tcp6_usrreqs = {
.pru_rcvd = tcp_usr_rcvd,
.pru_rcvoob = tcp_usr_rcvoob,
.pru_send = tcp_usr_send,
+ .pru_ready = tcp_usr_ready,
.pru_shutdown = tcp_usr_shutdown,
.pru_sockaddr = in6_mapped_sockaddr,
.pru_sosetlabel = in_pcbsosetlabel,
More information about the svn-src-all
mailing list