Date: Fri, 14 Nov 2014 15:55:57 +0000 (UTC) From: Gleb Smirnoff <glebius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r274513 - in projects/sendfile/sys: kern sys Message-ID: <201411141555.sAEFtvur007240@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: glebius Date: Fri Nov 14 15:55:56 2014 New Revision: 274513 URL: https://svnweb.freebsd.org/changeset/base/274513 Log: When sbcut() works on M_NOTREADY mbufs, it shouldn't free them, since they a referenced by some outside entity. Instead, sbcut() would mark them with a new flag and forget them. Later, if sbready() encounters such mbufs, it frees them. Sponsored by: Nginx, Inc. Modified: projects/sendfile/sys/kern/uipc_sockbuf.c projects/sendfile/sys/sys/sockbuf.h Modified: projects/sendfile/sys/kern/uipc_sockbuf.c ============================================================================== --- projects/sendfile/sys/kern/uipc_sockbuf.c Fri Nov 14 15:50:16 2014 (r274512) +++ projects/sendfile/sys/kern/uipc_sockbuf.c Fri Nov 14 15:55:56 2014 (r274513) @@ -78,6 +78,20 @@ sbready(struct sockbuf *sb, struct mbuf SOCKBUF_LOCK_ASSERT(sb); + if (m->m_flags & M_SBCUTTED) { + /* + * Oops, something bad happened to the socket buffer while + * we were working on the data. Our mbufs are detached from + * the sockbuf, and all what we can do is free them. + */ + for (int i = 0; i < count; i++) { + KASSERT(m->m_flags & M_SBCUTTED, + ("%s: m %p !M_SBCUTTED", __func__, m)); + m = m_free(m); + } + return (EPIPE); + } + KASSERT(sb->sb_fnrdy != NULL, ("%s: sb %p NULL fnrdy", __func__, sb)); blocker = (sb->sb_fnrdy == m) ? M_BLOCKED : 0; @@ -1045,8 +1059,12 @@ sbcut_internal(struct sockbuf *sb, int l len -= m->m_len; sbfree(sb, m); n = m->m_next; - m->m_next = mfree; - mfree = m; + if (m->m_flags & M_NOTREADY) + m->m_flags |= M_SBCUTTED; + else { + m->m_next = mfree; + mfree = m; + } m = n; } if (m) { Modified: projects/sendfile/sys/sys/sockbuf.h ============================================================================== --- projects/sendfile/sys/sys/sockbuf.h Fri Nov 14 15:50:16 2014 (r274512) +++ projects/sendfile/sys/sys/sockbuf.h Fri Nov 14 15:55:56 2014 (r274513) @@ -128,6 +128,7 @@ struct sockbuf { #define M_NOTREADY M_PROTO1 /* m_data not populated yet */ #define M_BLOCKED M_PROTO2 /* M_NOTREADY in front of m */ #define M_NOTAVAIL (M_NOTREADY | M_BLOCKED) +#define M_SBCUTTED M_PROTO3 /* mbuf was sbcutted out */ void sbappend(struct sockbuf *sb, struct mbuf *m); void sbappend_locked(struct sockbuf *sb, struct mbuf *m);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201411141555.sAEFtvur007240>