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.