From owner-svn-src-projects@FreeBSD.ORG Fri Nov 14 15:55:58 2014 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 395B482F; Fri, 14 Nov 2014 15:55:58 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 0CB7299B; Fri, 14 Nov 2014 15:55:58 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id sAEFtvlH007243; Fri, 14 Nov 2014 15:55:57 GMT (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id sAEFtvur007240; Fri, 14 Nov 2014 15:55:57 GMT (envelope-from glebius@FreeBSD.org) Message-Id: <201411141555.sAEFtvur007240@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: glebius set sender to glebius@FreeBSD.org using -f From: Gleb Smirnoff Date: Fri, 14 Nov 2014 15:55:57 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r274513 - in projects/sendfile/sys: kern sys X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Nov 2014 15:55:58 -0000 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);