Subject: Re: Prototype kernel continuation-passing for NetBSD
To: Jonathan Stone <jonathan@dsg.stanford.edu>
From: Matt Thomas <matt@3am-software.com>
List: tech-kern
Date: 03/27/2004 13:56:19
At 12:40 PM 3/27/2004, Jonathan Stone wrote:
>In message <FFF15B15-8027-11D8-8447-000A957020BC@3am-software.com>,
>Matt Thomas writes:
>
> >
> >On Mar 27, 2004, at 10:35 AM, Jonathan Stone wrote:
> >
>[... snip lots... ]
>
> >Don't pass in a NULL uio.
>
>I've tried.  Passing NULL uios to sosend() is the only sane way to go.
>The alternative is preallocating uios and wrapping mbufs chains you
>just read from one socket, inside a UIO_SYSPACE uio before sending
>them on another socket: thats a non-starter for performance reasons.
>Also, last I looked, it still doeesn't guarantee the atomic-send,
>record-boundary semantics needed for SOCK_DGRAM.

I don't think you were paying attention.  You can get the current
behavior by changing if (uio) to if (uio && uio->uio_iov) and
if (uio == NULL) to if (uio == NULL || uio->uio_iov == NULL).

This means you can passing a uio with uio_iov = NULL and it will
be as if you hadn't a uio at all.  (except for being able to specify
uio->uio_procp).

>[ ... Explicit struct proc* to so_send().. ]
>
>I never kept a list of what curproc gets used for, once sosend() grabs
>it and passes it down. I'm willing to entertain making sosend() work
>as you suggest -- or at least, to figure out if there are issues
>significant enough (more than the message-send counters), that warrant
>passing the struct proc *.

It does get passed to pr_usrreq.  But see above.

>I do have dim memories of code somewhere grabbing process credentials;
>but I've been using code that passes the explicit struct proc * to
>sosend() for so long that I honestly don't remember.

That's done in sorecieve and that does a uio with UIO_USERSPACE.

>FWIW, I originally tried a slightly different argument ordering, till
>I noticed the netsmb code claims other *BSDs all pass sosend() and
>so->so_send() a last argument that's the struct proc *.  The
>argument-lists to sosend() are already so big they overflow RISC
>in-register passing conventions, and dirty enough stack cache-lines,
>that (once calling sosend() from kconts tripped over the curproc) I'm
>willing to pass the process pointer, just for uniformity, for
>consistency with the non-kcont case, and for ease-of-use reading and
>porting other *BSD networking code.

Ok.  I've relented.  The usrreq is what convinced me.

>Whatever's best, really. I see this as something gentlepersons can
>agree to disagree in good faith :-/. As long as I can call sosend()
>RSN from kcont-context where curproc is NULL or otherwise not valid or
>not appropriate, I'll be content.

However, I do think that passing in curproc is wrong.  If you are
running off a softintr event, the supplied proc pointer must be 0.

I have set of changes I'll commit after the 2.0 branch.

-- 
Matt Thomas                     email: matt@3am-software.com
3am Software Foundry              www: http://3am-software.com/bio/matt/
Cupertino, CA              disclaimer: I avow all knowledge of this message.