diff options
Diffstat (limited to 'kernel/lockdep.c')
-rw-r--r-- | kernel/lockdep.c | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 81a4e4a3f087..65548eff029e 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/irqflags.h> | 39 | #include <linux/irqflags.h> |
40 | #include <linux/utsname.h> | 40 | #include <linux/utsname.h> |
41 | #include <linux/hash.h> | 41 | #include <linux/hash.h> |
42 | #include <linux/ftrace.h> | ||
42 | 43 | ||
43 | #include <asm/sections.h> | 44 | #include <asm/sections.h> |
44 | 45 | ||
@@ -81,6 +82,8 @@ static int graph_lock(void) | |||
81 | __raw_spin_unlock(&lockdep_lock); | 82 | __raw_spin_unlock(&lockdep_lock); |
82 | return 0; | 83 | return 0; |
83 | } | 84 | } |
85 | /* prevent any recursions within lockdep from causing deadlocks */ | ||
86 | current->lockdep_recursion++; | ||
84 | return 1; | 87 | return 1; |
85 | } | 88 | } |
86 | 89 | ||
@@ -89,6 +92,7 @@ static inline int graph_unlock(void) | |||
89 | if (debug_locks && !__raw_spin_is_locked(&lockdep_lock)) | 92 | if (debug_locks && !__raw_spin_is_locked(&lockdep_lock)) |
90 | return DEBUG_LOCKS_WARN_ON(1); | 93 | return DEBUG_LOCKS_WARN_ON(1); |
91 | 94 | ||
95 | current->lockdep_recursion--; | ||
92 | __raw_spin_unlock(&lockdep_lock); | 96 | __raw_spin_unlock(&lockdep_lock); |
93 | return 0; | 97 | return 0; |
94 | } | 98 | } |
@@ -982,7 +986,7 @@ check_noncircular(struct lock_class *source, unsigned int depth) | |||
982 | return 1; | 986 | return 1; |
983 | } | 987 | } |
984 | 988 | ||
985 | #ifdef CONFIG_TRACE_IRQFLAGS | 989 | #if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING) |
986 | /* | 990 | /* |
987 | * Forwards and backwards subgraph searching, for the purposes of | 991 | * Forwards and backwards subgraph searching, for the purposes of |
988 | * proving that two subgraphs can be connected by a new dependency | 992 | * proving that two subgraphs can be connected by a new dependency |
@@ -1680,7 +1684,7 @@ valid_state(struct task_struct *curr, struct held_lock *this, | |||
1680 | static int mark_lock(struct task_struct *curr, struct held_lock *this, | 1684 | static int mark_lock(struct task_struct *curr, struct held_lock *this, |
1681 | enum lock_usage_bit new_bit); | 1685 | enum lock_usage_bit new_bit); |
1682 | 1686 | ||
1683 | #ifdef CONFIG_TRACE_IRQFLAGS | 1687 | #if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING) |
1684 | 1688 | ||
1685 | /* | 1689 | /* |
1686 | * print irq inversion bug: | 1690 | * print irq inversion bug: |
@@ -2013,11 +2017,13 @@ void early_boot_irqs_on(void) | |||
2013 | /* | 2017 | /* |
2014 | * Hardirqs will be enabled: | 2018 | * Hardirqs will be enabled: |
2015 | */ | 2019 | */ |
2016 | void trace_hardirqs_on(void) | 2020 | void trace_hardirqs_on_caller(unsigned long a0) |
2017 | { | 2021 | { |
2018 | struct task_struct *curr = current; | 2022 | struct task_struct *curr = current; |
2019 | unsigned long ip; | 2023 | unsigned long ip; |
2020 | 2024 | ||
2025 | time_hardirqs_on(CALLER_ADDR0, a0); | ||
2026 | |||
2021 | if (unlikely(!debug_locks || current->lockdep_recursion)) | 2027 | if (unlikely(!debug_locks || current->lockdep_recursion)) |
2022 | return; | 2028 | return; |
2023 | 2029 | ||
@@ -2055,16 +2061,23 @@ void trace_hardirqs_on(void) | |||
2055 | curr->hardirq_enable_event = ++curr->irq_events; | 2061 | curr->hardirq_enable_event = ++curr->irq_events; |
2056 | debug_atomic_inc(&hardirqs_on_events); | 2062 | debug_atomic_inc(&hardirqs_on_events); |
2057 | } | 2063 | } |
2064 | EXPORT_SYMBOL(trace_hardirqs_on_caller); | ||
2058 | 2065 | ||
2066 | void trace_hardirqs_on(void) | ||
2067 | { | ||
2068 | trace_hardirqs_on_caller(CALLER_ADDR0); | ||
2069 | } | ||
2059 | EXPORT_SYMBOL(trace_hardirqs_on); | 2070 | EXPORT_SYMBOL(trace_hardirqs_on); |
2060 | 2071 | ||
2061 | /* | 2072 | /* |
2062 | * Hardirqs were disabled: | 2073 | * Hardirqs were disabled: |
2063 | */ | 2074 | */ |
2064 | void trace_hardirqs_off(void) | 2075 | void trace_hardirqs_off_caller(unsigned long a0) |
2065 | { | 2076 | { |
2066 | struct task_struct *curr = current; | 2077 | struct task_struct *curr = current; |
2067 | 2078 | ||
2079 | time_hardirqs_off(CALLER_ADDR0, a0); | ||
2080 | |||
2068 | if (unlikely(!debug_locks || current->lockdep_recursion)) | 2081 | if (unlikely(!debug_locks || current->lockdep_recursion)) |
2069 | return; | 2082 | return; |
2070 | 2083 | ||
@@ -2082,7 +2095,12 @@ void trace_hardirqs_off(void) | |||
2082 | } else | 2095 | } else |
2083 | debug_atomic_inc(&redundant_hardirqs_off); | 2096 | debug_atomic_inc(&redundant_hardirqs_off); |
2084 | } | 2097 | } |
2098 | EXPORT_SYMBOL(trace_hardirqs_off_caller); | ||
2085 | 2099 | ||
2100 | void trace_hardirqs_off(void) | ||
2101 | { | ||
2102 | trace_hardirqs_off_caller(CALLER_ADDR0); | ||
2103 | } | ||
2086 | EXPORT_SYMBOL(trace_hardirqs_off); | 2104 | EXPORT_SYMBOL(trace_hardirqs_off); |
2087 | 2105 | ||
2088 | /* | 2106 | /* |
@@ -2246,7 +2264,7 @@ static inline int separate_irq_context(struct task_struct *curr, | |||
2246 | * Mark a lock with a usage bit, and validate the state transition: | 2264 | * Mark a lock with a usage bit, and validate the state transition: |
2247 | */ | 2265 | */ |
2248 | static int mark_lock(struct task_struct *curr, struct held_lock *this, | 2266 | static int mark_lock(struct task_struct *curr, struct held_lock *this, |
2249 | enum lock_usage_bit new_bit) | 2267 | enum lock_usage_bit new_bit) |
2250 | { | 2268 | { |
2251 | unsigned int new_mask = 1 << new_bit, ret = 1; | 2269 | unsigned int new_mask = 1 << new_bit, ret = 1; |
2252 | 2270 | ||
@@ -2686,7 +2704,7 @@ static void check_flags(unsigned long flags) | |||
2686 | * and also avoid lockdep recursion: | 2704 | * and also avoid lockdep recursion: |
2687 | */ | 2705 | */ |
2688 | void lock_acquire(struct lockdep_map *lock, unsigned int subclass, | 2706 | void lock_acquire(struct lockdep_map *lock, unsigned int subclass, |
2689 | int trylock, int read, int check, unsigned long ip) | 2707 | int trylock, int read, int check, unsigned long ip) |
2690 | { | 2708 | { |
2691 | unsigned long flags; | 2709 | unsigned long flags; |
2692 | 2710 | ||
@@ -2708,7 +2726,8 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass, | |||
2708 | 2726 | ||
2709 | EXPORT_SYMBOL_GPL(lock_acquire); | 2727 | EXPORT_SYMBOL_GPL(lock_acquire); |
2710 | 2728 | ||
2711 | void lock_release(struct lockdep_map *lock, int nested, unsigned long ip) | 2729 | void lock_release(struct lockdep_map *lock, int nested, |
2730 | unsigned long ip) | ||
2712 | { | 2731 | { |
2713 | unsigned long flags; | 2732 | unsigned long flags; |
2714 | 2733 | ||