aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/lockdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/lockdep.c')
-rw-r--r--kernel/lockdep.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 3815ac1d58b2..4f8df01dbe51 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -49,7 +49,7 @@
49#include "lockdep_internals.h" 49#include "lockdep_internals.h"
50 50
51#define CREATE_TRACE_POINTS 51#define CREATE_TRACE_POINTS
52#include <trace/events/lockdep.h> 52#include <trace/events/lock.h>
53 53
54#ifdef CONFIG_PROVE_LOCKING 54#ifdef CONFIG_PROVE_LOCKING
55int prove_locking = 1; 55int prove_locking = 1;
@@ -142,6 +142,11 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock)
142#ifdef CONFIG_LOCK_STAT 142#ifdef CONFIG_LOCK_STAT
143static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], lock_stats); 143static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], lock_stats);
144 144
145static inline u64 lockstat_clock(void)
146{
147 return cpu_clock(smp_processor_id());
148}
149
145static int lock_point(unsigned long points[], unsigned long ip) 150static int lock_point(unsigned long points[], unsigned long ip)
146{ 151{
147 int i; 152 int i;
@@ -158,12 +163,12 @@ static int lock_point(unsigned long points[], unsigned long ip)
158 return i; 163 return i;
159} 164}
160 165
161static void lock_time_inc(struct lock_time *lt, s64 time) 166static void lock_time_inc(struct lock_time *lt, u64 time)
162{ 167{
163 if (time > lt->max) 168 if (time > lt->max)
164 lt->max = time; 169 lt->max = time;
165 170
166 if (time < lt->min || !lt->min) 171 if (time < lt->min || !lt->nr)
167 lt->min = time; 172 lt->min = time;
168 173
169 lt->total += time; 174 lt->total += time;
@@ -172,8 +177,15 @@ static void lock_time_inc(struct lock_time *lt, s64 time)
172 177
173static inline void lock_time_add(struct lock_time *src, struct lock_time *dst) 178static inline void lock_time_add(struct lock_time *src, struct lock_time *dst)
174{ 179{
175 dst->min += src->min; 180 if (!src->nr)
176 dst->max += src->max; 181 return;
182
183 if (src->max > dst->max)
184 dst->max = src->max;
185
186 if (src->min < dst->min || !dst->nr)
187 dst->min = src->min;
188
177 dst->total += src->total; 189 dst->total += src->total;
178 dst->nr += src->nr; 190 dst->nr += src->nr;
179} 191}
@@ -234,12 +246,12 @@ static void put_lock_stats(struct lock_class_stats *stats)
234static void lock_release_holdtime(struct held_lock *hlock) 246static void lock_release_holdtime(struct held_lock *hlock)
235{ 247{
236 struct lock_class_stats *stats; 248 struct lock_class_stats *stats;
237 s64 holdtime; 249 u64 holdtime;
238 250
239 if (!lock_stat) 251 if (!lock_stat)
240 return; 252 return;
241 253
242 holdtime = sched_clock() - hlock->holdtime_stamp; 254 holdtime = lockstat_clock() - hlock->holdtime_stamp;
243 255
244 stats = get_lock_stats(hlock_class(hlock)); 256 stats = get_lock_stats(hlock_class(hlock));
245 if (hlock->read) 257 if (hlock->read)
@@ -374,7 +386,8 @@ static int save_trace(struct stack_trace *trace)
374 * complete trace that maxes out the entries provided will be reported 386 * complete trace that maxes out the entries provided will be reported
375 * as incomplete, friggin useless </rant> 387 * as incomplete, friggin useless </rant>
376 */ 388 */
377 if (trace->entries[trace->nr_entries-1] == ULONG_MAX) 389 if (trace->nr_entries != 0 &&
390 trace->entries[trace->nr_entries-1] == ULONG_MAX)
378 trace->nr_entries--; 391 trace->nr_entries--;
379 392
380 trace->max_entries = trace->nr_entries; 393 trace->max_entries = trace->nr_entries;
@@ -2792,7 +2805,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
2792 hlock->references = references; 2805 hlock->references = references;
2793#ifdef CONFIG_LOCK_STAT 2806#ifdef CONFIG_LOCK_STAT
2794 hlock->waittime_stamp = 0; 2807 hlock->waittime_stamp = 0;
2795 hlock->holdtime_stamp = sched_clock(); 2808 hlock->holdtime_stamp = lockstat_clock();
2796#endif 2809#endif
2797 2810
2798 if (check == 2 && !mark_irqflags(curr, hlock)) 2811 if (check == 2 && !mark_irqflags(curr, hlock))
@@ -3322,7 +3335,7 @@ found_it:
3322 if (hlock->instance != lock) 3335 if (hlock->instance != lock)
3323 return; 3336 return;
3324 3337
3325 hlock->waittime_stamp = sched_clock(); 3338 hlock->waittime_stamp = lockstat_clock();
3326 3339
3327 contention_point = lock_point(hlock_class(hlock)->contention_point, ip); 3340 contention_point = lock_point(hlock_class(hlock)->contention_point, ip);
3328 contending_point = lock_point(hlock_class(hlock)->contending_point, 3341 contending_point = lock_point(hlock_class(hlock)->contending_point,
@@ -3345,8 +3358,7 @@ __lock_acquired(struct lockdep_map *lock, unsigned long ip)
3345 struct held_lock *hlock, *prev_hlock; 3358 struct held_lock *hlock, *prev_hlock;
3346 struct lock_class_stats *stats; 3359 struct lock_class_stats *stats;
3347 unsigned int depth; 3360 unsigned int depth;
3348 u64 now; 3361 u64 now, waittime = 0;
3349 s64 waittime = 0;
3350 int i, cpu; 3362 int i, cpu;
3351 3363
3352 depth = curr->lockdep_depth; 3364 depth = curr->lockdep_depth;
@@ -3374,7 +3386,7 @@ found_it:
3374 3386
3375 cpu = smp_processor_id(); 3387 cpu = smp_processor_id();
3376 if (hlock->waittime_stamp) { 3388 if (hlock->waittime_stamp) {
3377 now = sched_clock(); 3389 now = lockstat_clock();
3378 waittime = now - hlock->waittime_stamp; 3390 waittime = now - hlock->waittime_stamp;
3379 hlock->holdtime_stamp = now; 3391 hlock->holdtime_stamp = now;
3380 } 3392 }