[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: mach_host_self() doesn't acquire new port name?!

From: Thomas Bushnell, BSG
Subject: Re: mach_host_self() doesn't acquire new port name?!
Date: 08 May 2001 11:48:44 -0700
User-agent: Gnus/5.0803 (Gnus v5.8.3) Emacs/20.7

Marcus Brinkmann <Marcus.Brinkmann@ruhr-uni-bochum.de> writes:

> BTW, what about the count of user refs in the port name entry of the tasks
> port name space?  We don't set any policy here, so I suspect that here a
> task will simply get a failure on overrunning the user references.

There are two ref counts to keep track of; I'll call these local and
global references.  A local reference is the number of user references
task T has to the right.  The task itself holds a single global
reference, which is the total number of tasks holding send rights for
the port.

Local references are the low order 16 bits of the ie_bits field in the
entry (see gnumach/ipc/ipc_entry.h).  Global references are the
ip_srights field of the port.

Ok, now your question is the following: there are only 16 bits of
local reference counts; if the total number of local references goes
over 2^16, what then?  What happens if a task calls mach_host_self
more times than that?

Well, the code in question is ipc_right_copyout is
gnumach/ipc/ipc_right.c, and is exactly what we've been looking at,
and it does the right thing.

> Also, I can't find any handling of underruns in dealloc (mod_refs has, see
> ipc_right_delta).  

What are you talking about here?  Where do you expect to see handling
of underruns but you don't?  In ipc_right.c:ipc_right_copyout, the
kernel is holding a (global) reference to the port; it is that
reference which is deallocated after the user-reference count is
incremented.  It can't underflow; it's got a reference that it's

> This would mean that it is a mistake to deallocate send
> rights (I think it could trigger first a wrong no-senders message, and then
> an assertion srights > 0. Imagine task A pushing the port srights count to
> the maximum, task B getting a user reference, task A deallocating all
> srights.  

You are confusing two send right counts here.  The local count is
purely local to A, and that's all that ipc_right_copyout is concerned
with.  No matter what the urefs value is in A, it only counts for a
single item in the ip_srights field on the port.

Now what if there are a bajillion tasks, and each has a send right to
the port?  Note that here we aren't talking about a leak anymore; it's
a question of just there being a lot of real genuine live references.
We are wondering, that is, what if ip_srights gets too big?

ipc_right_copyout and ipc_right_delta deal with changes to the urefs
(local) count.  To answer this question, we have to look further up.

The caller of ipc_right.c passes in the kernel's send right, which is
always global, and gets deallocated once the user's ref in
ipc_right_copyout is incremented.  ipc_right_copyout occurs in many
contexts, but in this code path, it works like this:

mach_host_self          (the trap)
  ipc_port_make_send    (increment the global ref)
  ipc_port_copyout_send (copyout a send right, throw it away on failure) 
    ipc_object_copyout  (copyout a send right)
      ipc_right_reverse (look up the name)
      ipc_entry_get     (allocate a new name if lookup failed)
      ipc_right_copyout (increment the user [local] reference count,
                         drop the global ref)

I don't know whether you noted it, but mach_host_self does not check
to see whether ipc_port_make_send will succeed.  However, note that
this is not a live failure; if there are really that many tasks, there
is just no hope.  The kernel actually *never* bothers to check to see
if incrementing ip_srights will succeed, but that's really ok, because
the only way to inflate the count is by creating a metric bajillion
tasks, and resource failure will occur long before that happens.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]