diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2008-08-11 03:30:24 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-08-11 03:30:24 -0400 |
commit | 7531e2f34d1d551b096143f19111139f0dd84c8b (patch) | |
tree | 0a29d6703e28dc6752b9b4085594cca238595aac /include/linux/rcuclassic.h | |
parent | 4f3e7524b2e703d9f8b02ac338153a53dd7ede66 (diff) |
lockdep: lock protection locks
On Fri, 2008-08-01 at 16:26 -0700, Linus Torvalds wrote:
> On Fri, 1 Aug 2008, David Miller wrote:
> >
> > Taking more than a few locks of the same class at once is bad
> > news and it's better to find an alternative method.
>
> It's not always wrong.
>
> If you can guarantee that anybody that takes more than one lock of a
> particular class will always take a single top-level lock _first_, then
> that's all good. You can obviously screw up and take the same lock _twice_
> (which will deadlock), but at least you cannot get into ABBA situations.
>
> So maybe the right thing to do is to just teach lockdep about "lock
> protection locks". That would have solved the multi-queue issues for
> networking too - all the actual network drivers would still have taken
> just their single queue lock, but the one case that needs to take all of
> them would have taken a separate top-level lock first.
>
> Never mind that the multi-queue locks were always taken in the same order:
> it's never wrong to just have some top-level serialization, and anybody
> who needs to take <n> locks might as well do <n+1>, because they sure as
> hell aren't going to be on _any_ fastpaths.
>
> So the simplest solution really sounds like just teaching lockdep about
> that one special case. It's not "nesting" exactly, although it's obviously
> related to it.
Do as Linus suggested. The lock protection lock is called nest_lock.
Note that we still have the MAX_LOCK_DEPTH (48) limit to consider, so anything
that spills that it still up shit creek.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include/linux/rcuclassic.h')
-rw-r--r-- | include/linux/rcuclassic.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/include/linux/rcuclassic.h b/include/linux/rcuclassic.h index 8c774905dcfe..4ab843622727 100644 --- a/include/linux/rcuclassic.h +++ b/include/linux/rcuclassic.h | |||
@@ -117,7 +117,7 @@ extern int rcu_needs_cpu(int cpu); | |||
117 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 117 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
118 | extern struct lockdep_map rcu_lock_map; | 118 | extern struct lockdep_map rcu_lock_map; |
119 | # define rcu_read_acquire() \ | 119 | # define rcu_read_acquire() \ |
120 | lock_acquire(&rcu_lock_map, 0, 0, 2, 1, _THIS_IP_) | 120 | lock_acquire(&rcu_lock_map, 0, 0, 2, 1, NULL, _THIS_IP_) |
121 | # define rcu_read_release() lock_release(&rcu_lock_map, 1, _THIS_IP_) | 121 | # define rcu_read_release() lock_release(&rcu_lock_map, 1, _THIS_IP_) |
122 | #else | 122 | #else |
123 | # define rcu_read_acquire() do { } while (0) | 123 | # define rcu_read_acquire() do { } while (0) |