diff options
Diffstat (limited to 'kernel/lockdep.c')
-rw-r--r-- | kernel/lockdep.c | 54 |
1 files changed, 31 insertions, 23 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c index dbda475b13bd..e4bdda8dcf04 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c | |||
@@ -136,16 +136,16 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock) | |||
136 | #ifdef CONFIG_LOCK_STAT | 136 | #ifdef CONFIG_LOCK_STAT |
137 | static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], lock_stats); | 137 | static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], lock_stats); |
138 | 138 | ||
139 | static int lock_contention_point(struct lock_class *class, unsigned long ip) | 139 | static int lock_point(unsigned long points[], unsigned long ip) |
140 | { | 140 | { |
141 | int i; | 141 | int i; |
142 | 142 | ||
143 | for (i = 0; i < ARRAY_SIZE(class->contention_point); i++) { | 143 | for (i = 0; i < LOCKSTAT_POINTS; i++) { |
144 | if (class->contention_point[i] == 0) { | 144 | if (points[i] == 0) { |
145 | class->contention_point[i] = ip; | 145 | points[i] = ip; |
146 | break; | 146 | break; |
147 | } | 147 | } |
148 | if (class->contention_point[i] == ip) | 148 | if (points[i] == ip) |
149 | break; | 149 | break; |
150 | } | 150 | } |
151 | 151 | ||
@@ -185,6 +185,9 @@ struct lock_class_stats lock_stats(struct lock_class *class) | |||
185 | for (i = 0; i < ARRAY_SIZE(stats.contention_point); i++) | 185 | for (i = 0; i < ARRAY_SIZE(stats.contention_point); i++) |
186 | stats.contention_point[i] += pcs->contention_point[i]; | 186 | stats.contention_point[i] += pcs->contention_point[i]; |
187 | 187 | ||
188 | for (i = 0; i < ARRAY_SIZE(stats.contending_point); i++) | ||
189 | stats.contending_point[i] += pcs->contending_point[i]; | ||
190 | |||
188 | lock_time_add(&pcs->read_waittime, &stats.read_waittime); | 191 | lock_time_add(&pcs->read_waittime, &stats.read_waittime); |
189 | lock_time_add(&pcs->write_waittime, &stats.write_waittime); | 192 | lock_time_add(&pcs->write_waittime, &stats.write_waittime); |
190 | 193 | ||
@@ -209,6 +212,7 @@ void clear_lock_stats(struct lock_class *class) | |||
209 | memset(cpu_stats, 0, sizeof(struct lock_class_stats)); | 212 | memset(cpu_stats, 0, sizeof(struct lock_class_stats)); |
210 | } | 213 | } |
211 | memset(class->contention_point, 0, sizeof(class->contention_point)); | 214 | memset(class->contention_point, 0, sizeof(class->contention_point)); |
215 | memset(class->contending_point, 0, sizeof(class->contending_point)); | ||
212 | } | 216 | } |
213 | 217 | ||
214 | static struct lock_class_stats *get_lock_stats(struct lock_class *class) | 218 | static struct lock_class_stats *get_lock_stats(struct lock_class *class) |
@@ -2169,12 +2173,11 @@ void early_boot_irqs_on(void) | |||
2169 | /* | 2173 | /* |
2170 | * Hardirqs will be enabled: | 2174 | * Hardirqs will be enabled: |
2171 | */ | 2175 | */ |
2172 | void trace_hardirqs_on_caller(unsigned long a0) | 2176 | void trace_hardirqs_on_caller(unsigned long ip) |
2173 | { | 2177 | { |
2174 | struct task_struct *curr = current; | 2178 | struct task_struct *curr = current; |
2175 | unsigned long ip; | ||
2176 | 2179 | ||
2177 | time_hardirqs_on(CALLER_ADDR0, a0); | 2180 | time_hardirqs_on(CALLER_ADDR0, ip); |
2178 | 2181 | ||
2179 | if (unlikely(!debug_locks || current->lockdep_recursion)) | 2182 | if (unlikely(!debug_locks || current->lockdep_recursion)) |
2180 | return; | 2183 | return; |
@@ -2188,7 +2191,6 @@ void trace_hardirqs_on_caller(unsigned long a0) | |||
2188 | } | 2191 | } |
2189 | /* we'll do an OFF -> ON transition: */ | 2192 | /* we'll do an OFF -> ON transition: */ |
2190 | curr->hardirqs_enabled = 1; | 2193 | curr->hardirqs_enabled = 1; |
2191 | ip = (unsigned long) __builtin_return_address(0); | ||
2192 | 2194 | ||
2193 | if (DEBUG_LOCKS_WARN_ON(!irqs_disabled())) | 2195 | if (DEBUG_LOCKS_WARN_ON(!irqs_disabled())) |
2194 | return; | 2196 | return; |
@@ -2224,11 +2226,11 @@ EXPORT_SYMBOL(trace_hardirqs_on); | |||
2224 | /* | 2226 | /* |
2225 | * Hardirqs were disabled: | 2227 | * Hardirqs were disabled: |
2226 | */ | 2228 | */ |
2227 | void trace_hardirqs_off_caller(unsigned long a0) | 2229 | void trace_hardirqs_off_caller(unsigned long ip) |
2228 | { | 2230 | { |
2229 | struct task_struct *curr = current; | 2231 | struct task_struct *curr = current; |
2230 | 2232 | ||
2231 | time_hardirqs_off(CALLER_ADDR0, a0); | 2233 | time_hardirqs_off(CALLER_ADDR0, ip); |
2232 | 2234 | ||
2233 | if (unlikely(!debug_locks || current->lockdep_recursion)) | 2235 | if (unlikely(!debug_locks || current->lockdep_recursion)) |
2234 | return; | 2236 | return; |
@@ -2241,7 +2243,7 @@ void trace_hardirqs_off_caller(unsigned long a0) | |||
2241 | * We have done an ON -> OFF transition: | 2243 | * We have done an ON -> OFF transition: |
2242 | */ | 2244 | */ |
2243 | curr->hardirqs_enabled = 0; | 2245 | curr->hardirqs_enabled = 0; |
2244 | curr->hardirq_disable_ip = _RET_IP_; | 2246 | curr->hardirq_disable_ip = ip; |
2245 | curr->hardirq_disable_event = ++curr->irq_events; | 2247 | curr->hardirq_disable_event = ++curr->irq_events; |
2246 | debug_atomic_inc(&hardirqs_off_events); | 2248 | debug_atomic_inc(&hardirqs_off_events); |
2247 | } else | 2249 | } else |
@@ -3001,7 +3003,7 @@ __lock_contended(struct lockdep_map *lock, unsigned long ip) | |||
3001 | struct held_lock *hlock, *prev_hlock; | 3003 | struct held_lock *hlock, *prev_hlock; |
3002 | struct lock_class_stats *stats; | 3004 | struct lock_class_stats *stats; |
3003 | unsigned int depth; | 3005 | unsigned int depth; |
3004 | int i, point; | 3006 | int i, contention_point, contending_point; |
3005 | 3007 | ||
3006 | depth = curr->lockdep_depth; | 3008 | depth = curr->lockdep_depth; |
3007 | if (DEBUG_LOCKS_WARN_ON(!depth)) | 3009 | if (DEBUG_LOCKS_WARN_ON(!depth)) |
@@ -3025,18 +3027,22 @@ __lock_contended(struct lockdep_map *lock, unsigned long ip) | |||
3025 | found_it: | 3027 | found_it: |
3026 | hlock->waittime_stamp = sched_clock(); | 3028 | hlock->waittime_stamp = sched_clock(); |
3027 | 3029 | ||
3028 | point = lock_contention_point(hlock_class(hlock), ip); | 3030 | contention_point = lock_point(hlock_class(hlock)->contention_point, ip); |
3031 | contending_point = lock_point(hlock_class(hlock)->contending_point, | ||
3032 | lock->ip); | ||
3029 | 3033 | ||
3030 | stats = get_lock_stats(hlock_class(hlock)); | 3034 | stats = get_lock_stats(hlock_class(hlock)); |
3031 | if (point < ARRAY_SIZE(stats->contention_point)) | 3035 | if (contention_point < LOCKSTAT_POINTS) |
3032 | stats->contention_point[point]++; | 3036 | stats->contention_point[contention_point]++; |
3037 | if (contending_point < LOCKSTAT_POINTS) | ||
3038 | stats->contending_point[contending_point]++; | ||
3033 | if (lock->cpu != smp_processor_id()) | 3039 | if (lock->cpu != smp_processor_id()) |
3034 | stats->bounces[bounce_contended + !!hlock->read]++; | 3040 | stats->bounces[bounce_contended + !!hlock->read]++; |
3035 | put_lock_stats(stats); | 3041 | put_lock_stats(stats); |
3036 | } | 3042 | } |
3037 | 3043 | ||
3038 | static void | 3044 | static void |
3039 | __lock_acquired(struct lockdep_map *lock) | 3045 | __lock_acquired(struct lockdep_map *lock, unsigned long ip) |
3040 | { | 3046 | { |
3041 | struct task_struct *curr = current; | 3047 | struct task_struct *curr = current; |
3042 | struct held_lock *hlock, *prev_hlock; | 3048 | struct held_lock *hlock, *prev_hlock; |
@@ -3085,6 +3091,7 @@ found_it: | |||
3085 | put_lock_stats(stats); | 3091 | put_lock_stats(stats); |
3086 | 3092 | ||
3087 | lock->cpu = cpu; | 3093 | lock->cpu = cpu; |
3094 | lock->ip = ip; | ||
3088 | } | 3095 | } |
3089 | 3096 | ||
3090 | void lock_contended(struct lockdep_map *lock, unsigned long ip) | 3097 | void lock_contended(struct lockdep_map *lock, unsigned long ip) |
@@ -3106,7 +3113,7 @@ void lock_contended(struct lockdep_map *lock, unsigned long ip) | |||
3106 | } | 3113 | } |
3107 | EXPORT_SYMBOL_GPL(lock_contended); | 3114 | EXPORT_SYMBOL_GPL(lock_contended); |
3108 | 3115 | ||
3109 | void lock_acquired(struct lockdep_map *lock) | 3116 | void lock_acquired(struct lockdep_map *lock, unsigned long ip) |
3110 | { | 3117 | { |
3111 | unsigned long flags; | 3118 | unsigned long flags; |
3112 | 3119 | ||
@@ -3119,7 +3126,7 @@ void lock_acquired(struct lockdep_map *lock) | |||
3119 | raw_local_irq_save(flags); | 3126 | raw_local_irq_save(flags); |
3120 | check_flags(flags); | 3127 | check_flags(flags); |
3121 | current->lockdep_recursion = 1; | 3128 | current->lockdep_recursion = 1; |
3122 | __lock_acquired(lock); | 3129 | __lock_acquired(lock, ip); |
3123 | current->lockdep_recursion = 0; | 3130 | current->lockdep_recursion = 0; |
3124 | raw_local_irq_restore(flags); | 3131 | raw_local_irq_restore(flags); |
3125 | } | 3132 | } |
@@ -3278,10 +3285,10 @@ void __init lockdep_info(void) | |||
3278 | { | 3285 | { |
3279 | printk("Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar\n"); | 3286 | printk("Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar\n"); |
3280 | 3287 | ||
3281 | printk("... MAX_LOCKDEP_SUBCLASSES: %lu\n", MAX_LOCKDEP_SUBCLASSES); | 3288 | printk("... MAX_LOCKDEP_SUBCLASSES: %lu\n", MAX_LOCKDEP_SUBCLASSES); |
3282 | printk("... MAX_LOCK_DEPTH: %lu\n", MAX_LOCK_DEPTH); | 3289 | printk("... MAX_LOCK_DEPTH: %lu\n", MAX_LOCK_DEPTH); |
3283 | printk("... MAX_LOCKDEP_KEYS: %lu\n", MAX_LOCKDEP_KEYS); | 3290 | printk("... MAX_LOCKDEP_KEYS: %lu\n", MAX_LOCKDEP_KEYS); |
3284 | printk("... CLASSHASH_SIZE: %lu\n", CLASSHASH_SIZE); | 3291 | printk("... CLASSHASH_SIZE: %lu\n", CLASSHASH_SIZE); |
3285 | printk("... MAX_LOCKDEP_ENTRIES: %lu\n", MAX_LOCKDEP_ENTRIES); | 3292 | printk("... MAX_LOCKDEP_ENTRIES: %lu\n", MAX_LOCKDEP_ENTRIES); |
3286 | printk("... MAX_LOCKDEP_CHAINS: %lu\n", MAX_LOCKDEP_CHAINS); | 3293 | printk("... MAX_LOCKDEP_CHAINS: %lu\n", MAX_LOCKDEP_CHAINS); |
3287 | printk("... CHAINHASH_SIZE: %lu\n", CHAINHASH_SIZE); | 3294 | printk("... CHAINHASH_SIZE: %lu\n", CHAINHASH_SIZE); |
@@ -3417,9 +3424,10 @@ retry: | |||
3417 | } | 3424 | } |
3418 | printk(" ignoring it.\n"); | 3425 | printk(" ignoring it.\n"); |
3419 | unlock = 0; | 3426 | unlock = 0; |
3427 | } else { | ||
3428 | if (count != 10) | ||
3429 | printk(KERN_CONT " locked it.\n"); | ||
3420 | } | 3430 | } |
3421 | if (count != 10) | ||
3422 | printk(" locked it.\n"); | ||
3423 | 3431 | ||
3424 | do_each_thread(g, p) { | 3432 | do_each_thread(g, p) { |
3425 | /* | 3433 | /* |