path: root/sys/sys
diff options
authorGleb Smirnoff <glebius@FreeBSD.org>2014-11-30 12:52:33 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2014-11-30 12:52:33 +0000
commit0f9d0a73a495b204ea02cf1da28db1bdd0c7e40b (patch)
tree6aca46c356e9150741198b08512009a1b5138ca0 /sys/sys
parentabcd4129406a0a80e0c53cfba05d9c5b6ff4c576 (diff)
Merge from projects/sendfile:
o Introduce a notion of "not ready" mbufs in socket buffers. These mbufs are now being populated by some I/O in background and are referenced outside. This forces following implications: - An mbuf which is "not ready" can't be taken out of the buffer. - An mbuf that is behind a "not ready" in the queue neither. - If sockbet buffer is flushed, then "not ready" mbufs shouln't be freed. o In struct sockbuf the sb_cc field is split into sb_ccc and sb_acc. The sb_ccc stands for ""claimed character count", or "committed character count". And the sb_acc is "available character count". Consumers of socket buffer API shouldn't already access them directly, but use sbused() and sbavail() respectively. o Not ready mbufs are marked with M_NOTREADY, and ready but blocked ones with M_BLOCKED. o New field sb_fnrdy points to the first not ready mbuf, to avoid linear search. o New function sbready() is provided to activate certain amount of mbufs in a socket buffer. A special note on SCTP: SCTP has its own sockbufs. Unfortunately, FreeBSD stack doesn't yet allow protocol specific sockbufs. Thus, SCTP does some hacks to make itself compatible with FreeBSD: it manages sockbufs on its own, but keeps sb_cc updated to inform the stack of amount of data in them. The new notion of "not ready" data isn't supported by SCTP. Instead, only a mechanical substitute is done: s/sb_cc/sb_ccc/. A proper solution would be to take away struct sockbuf from struct socket and allow protocols to implement their own socket buffers, like SCTP already does. This was discussed with rrs@. Sponsored by: Netflix Sponsored by: Nginx, Inc.
Notes: svn path=/head/; revision=275326
Diffstat (limited to 'sys/sys')
1 files changed, 25 insertions, 12 deletions
diff --git a/sys/sys/sockbuf.h b/sys/sys/sockbuf.h
index 1cd419f3283a..ec16b2593dd2 100644
--- a/sys/sys/sockbuf.h
+++ b/sys/sys/sockbuf.h
@@ -89,8 +89,10 @@ struct sockbuf {
struct mbuf *sb_lastrecord; /* (c/d) first mbuf of last
* record in socket buffer */
struct mbuf *sb_sndptr; /* (c/d) pointer into mbuf chain */
+ struct mbuf *sb_fnrdy; /* (c/d) pointer to first not ready buffer */
u_int sb_sndptroff; /* (c/d) byte offset of ptr into chain */
- u_int sb_cc; /* (c/d) actual chars in buffer */
+ u_int sb_acc; /* (c/d) available chars in buffer */
+ u_int sb_ccc; /* (c/d) claimed chars in buffer */
u_int sb_hiwat; /* (c/d) max actual char count */
u_int sb_mbcnt; /* (c/d) chars of mbufs used */
u_int sb_mcnt; /* (c/d) number of mbufs in buffer */
@@ -120,6 +122,13 @@ struct sockbuf {
#define SOCKBUF_LOCK_ASSERT(_sb) mtx_assert(SOCKBUF_MTX(_sb), MA_OWNED)
+ * Socket buffer private mbuf(9) flags.
+ */
+#define M_NOTREADY M_PROTO1 /* m_data not populated yet */
+#define M_BLOCKED M_PROTO2 /* M_NOTREADY in front of m */
void sbappend(struct sockbuf *sb, struct mbuf *m);
void sbappend_locked(struct sockbuf *sb, struct mbuf *m);
void sbappendstream(struct sockbuf *sb, struct mbuf *m);
@@ -165,10 +174,11 @@ int sblock(struct sockbuf *sb, int flags);
void sbunlock(struct sockbuf *sb);
void sballoc(struct sockbuf *, struct mbuf *);
void sbfree(struct sockbuf *, struct mbuf *);
+int sbready(struct sockbuf *, struct mbuf *, int);
* Return how much data is available to be taken out of socket
- * bufffer right now.
+ * buffer right now.
static inline u_int
sbavail(struct sockbuf *sb)
@@ -177,7 +187,7 @@ sbavail(struct sockbuf *sb)
#if 0
- return (sb->sb_cc);
+ return (sb->sb_acc);
@@ -191,27 +201,30 @@ sbused(struct sockbuf *sb)
#if 0
- return (sb->sb_cc);
+ return (sb->sb_ccc);
* How much space is there in a socket buffer (so->so_snd or so->so_rcv)?
* This is problematical if the fields are unsigned, as the space might
- * still be negative (cc > hiwat or mbcnt > mbmax). Should detect
- * overflow and return 0. Should use "lmin" but it doesn't exist now.
+ * still be negative (ccc > hiwat or mbcnt > mbmax).
-static __inline
+static inline long
sbspace(struct sockbuf *sb)
- long bleft;
- long mleft;
+ long bleft, mleft;
+#if 0
if (sb->sb_flags & SB_STOP)
- bleft = sb->sb_hiwat - sb->sb_cc;
+ bleft = sb->sb_hiwat - sb->sb_ccc;
mleft = sb->sb_mbmax - sb->sb_mbcnt;
- return((bleft < mleft) ? bleft : mleft);
+ return ((bleft < mleft) ? bleft : mleft);
#define SB_EMPTY_FIXUP(sb) do { \