diff options
Diffstat (limited to 'kernel/lockdep.c')
-rw-r--r-- | kernel/lockdep.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 46a404173db2..c4c7df23f8c7 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c | |||
@@ -25,6 +25,7 @@ | |||
25 | * Thanks to Arjan van de Ven for coming up with the initial idea of | 25 | * Thanks to Arjan van de Ven for coming up with the initial idea of |
26 | * mapping lock dependencies runtime. | 26 | * mapping lock dependencies runtime. |
27 | */ | 27 | */ |
28 | #define DISABLE_BRANCH_PROFILING | ||
28 | #include <linux/mutex.h> | 29 | #include <linux/mutex.h> |
29 | #include <linux/sched.h> | 30 | #include <linux/sched.h> |
30 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
@@ -136,16 +137,16 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock) | |||
136 | #ifdef CONFIG_LOCK_STAT | 137 | #ifdef CONFIG_LOCK_STAT |
137 | static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], lock_stats); | 138 | static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], lock_stats); |
138 | 139 | ||
139 | static int lock_contention_point(struct lock_class *class, unsigned long ip) | 140 | static int lock_point(unsigned long points[], unsigned long ip) |
140 | { | 141 | { |
141 | int i; | 142 | int i; |
142 | 143 | ||
143 | for (i = 0; i < ARRAY_SIZE(class->contention_point); i++) { | 144 | for (i = 0; i < LOCKSTAT_POINTS; i++) { |
144 | if (class->contention_point[i] == 0) { | 145 | if (points[i] == 0) { |
145 | class->contention_point[i] = ip; | 146 | points[i] = ip; |
146 | break; | 147 | break; |
147 | } | 148 | } |
148 | if (class->contention_point[i] == ip) | 149 | if (points[i] == ip) |
149 | break; | 150 | break; |
150 | } | 151 | } |
151 | 152 | ||
@@ -185,6 +186,9 @@ struct lock_class_stats lock_stats(struct lock_class *class) | |||
185 | for (i = 0; i < ARRAY_SIZE(stats.contention_point); i++) | 186 | for (i = 0; i < ARRAY_SIZE(stats.contention_point); i++) |
186 | stats.contention_point[i] += pcs->contention_point[i]; | 187 | stats.contention_point[i] += pcs->contention_point[i]; |
187 | 188 | ||
189 | for (i = 0; i < ARRAY_SIZE(stats.contending_point); i++) | ||
190 | stats.contending_point[i] += pcs->contending_point[i]; | ||
191 | |||
188 | lock_time_add(&pcs->read_waittime, &stats.read_waittime); | 192 | lock_time_add(&pcs->read_waittime, &stats.read_waittime); |
189 | lock_time_add(&pcs->write_waittime, &stats.write_waittime); | 193 | lock_time_add(&pcs->write_waittime, &stats.write_waittime); |
190 | 194 | ||
@@ -209,6 +213,7 @@ void clear_lock_stats(struct lock_class *class) | |||
209 | memset(cpu_stats, 0, sizeof(struct lock_class_stats)); | 213 | memset(cpu_stats, 0, sizeof(struct lock_class_stats)); |
210 | } | 214 | } |
211 | memset(class->contention_point, 0, sizeof(class->contention_point)); | 215 | memset(class->contention_point, 0, sizeof(class->contention_point)); |
216 | memset(class->contending_point, 0, sizeof(class->contending_point)); | ||
212 | } | 217 | } |
213 | 218 | ||
214 | static struct lock_class_stats *get_lock_stats(struct lock_class *class) | 219 | static struct lock_class_stats *get_lock_stats(struct lock_class *class) |
@@ -2999,7 +3004,7 @@ __lock_contended(struct lockdep_map *lock, unsigned long ip) | |||
2999 | struct held_lock *hlock, *prev_hlock; | 3004 | struct held_lock *hlock, *prev_hlock; |
3000 | struct lock_class_stats *stats; | 3005 | struct lock_class_stats *stats; |
3001 | unsigned int depth; | 3006 | unsigned int depth; |
3002 | int i, point; | 3007 | int i, contention_point, contending_point; |
3003 | 3008 | ||
3004 | depth = curr->lockdep_depth; | 3009 | depth = curr->lockdep_depth; |
3005 | if (DEBUG_LOCKS_WARN_ON(!depth)) | 3010 | if (DEBUG_LOCKS_WARN_ON(!depth)) |
@@ -3023,18 +3028,22 @@ __lock_contended(struct lockdep_map *lock, unsigned long ip) | |||
3023 | found_it: | 3028 | found_it: |
3024 | hlock->waittime_stamp = sched_clock(); | 3029 | hlock->waittime_stamp = sched_clock(); |
3025 | 3030 | ||
3026 | point = lock_contention_point(hlock_class(hlock), ip); | 3031 | contention_point = lock_point(hlock_class(hlock)->contention_point, ip); |
3032 | contending_point = lock_point(hlock_class(hlock)->contending_point, | ||
3033 | lock->ip); | ||
3027 | 3034 | ||
3028 | stats = get_lock_stats(hlock_class(hlock)); | 3035 | stats = get_lock_stats(hlock_class(hlock)); |
3029 | if (point < ARRAY_SIZE(stats->contention_point)) | 3036 | if (contention_point < LOCKSTAT_POINTS) |
3030 | stats->contention_point[point]++; | 3037 | stats->contention_point[contention_point]++; |
3038 | if (contending_point < LOCKSTAT_POINTS) | ||
3039 | stats->contending_point[contending_point]++; | ||
3031 | if (lock->cpu != smp_processor_id()) | 3040 | if (lock->cpu != smp_processor_id()) |
3032 | stats->bounces[bounce_contended + !!hlock->read]++; | 3041 | stats->bounces[bounce_contended + !!hlock->read]++; |
3033 | put_lock_stats(stats); | 3042 | put_lock_stats(stats); |
3034 | } | 3043 | } |
3035 | 3044 | ||
3036 | static void | 3045 | static void |
3037 | __lock_acquired(struct lockdep_map *lock) | 3046 | __lock_acquired(struct lockdep_map *lock, unsigned long ip) |
3038 | { | 3047 | { |
3039 | struct task_struct *curr = current; | 3048 | struct task_struct *curr = current; |
3040 | struct held_lock *hlock, *prev_hlock; | 3049 | struct held_lock *hlock, *prev_hlock; |
@@ -3083,6 +3092,7 @@ found_it: | |||
3083 | put_lock_stats(stats); | 3092 | put_lock_stats(stats); |
3084 | 3093 | ||
3085 | lock->cpu = cpu; | 3094 | lock->cpu = cpu; |
3095 | lock->ip = ip; | ||
3086 | } | 3096 | } |
3087 | 3097 | ||
3088 | void lock_contended(struct lockdep_map *lock, unsigned long ip) | 3098 | void lock_contended(struct lockdep_map *lock, unsigned long ip) |
@@ -3104,7 +3114,7 @@ void lock_contended(struct lockdep_map *lock, unsigned long ip) | |||
3104 | } | 3114 | } |
3105 | EXPORT_SYMBOL_GPL(lock_contended); | 3115 | EXPORT_SYMBOL_GPL(lock_contended); |
3106 | 3116 | ||
3107 | void lock_acquired(struct lockdep_map *lock) | 3117 | void lock_acquired(struct lockdep_map *lock, unsigned long ip) |
3108 | { | 3118 | { |
3109 | unsigned long flags; | 3119 | unsigned long flags; |
3110 | 3120 | ||
@@ -3117,7 +3127,7 @@ void lock_acquired(struct lockdep_map *lock) | |||
3117 | raw_local_irq_save(flags); | 3127 | raw_local_irq_save(flags); |
3118 | check_flags(flags); | 3128 | check_flags(flags); |
3119 | current->lockdep_recursion = 1; | 3129 | current->lockdep_recursion = 1; |
3120 | __lock_acquired(lock); | 3130 | __lock_acquired(lock, ip); |
3121 | current->lockdep_recursion = 0; | 3131 | current->lockdep_recursion = 0; |
3122 | raw_local_irq_restore(flags); | 3132 | raw_local_irq_restore(flags); |
3123 | } | 3133 | } |