aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorGregory Haskins <ghaskins@novell.com>2007-10-11 16:11:11 -0400
committerPeter Zijlstra <a.p.zijlstra@chello.nl>2007-10-11 16:11:11 -0400
commit3aa416b07f0adf01c090baab26fb70c35ec17623 (patch)
treea2c2c2f7bd8445b138b293ba6661833f970954ee /kernel
parent94c61c0aeffe64452e742087cf803d0347ef8418 (diff)
lockdep: fix mismatched lockdep_depth/curr_chain_hash
It is possible for the current->curr_chain_key to become inconsistent with the current index if the chain fails to validate. The end result is that future lock_acquire() operations may inadvertently fail to find a hit in the cache resulting in a new node being added to the graph for every acquire. Signed-off-by: Gregory Haskins <ghaskins@novell.com> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/lockdep.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 734da579ad13..42ae4a5ab4dc 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -1521,7 +1521,7 @@ cache_hit:
1521} 1521}
1522 1522
1523static int validate_chain(struct task_struct *curr, struct lockdep_map *lock, 1523static int validate_chain(struct task_struct *curr, struct lockdep_map *lock,
1524 struct held_lock *hlock, int chain_head) 1524 struct held_lock *hlock, int chain_head, u64 chain_key)
1525{ 1525{
1526 /* 1526 /*
1527 * Trylock needs to maintain the stack of held locks, but it 1527 * Trylock needs to maintain the stack of held locks, but it
@@ -1534,7 +1534,7 @@ static int validate_chain(struct task_struct *curr, struct lockdep_map *lock,
1534 * graph_lock for us) 1534 * graph_lock for us)
1535 */ 1535 */
1536 if (!hlock->trylock && (hlock->check == 2) && 1536 if (!hlock->trylock && (hlock->check == 2) &&
1537 lookup_chain_cache(curr->curr_chain_key, hlock->class)) { 1537 lookup_chain_cache(chain_key, hlock->class)) {
1538 /* 1538 /*
1539 * Check whether last held lock: 1539 * Check whether last held lock:
1540 * 1540 *
@@ -1576,7 +1576,7 @@ static int validate_chain(struct task_struct *curr, struct lockdep_map *lock,
1576#else 1576#else
1577static inline int validate_chain(struct task_struct *curr, 1577static inline int validate_chain(struct task_struct *curr,
1578 struct lockdep_map *lock, struct held_lock *hlock, 1578 struct lockdep_map *lock, struct held_lock *hlock,
1579 int chain_head) 1579 int chain_head, u64 chain_key)
1580{ 1580{
1581 return 1; 1581 return 1;
1582} 1582}
@@ -2450,11 +2450,11 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
2450 chain_head = 1; 2450 chain_head = 1;
2451 } 2451 }
2452 chain_key = iterate_chain_key(chain_key, id); 2452 chain_key = iterate_chain_key(chain_key, id);
2453 curr->curr_chain_key = chain_key;
2454 2453
2455 if (!validate_chain(curr, lock, hlock, chain_head)) 2454 if (!validate_chain(curr, lock, hlock, chain_head, chain_key))
2456 return 0; 2455 return 0;
2457 2456
2457 curr->curr_chain_key = chain_key;
2458 curr->lockdep_depth++; 2458 curr->lockdep_depth++;
2459 check_chain_key(curr); 2459 check_chain_key(curr);
2460#ifdef CONFIG_DEBUG_LOCKDEP 2460#ifdef CONFIG_DEBUG_LOCKDEP