Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 11 Nov 2001 10:31:54 -0500 (EST)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        freebsd-arch@FreeBSD.org
Subject:   cur{thread/proc}, or not.
Message-ID:  <Pine.NEB.3.96L.1011111101234.11566A-100000@fledge.watson.org>

next in thread | raw e-mail | index | archive | help

Every now and then, we get to discuss curproc, and its merits.  Let's do
it again.

There are a number of uses of curproc in the netinet code, used to
retrieve credentials for authorization somewhere down the stack, when no
proc or thread pointer has been passed down.  With the eventual addition
of td->td_ucred, it will be desirable to use the credential for the
current thread, rather than the proc, which will require locking to use. 
(This is, incidentally, true of many places in the system).  As I
understand it, use of curproc was branded 'undesirable' at some point in
the semi-distant past, and since that time, a reference to 'proc' has been
passed down the stack.  With a change to KSE, this has been translated to
references the thread, but the issue remains the same.  This comes up in
particular because I have a tree where I have propagated the thread
pointer down if_ioctl in the network stack: the normal ioctl call carries
a thread pointer now, but when it is translated into if_ioctl by the
network stack, that pointer is lost.  This raises the question: should we
(in practice) be adding process or thread pointers to many more of the
function arguments, or should we switch to using curproc/curthread
instead. 

The argument I've seen a couple of times for using the proc/thread pointer
is that of delegation: a kernel thread might be acting on behalf of
another process, and need a reference to the process so that it can use
its (file descriptors, credential, address space, ...).  I suspect that,
in practice, this is a Bad Idea, given the increased complexity of
fine-grained threading/locking and SMPng.  "borrowing" references in such
an environment seems like a recipe for buginess, and instead such
references should be "given" by the thread that obeys the
locking/reference counting, and should not be done at the level of the
proc.  For example, for a credential, you would simply grab another
reference to the credential and pass off the reference, rather than
sharing a reference.  In fact, it seems that in a lot of places where a
struct proc is passed in, the implicit assumption of the code is that this
is the "current process", and as we add more process-related locking, that
assumption will probably only grow stronger, so as to not raise lock order
issues. 

I don't pretend to have a grasp of all the issues here, so the purpose of
this message is to raise the issues so that I can understand them.  I have
a tree where I've eliminated many references to curproc; however, I'm now
wondering if it wouldn't simply be more useful to eliminate many of the
references to struct proc in the function arguments, and use curproc
instead, and add references to ucred (and related ref-counted structures)
as needed for delegation types of situations.  In particular, that would
suggest the following changes: 

(1) 'suser' would always use 'curthread', and lose its proc/thread
    argument (proc in the main tree, thread in my tree).  'suser_cred'
    would be used for delegation situations (as is the case in my tree). 

    (Note that this remains incompatible with other platforms, which
    generally accept a cred argument for 'suser', including other *BSD and
    Solaris.) 

(2) proc/thread arguments would (in general) be removed (gradually) from
    the arguments of many existing kernel functions, and
    'curproc'/'curthread' would be used instead.  For example, in the
    'VOP_*' interface, use of the 'p' or 'td' entries would be abandoned,
    and 'cred' would be more widely passed down (such as into open). 

    (Note that this is the path taken by a number of other fine-grained
    UNIX kernels, including Solaris, IRIX, et al). 

(3) Use of 'curproc' would be removed in a number of places, where
    abstracted functions such as 'suser' would invoke curthread instead.

It seems to me that unless a very strong argument exists against using
curproc/curthread (and I don't preclude one existing), using them would
actually be an improvement, as it would assert that this class of
'borrowing' couldn't exist, simplifying the kernel, not to mention
squeezing a bit more stuff out of the stack (which, at ten levels deep,
actually begins to add up on 64-bit machines).  I believe that there are
many places where the 'p' passed in is implicitly assumed to be the
current process, and that making that reliance explicit would be an
improvement, rather than a problem. 

Flames appreciated. 

Robert N M Watson             FreeBSD Core Team, TrustedBSD Project
robert@fledge.watson.org      NAI Labs, Safeport Network Services


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.NEB.3.96L.1011111101234.11566A-100000>