aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/lockdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/lockdep.c')
-rw-r--r--kernel/lockdep.c60
1 files changed, 32 insertions, 28 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 46a404173db2..4fa6eeb4e8a7 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)
@@ -287,14 +291,12 @@ void lockdep_off(void)
287{ 291{
288 current->lockdep_recursion++; 292 current->lockdep_recursion++;
289} 293}
290
291EXPORT_SYMBOL(lockdep_off); 294EXPORT_SYMBOL(lockdep_off);
292 295
293void lockdep_on(void) 296void lockdep_on(void)
294{ 297{
295 current->lockdep_recursion--; 298 current->lockdep_recursion--;
296} 299}
297
298EXPORT_SYMBOL(lockdep_on); 300EXPORT_SYMBOL(lockdep_on);
299 301
300/* 302/*
@@ -576,7 +578,8 @@ static void print_lock_class_header(struct lock_class *class, int depth)
576/* 578/*
577 * printk all lock dependencies starting at <entry>: 579 * printk all lock dependencies starting at <entry>:
578 */ 580 */
579static void print_lock_dependencies(struct lock_class *class, int depth) 581static void __used
582print_lock_dependencies(struct lock_class *class, int depth)
580{ 583{
581 struct lock_list *entry; 584 struct lock_list *entry;
582 585
@@ -2508,7 +2511,6 @@ void lockdep_init_map(struct lockdep_map *lock, const char *name,
2508 if (subclass) 2511 if (subclass)
2509 register_lock_class(lock, subclass, 1); 2512 register_lock_class(lock, subclass, 1);
2510} 2513}
2511
2512EXPORT_SYMBOL_GPL(lockdep_init_map); 2514EXPORT_SYMBOL_GPL(lockdep_init_map);
2513 2515
2514/* 2516/*
@@ -2689,8 +2691,9 @@ static int check_unlock(struct task_struct *curr, struct lockdep_map *lock,
2689} 2691}
2690 2692
2691static int 2693static int
2692__lock_set_subclass(struct lockdep_map *lock, 2694__lock_set_class(struct lockdep_map *lock, const char *name,
2693 unsigned int subclass, unsigned long ip) 2695 struct lock_class_key *key, unsigned int subclass,
2696 unsigned long ip)
2694{ 2697{
2695 struct task_struct *curr = current; 2698 struct task_struct *curr = current;
2696 struct held_lock *hlock, *prev_hlock; 2699 struct held_lock *hlock, *prev_hlock;
@@ -2717,6 +2720,7 @@ __lock_set_subclass(struct lockdep_map *lock,
2717 return print_unlock_inbalance_bug(curr, lock, ip); 2720 return print_unlock_inbalance_bug(curr, lock, ip);
2718 2721
2719found_it: 2722found_it:
2723 lockdep_init_map(lock, name, key, 0);
2720 class = register_lock_class(lock, subclass, 0); 2724 class = register_lock_class(lock, subclass, 0);
2721 hlock->class_idx = class - lock_classes + 1; 2725 hlock->class_idx = class - lock_classes + 1;
2722 2726
@@ -2901,9 +2905,9 @@ static void check_flags(unsigned long flags)
2901#endif 2905#endif
2902} 2906}
2903 2907
2904void 2908void lock_set_class(struct lockdep_map *lock, const char *name,
2905lock_set_subclass(struct lockdep_map *lock, 2909 struct lock_class_key *key, unsigned int subclass,
2906 unsigned int subclass, unsigned long ip) 2910 unsigned long ip)
2907{ 2911{
2908 unsigned long flags; 2912 unsigned long flags;
2909 2913
@@ -2913,13 +2917,12 @@ lock_set_subclass(struct lockdep_map *lock,
2913 raw_local_irq_save(flags); 2917 raw_local_irq_save(flags);
2914 current->lockdep_recursion = 1; 2918 current->lockdep_recursion = 1;
2915 check_flags(flags); 2919 check_flags(flags);
2916 if (__lock_set_subclass(lock, subclass, ip)) 2920 if (__lock_set_class(lock, name, key, subclass, ip))
2917 check_chain_key(current); 2921 check_chain_key(current);
2918 current->lockdep_recursion = 0; 2922 current->lockdep_recursion = 0;
2919 raw_local_irq_restore(flags); 2923 raw_local_irq_restore(flags);
2920} 2924}
2921 2925EXPORT_SYMBOL_GPL(lock_set_class);
2922EXPORT_SYMBOL_GPL(lock_set_subclass);
2923 2926
2924/* 2927/*
2925 * We are not always called with irqs disabled - do that here, 2928 * We are not always called with irqs disabled - do that here,
@@ -2943,7 +2946,6 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
2943 current->lockdep_recursion = 0; 2946 current->lockdep_recursion = 0;
2944 raw_local_irq_restore(flags); 2947 raw_local_irq_restore(flags);
2945} 2948}
2946
2947EXPORT_SYMBOL_GPL(lock_acquire); 2949EXPORT_SYMBOL_GPL(lock_acquire);
2948 2950
2949void lock_release(struct lockdep_map *lock, int nested, 2951void lock_release(struct lockdep_map *lock, int nested,
@@ -2961,7 +2963,6 @@ void lock_release(struct lockdep_map *lock, int nested,
2961 current->lockdep_recursion = 0; 2963 current->lockdep_recursion = 0;
2962 raw_local_irq_restore(flags); 2964 raw_local_irq_restore(flags);
2963} 2965}
2964
2965EXPORT_SYMBOL_GPL(lock_release); 2966EXPORT_SYMBOL_GPL(lock_release);
2966 2967
2967#ifdef CONFIG_LOCK_STAT 2968#ifdef CONFIG_LOCK_STAT
@@ -2999,7 +3000,7 @@ __lock_contended(struct lockdep_map *lock, unsigned long ip)
2999 struct held_lock *hlock, *prev_hlock; 3000 struct held_lock *hlock, *prev_hlock;
3000 struct lock_class_stats *stats; 3001 struct lock_class_stats *stats;
3001 unsigned int depth; 3002 unsigned int depth;
3002 int i, point; 3003 int i, contention_point, contending_point;
3003 3004
3004 depth = curr->lockdep_depth; 3005 depth = curr->lockdep_depth;
3005 if (DEBUG_LOCKS_WARN_ON(!depth)) 3006 if (DEBUG_LOCKS_WARN_ON(!depth))
@@ -3023,18 +3024,22 @@ __lock_contended(struct lockdep_map *lock, unsigned long ip)
3023found_it: 3024found_it:
3024 hlock->waittime_stamp = sched_clock(); 3025 hlock->waittime_stamp = sched_clock();
3025 3026
3026 point = lock_contention_point(hlock_class(hlock), ip); 3027 contention_point = lock_point(hlock_class(hlock)->contention_point, ip);
3028 contending_point = lock_point(hlock_class(hlock)->contending_point,
3029 lock->ip);
3027 3030
3028 stats = get_lock_stats(hlock_class(hlock)); 3031 stats = get_lock_stats(hlock_class(hlock));
3029 if (point < ARRAY_SIZE(stats->contention_point)) 3032 if (contention_point < LOCKSTAT_POINTS)
3030 stats->contention_point[point]++; 3033 stats->contention_point[contention_point]++;
3034 if (contending_point < LOCKSTAT_POINTS)
3035 stats->contending_point[contending_point]++;
3031 if (lock->cpu != smp_processor_id()) 3036 if (lock->cpu != smp_processor_id())
3032 stats->bounces[bounce_contended + !!hlock->read]++; 3037 stats->bounces[bounce_contended + !!hlock->read]++;
3033 put_lock_stats(stats); 3038 put_lock_stats(stats);
3034} 3039}
3035 3040
3036static void 3041static void
3037__lock_acquired(struct lockdep_map *lock) 3042__lock_acquired(struct lockdep_map *lock, unsigned long ip)
3038{ 3043{
3039 struct task_struct *curr = current; 3044 struct task_struct *curr = current;
3040 struct held_lock *hlock, *prev_hlock; 3045 struct held_lock *hlock, *prev_hlock;
@@ -3083,6 +3088,7 @@ found_it:
3083 put_lock_stats(stats); 3088 put_lock_stats(stats);
3084 3089
3085 lock->cpu = cpu; 3090 lock->cpu = cpu;
3091 lock->ip = ip;
3086} 3092}
3087 3093
3088void lock_contended(struct lockdep_map *lock, unsigned long ip) 3094void lock_contended(struct lockdep_map *lock, unsigned long ip)
@@ -3104,7 +3110,7 @@ void lock_contended(struct lockdep_map *lock, unsigned long ip)
3104} 3110}
3105EXPORT_SYMBOL_GPL(lock_contended); 3111EXPORT_SYMBOL_GPL(lock_contended);
3106 3112
3107void lock_acquired(struct lockdep_map *lock) 3113void lock_acquired(struct lockdep_map *lock, unsigned long ip)
3108{ 3114{
3109 unsigned long flags; 3115 unsigned long flags;
3110 3116
@@ -3117,7 +3123,7 @@ void lock_acquired(struct lockdep_map *lock)
3117 raw_local_irq_save(flags); 3123 raw_local_irq_save(flags);
3118 check_flags(flags); 3124 check_flags(flags);
3119 current->lockdep_recursion = 1; 3125 current->lockdep_recursion = 1;
3120 __lock_acquired(lock); 3126 __lock_acquired(lock, ip);
3121 current->lockdep_recursion = 0; 3127 current->lockdep_recursion = 0;
3122 raw_local_irq_restore(flags); 3128 raw_local_irq_restore(flags);
3123} 3129}
@@ -3441,7 +3447,6 @@ retry:
3441 if (unlock) 3447 if (unlock)
3442 read_unlock(&tasklist_lock); 3448 read_unlock(&tasklist_lock);
3443} 3449}
3444
3445EXPORT_SYMBOL_GPL(debug_show_all_locks); 3450EXPORT_SYMBOL_GPL(debug_show_all_locks);
3446 3451
3447/* 3452/*
@@ -3462,7 +3467,6 @@ void debug_show_held_locks(struct task_struct *task)
3462{ 3467{
3463 __debug_show_held_locks(task); 3468 __debug_show_held_locks(task);
3464} 3469}
3465
3466EXPORT_SYMBOL_GPL(debug_show_held_locks); 3470EXPORT_SYMBOL_GPL(debug_show_held_locks);
3467 3471
3468void lockdep_sys_exit(void) 3472void lockdep_sys_exit(void)