[linux-dvb] [PATCH] dvb-core: Fix several locking related problems.

Oliver Endriss o.endriss at gmx.de
Sat Mar 10 01:07:49 CET 2007


Johannes Stezenbach wrote:
> On Mon, Mar 05, 2007 at 06:19:01PM +0100, Oliver Endriss wrote:
> > 
> > From 'Linux Device Drivers' (replace 'down' by 'mutex_lock'):
> > | ...
> > | down decrements the value of the semaphore and waits as long as need
> > | be. down_ interruptible does the same, but the operation is
> > | interruptible. The interruptible version is almost always the one you
> > | will want; it allows a user-space process that is waiting on a
> > | semaphore to be interrupted by the user. You do not, as a general
> >                                            ^^^^^^^^^^^^^^^^^^^^^^^^
> > | rule, want to use noninterruptible operations unless there truly is no
> >   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > | alternative. Noninterruptible operations are a good way to create
> >   ^^^^^^^^^^^
> > | unkillable processes (the dreaded  D state  seen in ps), and annoy
> > | your users. Using down_interruptible requires some extra care,
> > | however, if the operation is interrupted, the function returns a
> > | nonzero value, and the caller does not hold the semaphore. Proper use
> > | of down_interruptible requires always checking the return value and
> > | responding accordingly.            
> > | ...
> 
> I don't think this advice applies to mutexes (at least if the
> mutexes are used in the usual way to protect some common data).
> 
> For event semaphores, you block waiting for an event, and if
> the event doesn't happen (maybe you wait for an irq), you need
> a way out or you're screwed. So using down_interruptible()
> is what you want.
> 
> Mutexes, however, are supposed to be held only while manipulating
> some shared data. So the code looks *always* like this:
> 
> 	mutex_lock(&mtx);
> 	do_something_with_shared_data();
> 	mutex_unlock(&mtx);
> 
> Now if some process sleeps uninterruptibly in mutex_lock(),
> some other process holds the mutex and sleeps in do_something().
> If it wedges up, you either have some locking bug
> (someone forgot a mutex_unlock()), or it wedged up in
> do_something(), and you got to fix *that*.

Well, your example is simple.
Locking is easy if there is only one mutex involved.

But there are a lot of mutexes/spinlocks/event semaphores in various
layers of the subsystem. I simply cannot tell whether a deadlock may
happen under some rare conditions or not...

> mutex_unlock_interruptible() would only help to paper over
> locking bugs, and its use in dvb-core comes from a straight
> conversion from down_interruptible(), which itself was used
> because it was once useful during development. How that the
> signal handling was found to be buggy I think it's much better
> to use mutex_lock() instead of fixing the mutex_unlock_interruptible()
> usage.
> 
> BTW, some statistics:
> 
> linux-2.6.20$ grep -r '\<mutex_lock\>' . | wc -l
> 3080
> linux-2.6.20$ grep -r '\<mutex_lock_interruptible\>' . | wc -l
> 236

Ok, to make it short:
Please proceed and apply this patch, or convert all occurrences of
mutex_lock_interruptible() to mutex_lock() if you prefer.
dvb_core is not my working area. ;-)

Oliver

-- 
--------------------------------------------------------
VDR Remote Plugin 0.3.9 available at
http://www.escape-edv.de/endriss/vdr/
--------------------------------------------------------




More information about the linux-dvb mailing list