Date: Sat, 19 Dec 1998 02:05:54 -0800 (PST) From: Matthew Dillon <dillon@apollo.backplane.com> To: Archie Cobbs <archie@whistle.com> Cc: freebsd-current@FreeBSD.ORG Subject: Re: asleep()/await(), M_AWAIT, etc... Message-ID: <199812191005.CAA07224@apollo.backplane.com> References: <199812190809.AAA27615@bubba.whistle.com>
next in thread | previous in thread | raw e-mail | index | archive | help
:
:Matthew Dillon writes:
:> We add an asleep() kernel function to complement tsleep(). asleep()
:> works like tsleep() in that it adds the process to the appropriate
:> slpque, but asleep() does *not* put the process to sleep. Instead it
:> returns immediately. The process stays runnable. Additional calls
:> to asleep() (or a call to tsleep()) removes the proc from any slpque
:> and re-adds it to the new one. i.e. only the most recent call is
:> effective.
:>
:> We add an await() kernel function. This function initiates any timeout
:> and puts the process to sleep, but only if it is still on a sleep queue.
:> If someone (i.e. an interrupt) wakes up the sleep address after the
:> process calls asleep() but before it calls await(), the slpque is
:> cleared and the await() winds up being a NOP.
:
:Hmm.. sounds interesting. Seems like one problem is that most
:function calls have the semantics that they don't return until
:the job they are supposed to do is finished. This would change.
:
:So you would have to adjust all the upper layer functions to take
:account of this change in semantics (they'd have to know to call
:await() at the least, of course).
:
:Also, this only works once; you can't call two subroutines
:in a row that both call asleep(), because the second asleep()
:will erase the first.
:
:But in certain cases where you don't need to hold a lock for
:the duration of the lengthy operation it would definitely help
:reduce contention.
:
:It would be interesting to see a list of specific cases where
:this could be used and would make a significant difference.
It's something we could work on from the bottom-up. We
would not have to change everything at once. For example, giving
the (kernel) malloc an M_AWAIT capability would require fixing
kmem_malloc and vm_page_alloc, but nothing else. We can then
'fix' routines that call malloc individually (and then only if
necessary or prudent). Those routines can still maintain the
fully-synchronous semantics their callers expect and still
use the new malloc feature. Ultimately the capability can be
propogated back further, especially with those functions that
are already passed a flags argument and can thus operate
both fully synchronously and semi-synchronously.
Truth be said, we don't want to necessarily change the semantics
for all the routines to be totally asynchronous - probably 80%
of the cases can remain synchronous because they guarentee the
lock order. Ultimately I think around 20% of the current code
would benefit from a new locking scheme, especially when SMP locks
are brought in further.
The biggest use of the feature would be the short-term unwinding of
locks in order to be able to block without holding any (or too many),
and the second biggest use would be to unwind an upper-level lock
when we fail to get a lower-level lock in a non-blocking fashion (i.e.
unwind a potential deadlock) in order to retry both locks later when we
'might' be able to get the inner lock again. ( This situation is
actually somewhat more complex since the issue of deadlock detection
is rather complex, but it would solve most 2-level deadlock situations
almost trivially ).
-Matt
:-Archie
:
:___________________________________________________________________________
:Archie Cobbs * Whistle Communications, Inc. * http://www.whistle.com
:
Matthew Dillon Engineering, HiWay Technologies, Inc. & BEST Internet
Communications & God knows what else.
<dillon@backplane.com> (Please include original email in any response)
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199812191005.CAA07224>
