Re: Semphore -> mutex in the device tree

!MAILaRCHIVE_VOTE_RePLACE
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: Alan Stern <stern@...>
Cc: Kernel development list <linux-kernel@...>, Ingo Molnar <mingo@...>, Paul E McKenney <paulmck@...>
Date: Friday, April 18, 2008 - 11:32 am

On Fri, 2008-04-18 at 10:27 -0400, Alan Stern wrote:

Yes, it is fully class based.


Do I interpert this correct when I envision a call-chain like this:

  register_devise(A, some_parent)
    lock_device(A, NESTING_PARENT)
    D->probe()
      register_device(B, A)
      lock_device(B, NESTING_PARENT)

That would work iff register_device() sets a tree-level class on B that
is one down from A.


Yes, associate a class with each level like this:

static struct lockdep_class_key device_tree_class[MAX_DEVICE_TREE_DEPTH];

register_device(child, parent)
{
	...
	child->depth = parent->depth + 1;
	WARN_ON(child->depth > MAX_DEVICE_TREE_DEPTH);
	mutex_destroy(&child->lock);
	mutex_init(&child->lock);
	lockdep_set_class(&child->lock, &device_tree_class[child->depth]);
	...
}

Now suppose we have a tree like:

0          A
         / | \
1       B  C  D
            / | \
2          E  F  F
           |
3          H


Now, you can lock the whole path to H like:

  mutex_lock(&A->lock);
  mutex_lock(&D->lock);
  mutex_unlock(&A->lock);
  mutex_lock(&E->lock);
  mutex_unlock(&D->lock);
  mutex_lock(&H->lock);
  mutex_unlock(&E->lock);

  < H locked >

without a single other lockdep annotation; this will teach lockdep the
following class order:

  device_tree_class[0]
    device_tree_class[1]
      device_tree_class[2]
        device_tree_class[3]

So a lock sequence like:

  mutex_lock(&E->lock);
  mutex_lock(&D->lock);

Which will go from 2 -> 1, will generate a complaint.

So, now your sibling scenario:

Lock D, E and F:

  mutex_lock(&D->lock);
  mutex_lock(&E->lock);
  mutex_lock_nested(&F->lock, SINGLE_DEPTH_NESTING);

This will teach lockdep the following class order:

  device_tree_class[1]
    device_tree_class[2]
      device_tree_class[2].subclass[1]

So, if at another time you do:

  mutex_lock(&D->lock);
  mutex_lock(&F->lock);
  mutex_lock(&E->lock, SINGLE_DEPTH_NESTING);

you're still obeying that order; of course you have to somehow guarantee
that it will never actually deadlock - otherwise you annotate a genuine
warning away.

                                    ^ B, right?

Interesting.. yes, this would make lockdep upset - basically because you
introduce nesting of M.

  device_tree_class[4]
    M_class
      device_tree_class[5]
        M_class

So you take M_class inside M_class.

Is this a common scenario? Normally a driver would only deal with a
single device instance at a time, so I guess that once this scenario can
happen the driver is already aware of this, right?

It would need a separate annotation; if the coupling would be static
(ps2 keyboard/mouse comes to mind) then the driver can have different
lockdep_class_key instances.


--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
Semphore -&gt; mutex in the device tree, Alan Stern, (Thu Apr 17, 11:22 am)
Re: Semphore -&gt; mutex in the device tree, Peter Zijlstra, (Thu Apr 17, 11:45 am)
Re: Semphore -&gt; mutex in the device tree, Alan Stern, (Thu Apr 17, 12:11 pm)
Re: Semphore -&gt; mutex in the device tree, Peter Zijlstra, (Thu Apr 17, 12:17 pm)
Re: Semphore -&gt; mutex in the device tree, Alan Stern, (Thu Apr 17, 2:43 pm)
Re: Semphore -&gt; mutex in the device tree, Peter Zijlstra, (Fri Apr 18, 2:32 am)
Re: Semphore -&gt; mutex in the device tree, Alan Stern, (Fri Apr 18, 10:27 am)
Re: Semphore -> mutex in the device tree, Peter Zijlstra, (Fri Apr 18, 11:32 am)
Re: Semphore -&gt; mutex in the device tree, Alan Stern, (Fri Apr 18, 5:45 pm)