Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 Sep 2000 07:29:55 -0400 (EDT)
From:      Daniel Eischen <eischen@vigrid.com>
To:        Matt Dillon <dillon@earth.backplane.com>
Cc:        John Polstra <jdp@polstra.com>, arch@FreeBSD.ORG
Subject:   Re: Mutexes and semaphores
Message-ID:  <Pine.SUN.3.91.1000926065812.26612A-100000@pcnet1.pcnet.com>
In-Reply-To: <200009252123.e8PLN5F84806@earth.backplane.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 25 Sep 2000, Matt Dillon wrote:
> :
> :Mutexes should protect data.  If you want to allow recursive ownership of
> :data, then keep your own owner and ref count field in the protected data
> :and use the mutex properly (release it after setting the owner or 
> :incrementing the ref count).  You don't need to hold the mutex, and
> :now you can use the same mutex for msleep/cv_wait.
> :
> :-- 
> :Dan Eischen
> 
>     Mutexes protect data *CONSISTENCY*, not data.  There is a big difference.
>     Probably 95% of the kernel assumes data consistency throughout any given
>     routine.  If that routine must call other routines (and most do), then
>     you have a major issue to contend with in regards to how to maintain
>     consistency across the call.
> 
>     There are several ways to deal with it:
> 
> 	* The subroutine calls are not allowed to block - lots of examples of
> 	  this in the VM and other subsystems.
> 
> 	* You use a heavy-weight lock instead of a mutex - an example
> 	  of this would be the VFS subsystem (vnode locks).
> 
> 	* You engineer the code to allow data to change out from under
> 	  it at certain points (such as when something blocks) - probably
> 	  the best example is vm_fault in the VM subsystem.
> 
>     Unfortunately, all but the first can lead to serious bugs.  Consider
>     how many bugs have been fixed in the VFS and VM subsystems just in the
>     last year that have been related to data consistency issues and you'll
>     understand.
> 
>     The first issue - not allowing a subroutine call to block, when such a
>     case exists, is the perfect place to put a recursive mutex.  If you don't
>     use a recursive mutex at that point then you wind up having to 
>     reengineer and rewrite big pieces of the code, or you wind up writing
>     lots of little tag routines to do end-runs around the mutexes or to
>     pass a flag that indicates that the mutex is already held and should
>     not be obtained again, and so forth.  
> 
>     Remember, I'm not talking about subsystem A calling subsystem B here,
>     I'm talking about subsystem A calling itself.  That is, a situation
>     where you are not obtaining several different mutexes but are instead
>     obtaining the same mutex several times.

If you absolutley need recursive mutexes, then roll your own and keep
the base mutex simple.  This is trivial to do and makes the base mutex
more efficient without the need to check for recursive ownership.

Mutexes should be held for very short amounts of time, and it
should be apparent in the encompassing code where the mutex is
taken and where it is released.  In your example, what do you
do in the case of abnormal exits from recursively called code?
It makes it far more easier to handle this situation if you roll
your own mutex and keep track of the ref count and owner yourself.  
If you don't, you'll end up adding mtx_exit_and_clear_refcount().

My main concern is not to eliminate recursive mutexes, though
I still think they should go.  I would like to see all barriers
to eliminating the flags/options to mtx_enter() and mtx_exit()
removed.  The current form of the mutex routines is not an API/ABI
we should be using.

-- 
Dan Eischen


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.SUN.3.91.1000926065812.26612A-100000>