aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/lockdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/lockdep.c')
-rw-r--r--kernel/lockdep.c54
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
137static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], lock_stats); 137static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], lock_stats);
138 138
139static int lock_contention_point(struct lock_class *class, unsigned long ip) 139static 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
214static struct lock_class_stats *get_lock_stats(struct lock_class *class) 218static 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 */
2172void trace_hardirqs_on_caller(unsigned long a0) 2176void 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 */
2227void trace_hardirqs_off_caller(unsigned long a0) 2229void 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)
3025found_it: 3027found_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
3038static void 3044static 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
3090void lock_contended(struct lockdep_map *lock, unsigned long ip) 3097void 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}
3107EXPORT_SYMBOL_GPL(lock_contended); 3114EXPORT_SYMBOL_GPL(lock_contended);
3108 3115
3109void lock_acquired(struct lockdep_map *lock) 3116void 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 /*