From owner-svn-src-all@FreeBSD.ORG Mon Jun 22 23:56:47 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 22D32106566C; Mon, 22 Jun 2009 23:56:47 +0000 (UTC) (envelope-from mat.macy@gmail.com) Received: from an-out-0708.google.com (an-out-0708.google.com [209.85.132.246]) by mx1.freebsd.org (Postfix) with ESMTP id 810FF8FC13; Mon, 22 Jun 2009 23:56:46 +0000 (UTC) (envelope-from mat.macy@gmail.com) Received: by an-out-0708.google.com with SMTP id c3so1571565ana.13 for ; Mon, 22 Jun 2009 16:56:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:sender:received:in-reply-to :references:date:x-google-sender-auth:message-id:subject:from:to:cc :content-type:content-transfer-encoding; bh=nZYie0iytPG/iC6KYhZPnY3RxG60IGvhYUPd+IyQWKE=; b=QE1XJUCtZBhIsSSiTT01IbGgo/9zkqa1/gQE1/q2a6+Ns3FCdGS0SKVMjuu47r10bc rv1FQeP+h0WXR/Qth/67OZtIyBXmbk0yyGS16nfre/8gjzUKjxs6VYZYtlVFPhnM0PHc 6FDYLH1c/hKPlAYccXnavVhL3PGRYaP2RMjjw= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type :content-transfer-encoding; b=Ia8UJgwdkH57VACYijYPL7A+PQ0JjPxKXiQfgQvSsq2EHXcnNv850wXskqTc65y3xG g9JWy2WQ0NMEeKVkpRUjkC7zM/CM6MCOyixwzIt7GJy6nWBqyyy6nbiccx5Gz7osbWfF qI+F/jIxcLH119xQV/mXmWGkMMhc0w24+8k7k= MIME-Version: 1.0 Sender: mat.macy@gmail.com Received: by 10.100.195.15 with SMTP id s15mr8873296anf.18.1245715005102; Mon, 22 Jun 2009 16:56:45 -0700 (PDT) In-Reply-To: <200906222308.n5MN856I055711@svn.freebsd.org> References: <200906222308.n5MN856I055711@svn.freebsd.org> Date: Mon, 22 Jun 2009 16:56:45 -0700 X-Google-Sender-Auth: c389e4944f9ca1f6 Message-ID: <3c1674c90906221656n63aff4ddo2080bfac55496ca9@mail.gmail.com> From: Kip Macy To: Andre Oppermann Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r194672 - in head/sys: kern netinet sys X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 Jun 2009 23:56:47 -0000 Who is reviewing and testing these changes? -Kip On Mon, Jun 22, 2009 at 4:08 PM, Andre Oppermann wrote: > Author: andre > Date: Mon Jun 22 23:08:05 2009 > New Revision: 194672 > URL: http://svn.freebsd.org/changeset/base/194672 > > Log: > =A0Add soreceive_stream(), an optimized version of soreceive() for > =A0stream (TCP) sockets. > > =A0It is functionally identical to generic soreceive() but has a > =A0number stream specific optimizations: > =A0o does only one sockbuf unlock/lock per receive independent of > =A0 =A0the length of data to be moved into the uio compared to > =A0 =A0soreceive() which unlocks/locks per *mbuf*. > =A0o uses m_mbuftouio() instead of its own copy(out) variant. > =A0o much more compact code flow as a large number of special > =A0 =A0cases is removed. > =A0o much improved reability. > > =A0It offers significantly reduced CPU usage and lock contention > =A0when receiving fast TCP streams. =A0Additional gains are obtained > =A0when the receiving application is using SO_RCVLOWAT to batch up > =A0some data before a read (and wakeup) is done. > > =A0This function was written by "reverse engineering" and is not > =A0just a stripped down variant of soreceive(). > > =A0It is not yet enabled by default on TCP sockets. =A0Instead it is > =A0commented out in the protocol initialization in tcp_usrreq.c > =A0until more widespread testing has been done. > > =A0Testers, especially with 10GigE gear, are welcome. > > =A0MFP4: r164817 //depot/user/andre/soreceive_stream/ > > Modified: > =A0head/sys/kern/uipc_socket.c > =A0head/sys/netinet/tcp_usrreq.c > =A0head/sys/sys/socketvar.h > > Modified: head/sys/kern/uipc_socket.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > --- head/sys/kern/uipc_socket.c Mon Jun 22 22:54:44 2009 =A0 =A0 =A0 =A0(= r194671) > +++ head/sys/kern/uipc_socket.c Mon Jun 22 23:08:05 2009 =A0 =A0 =A0 =A0(= r194672) > @@ -1857,6 +1857,202 @@ release: > =A0} > > =A0/* > + * Optimized version of soreceive() for stream (TCP) sockets. > + */ > +int > +soreceive_stream(struct socket *so, struct sockaddr **psa, struct uio *u= io, > + =A0 =A0struct mbuf **mp0, struct mbuf **controlp, int *flagsp) > +{ > + =A0 =A0 =A0 int len =3D 0, error =3D 0, flags, oresid; > + =A0 =A0 =A0 struct sockbuf *sb; > + =A0 =A0 =A0 struct mbuf *m, *n =3D NULL; > + > + =A0 =A0 =A0 /* We only do stream sockets. */ > + =A0 =A0 =A0 if (so->so_type !=3D SOCK_STREAM) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (EINVAL); > + =A0 =A0 =A0 if (psa !=3D NULL) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 *psa =3D NULL; > + =A0 =A0 =A0 if (controlp !=3D NULL) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (EINVAL); > + =A0 =A0 =A0 if (flagsp !=3D NULL) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 flags =3D *flagsp &~ MSG_EOR; > + =A0 =A0 =A0 else > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 flags =3D 0; > + =A0 =A0 =A0 if (flags & MSG_OOB) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (soreceive_rcvoob(so, uio, flags)); > + =A0 =A0 =A0 if (mp0 !=3D NULL) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 *mp0 =3D NULL; > + > + =A0 =A0 =A0 sb =3D &so->so_rcv; > + > + =A0 =A0 =A0 /* Prevent other readers from entering the socket. */ > + =A0 =A0 =A0 error =3D sblock(sb, SBLOCKWAIT(flags)); > + =A0 =A0 =A0 if (error) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto out; > + =A0 =A0 =A0 SOCKBUF_LOCK(sb); > + > + =A0 =A0 =A0 /* Easy one, no space to copyout anything. */ > + =A0 =A0 =A0 if (uio->uio_resid =3D=3D 0) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 error =3D EINVAL; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto out; > + =A0 =A0 =A0 } > + =A0 =A0 =A0 oresid =3D uio->uio_resid; > + > + =A0 =A0 =A0 /* We will never ever get anything unless we are connected.= */ > + =A0 =A0 =A0 if (!(so->so_state & (SS_ISCONNECTED|SS_ISDISCONNECTED))) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* When disconnecting there may be still so= me data left. */ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (sb->sb_cc > 0) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto deliver; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!(so->so_state & SS_ISDISCONNECTED)) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 error =3D ENOTCONN; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto out; > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 /* Socket buffer is empty and we shall not block. */ > + =A0 =A0 =A0 if (sb->sb_cc =3D=3D 0 && > + =A0 =A0 =A0 =A0 =A0 ((sb->sb_flags & SS_NBIO) || (flags & (MSG_DONTWAIT= |MSG_NBIO)))) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 error =3D EAGAIN; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto out; > + =A0 =A0 =A0 } > + > +restart: > + =A0 =A0 =A0 SOCKBUF_LOCK_ASSERT(&so->so_rcv); > + > + =A0 =A0 =A0 /* Abort if socket has reported problems. */ > + =A0 =A0 =A0 if (so->so_error) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (sb->sb_cc > 0) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto deliver; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (oresid > uio->uio_resid) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto out; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 error =3D so->so_error; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!(flags & MSG_PEEK)) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 so->so_error =3D 0; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto out; > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 /* Door is closed. =A0Deliver what is left, if any. */ > + =A0 =A0 =A0 if (sb->sb_state & SBS_CANTRCVMORE) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (sb->sb_cc > 0) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto deliver; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 else > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto out; > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 /* Socket buffer got some data that we shall deliver now. *= / > + =A0 =A0 =A0 if (sb->sb_cc > 0 && !(flags & MSG_WAITALL) && > + =A0 =A0 =A0 =A0 =A0 ((sb->sb_flags & SS_NBIO) || > + =A0 =A0 =A0 =A0 =A0 =A0(flags & (MSG_DONTWAIT|MSG_NBIO)) || > + =A0 =A0 =A0 =A0 =A0 =A0sb->sb_cc >=3D sb->sb_lowat || > + =A0 =A0 =A0 =A0 =A0 =A0sb->sb_cc >=3D uio->uio_resid || > + =A0 =A0 =A0 =A0 =A0 =A0sb->sb_cc >=3D sb->sb_hiwat) ) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto deliver; > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 /* On MSG_WAITALL we must wait until all data or error arri= ves. */ > + =A0 =A0 =A0 if ((flags & MSG_WAITALL) && > + =A0 =A0 =A0 =A0 =A0 (sb->sb_cc >=3D uio->uio_resid || sb->sb_cc >=3D sb= ->sb_lowat)) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto deliver; > + > + =A0 =A0 =A0 /* > + =A0 =A0 =A0 =A0* Wait and block until (more) data comes in. > + =A0 =A0 =A0 =A0* NB: Drops the sockbuf lock during wait. > + =A0 =A0 =A0 =A0*/ > + =A0 =A0 =A0 error =3D sbwait(sb); > + =A0 =A0 =A0 if (error) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto out; > + =A0 =A0 =A0 goto restart; > + > +deliver: > + =A0 =A0 =A0 SOCKBUF_LOCK_ASSERT(&so->so_rcv); > + =A0 =A0 =A0 KASSERT(sb->sb_cc > 0, ("%s: sockbuf empty", __func__)); > + =A0 =A0 =A0 KASSERT(sb->sb_mb !=3D NULL, ("%s: sb_mb =3D=3D NULL", __fu= nc__)); > + > + =A0 =A0 =A0 /* Statistics. */ > + =A0 =A0 =A0 if (uio->uio_td) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 uio->uio_td->td_ru.ru_msgrcv++; > + > + =A0 =A0 =A0 /* Fill uio until full or current end of socket buffer is r= eached. */ > + =A0 =A0 =A0 len =3D min(uio->uio_resid, sb->sb_cc); > + =A0 =A0 =A0 if (mp0 !=3D NULL) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Dequeue as many mbufs as possible. */ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!(flags & MSG_PEEK) && len >=3D sb->sb_= mb->m_len) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 for (*mp0 =3D m =3D sb->sb_= mb; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0m !=3D NULL && m= ->m_len <=3D len; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0m =3D m->m_next)= { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 len -=3D m-= >m_len; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 uio->uio_re= sid -=3D m->m_len; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 sbfree(sb, = m); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 n =3D m; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 sb->sb_mb =3D m; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (sb->sb_mb =3D=3D NULL) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 SB_EMPTY_FI= XUP(sb); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 n->m_next =3D NULL; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Copy the remainder. */ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (len > 0) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 KASSERT(sb->sb_mb !=3D NULL= , > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ("%s: len > 0 && sb= ->sb_mb empty", __func__)); > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 m =3D m_copym(sb->sb_mb, 0,= len, M_DONTWAIT); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (m =3D=3D NULL) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 len =3D 0; = =A0 =A0 =A0 =A0/* Don't flush data from sockbuf. */ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 else > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 uio->uio_re= sid -=3D m->m_len; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (*mp0 !=3D NULL) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 n->m_next = =3D m; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 else > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *mp0 =3D m; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (*mp0 =3D=3D NULL) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 error =3D E= NOBUFS; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto out; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 } else { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* NB: Must unlock socket buffer as uiomove= may sleep. */ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 SOCKBUF_UNLOCK(sb); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 error =3D m_mbuftouio(uio, sb->sb_mb, len); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 SOCKBUF_LOCK(sb); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (error) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto out; > + =A0 =A0 =A0 } > + =A0 =A0 =A0 SBLASTRECORDCHK(sb); > + =A0 =A0 =A0 SBLASTMBUFCHK(sb); > + > + =A0 =A0 =A0 /* > + =A0 =A0 =A0 =A0* Remove the delivered data from the socket buffer unles= s we > + =A0 =A0 =A0 =A0* were only peeking. > + =A0 =A0 =A0 =A0*/ > + =A0 =A0 =A0 if (!(flags & MSG_PEEK)) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (len > 0) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 sbdrop_locked(sb, len); > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Notify protocol that we drained some dat= a. */ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((so->so_proto->pr_flags & PR_WANTRCVD) = && > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (((flags & MSG_WAITALL) && uio->uio= _resid > 0) || > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0!(flags & MSG_SOCALLBCK))) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 SOCKBUF_UNLOCK(sb); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (*so->so_proto->pr_usrreqs-= >pru_rcvd)(so, flags); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 SOCKBUF_LOCK(sb); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 /* > + =A0 =A0 =A0 =A0* For MSG_WAITALL we may have to loop again and wait for > + =A0 =A0 =A0 =A0* more data to come in. > + =A0 =A0 =A0 =A0*/ > + =A0 =A0 =A0 if ((flags & MSG_WAITALL) && uio->uio_resid > 0) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto restart; > +out: > + =A0 =A0 =A0 SOCKBUF_LOCK_ASSERT(sb); > + =A0 =A0 =A0 SBLASTRECORDCHK(sb); > + =A0 =A0 =A0 SBLASTMBUFCHK(sb); > + =A0 =A0 =A0 SOCKBUF_UNLOCK(sb); > + =A0 =A0 =A0 sbunlock(sb); > + =A0 =A0 =A0 return (error); > +} > + > +/* > =A0* Optimized version of soreceive() for simple datagram cases from user= space. > =A0* Unlike in the stream case, we're able to drop a datagram if copyout(= ) > =A0* fails, and because we handle datagrams atomically, we don't need to = use a > > Modified: head/sys/netinet/tcp_usrreq.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > --- head/sys/netinet/tcp_usrreq.c =A0 =A0 =A0 Mon Jun 22 22:54:44 2009 = =A0 =A0 =A0 =A0(r194671) > +++ head/sys/netinet/tcp_usrreq.c =A0 =A0 =A0 Mon Jun 22 23:08:05 2009 = =A0 =A0 =A0 =A0(r194672) > @@ -1032,6 +1032,9 @@ struct pr_usrreqs tcp_usrreqs =3D { > =A0 =A0 =A0 =A0.pru_send =3D =A0 =A0 =A0 =A0 =A0 =A0 tcp_usr_send, > =A0 =A0 =A0 =A0.pru_shutdown =3D =A0 =A0 =A0 =A0 tcp_usr_shutdown, > =A0 =A0 =A0 =A0.pru_sockaddr =3D =A0 =A0 =A0 =A0 in_getsockaddr, > +#if 0 > + =A0 =A0 =A0 .pru_soreceive =3D =A0 =A0 =A0 =A0soreceive_stream, > +#endif > =A0 =A0 =A0 =A0.pru_sosetlabel =3D =A0 =A0 =A0 in_pcbsosetlabel, > =A0 =A0 =A0 =A0.pru_close =3D =A0 =A0 =A0 =A0 =A0 =A0tcp_usr_close, > =A0}; > @@ -1053,6 +1056,9 @@ struct pr_usrreqs tcp6_usrreqs =3D { > =A0 =A0 =A0 =A0.pru_send =3D =A0 =A0 =A0 =A0 =A0 =A0 tcp_usr_send, > =A0 =A0 =A0 =A0.pru_shutdown =3D =A0 =A0 =A0 =A0 tcp_usr_shutdown, > =A0 =A0 =A0 =A0.pru_sockaddr =3D =A0 =A0 =A0 =A0 in6_mapped_sockaddr, > +#if 0 > + =A0 =A0 =A0 .pru_soreceive =3D =A0 =A0 =A0 =A0soreceive_stream, > +#endif > =A0 =A0 =A0 =A0.pru_sosetlabel =3D =A0 =A0 =A0 in_pcbsosetlabel, > =A0 =A0 =A0 =A0.pru_close =3D =A0 =A0 =A0 =A0 =A0 =A0tcp_usr_close, > =A0}; > > Modified: head/sys/sys/socketvar.h > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > --- head/sys/sys/socketvar.h =A0 =A0Mon Jun 22 22:54:44 2009 =A0 =A0 =A0 = =A0(r194671) > +++ head/sys/sys/socketvar.h =A0 =A0Mon Jun 22 23:08:05 2009 =A0 =A0 =A0 = =A0(r194672) > @@ -345,6 +345,9 @@ int sopoll_generic(struct socket *so, in > =A0 =A0 =A0 =A0 =A0 =A0struct ucred *active_cred, struct thread *td); > =A0int =A0 =A0soreceive(struct socket *so, struct sockaddr **paddr, struc= t uio *uio, > =A0 =A0 =A0 =A0 =A0 =A0struct mbuf **mp0, struct mbuf **controlp, int *fl= agsp); > +int =A0 =A0soreceive_stream(struct socket *so, struct sockaddr **paddr, > + =A0 =A0 =A0 =A0 =A0 struct uio *uio, struct mbuf **mp0, struct mbuf **c= ontrolp, > + =A0 =A0 =A0 =A0 =A0 int *flagsp); > =A0int =A0 =A0soreceive_dgram(struct socket *so, struct sockaddr **paddr, > =A0 =A0 =A0 =A0 =A0 =A0struct uio *uio, struct mbuf **mp0, struct mbuf **= controlp, > =A0 =A0 =A0 =A0 =A0 =A0int *flagsp); > --=20 When bad men combine, the good must associate; else they will fall one by one, an unpitied sacrifice in a contemptible struggle. Edmund Burke