aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/lockdep.c
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2008-10-16 17:17:09 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-20 09:43:10 -0400
commitc7e78cff6b7518212247fb20b1dc6411540dc9af (patch)
tree4152afb3e00df125303c4c603e01addc19059ac7 /kernel/lockdep.c
parent7317d7b87edb41a9135e30be1ec3f7ef817c53dd (diff)
lockstat: contend with points
We currently only provide points that have to wait on contention, also lists the points we have to wait for. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/lockdep.c')
-rw-r--r--kernel/lockdep.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index dbda475b13bd..234a9dccb4be 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)
@@ -3001,7 +3005,7 @@ __lock_contended(struct lockdep_map *lock, unsigned long ip)
3001 struct held_lock *hlock, *prev_hlock; 3005 struct held_lock *hlock, *prev_hlock;
3002 struct lock_class_stats *stats; 3006 struct lock_class_stats *stats;
3003 unsigned int depth; 3007 unsigned int depth;
3004 int i, point; 3008 int i, contention_point, contending_point;
3005 3009
3006 depth = curr->lockdep_depth; 3010 depth = curr->lockdep_depth;
3007 if (DEBUG_LOCKS_WARN_ON(!depth)) 3011 if (DEBUG_LOCKS_WARN_ON(!depth))
@@ -3025,18 +3029,22 @@ __lock_contended(struct lockdep_map *lock, unsigned long ip)
3025found_it: 3029found_it:
3026 hlock->waittime_stamp = sched_clock(); 3030 hlock->waittime_stamp = sched_clock();
3027 3031
3028 point = lock_contention_point(hlock_class(hlock), ip); 3032 contention_point = lock_point(hlock_class(hlock)->contention_point, ip);
3033 contending_point = lock_point(hlock_class(hlock)->contending_point,
3034 lock->ip);
3029 3035
3030 stats = get_lock_stats(hlock_class(hlock)); 3036 stats = get_lock_stats(hlock_class(hlock));
3031 if (point < ARRAY_SIZE(stats->contention_point)) 3037 if (contention_point < LOCKSTAT_POINTS)
3032 stats->contention_point[point]++; 3038 stats->contention_point[contention_point]++;
3039 if (contending_point < LOCKSTAT_POINTS)
3040 stats->contending_point[contending_point]++;
3033 if (lock->cpu != smp_processor_id()) 3041 if (lock->cpu != smp_processor_id())
3034 stats->bounces[bounce_contended + !!hlock->read]++; 3042 stats->bounces[bounce_contended + !!hlock->read]++;
3035 put_lock_stats(stats); 3043 put_lock_stats(stats);
3036} 3044}
3037 3045
3038static void 3046static void
3039__lock_acquired(struct lockdep_map *lock) 3047__lock_acquired(struct lockdep_map *lock, unsigned long ip)
3040{ 3048{
3041 struct task_struct *curr = current; 3049 struct task_struct *curr = current;
3042 struct held_lock *hlock, *prev_hlock; 3050 struct held_lock *hlock, *prev_hlock;
@@ -3085,6 +3093,7 @@ found_it:
3085 put_lock_stats(stats); 3093 put_lock_stats(stats);
3086 3094
3087 lock->cpu = cpu; 3095 lock->cpu = cpu;
3096 lock->ip = ip;
3088} 3097}
3089 3098
3090void lock_contended(struct lockdep_map *lock, unsigned long ip) 3099void lock_contended(struct lockdep_map *lock, unsigned long ip)
@@ -3106,7 +3115,7 @@ void lock_contended(struct lockdep_map *lock, unsigned long ip)
3106} 3115}
3107EXPORT_SYMBOL_GPL(lock_contended); 3116EXPORT_SYMBOL_GPL(lock_contended);
3108 3117
3109void lock_acquired(struct lockdep_map *lock) 3118void lock_acquired(struct lockdep_map *lock, unsigned long ip)
3110{ 3119{
3111 unsigned long flags; 3120 unsigned long flags;
3112 3121
@@ -3119,7 +3128,7 @@ void lock_acquired(struct lockdep_map *lock)
3119 raw_local_irq_save(flags); 3128 raw_local_irq_save(flags);
3120 check_flags(flags); 3129 check_flags(flags);
3121 current->lockdep_recursion = 1; 3130 current->lockdep_recursion = 1;
3122 __lock_acquired(lock); 3131 __lock_acquired(lock, ip);
3123 current->lockdep_recursion = 0; 3132 current->lockdep_recursion = 0;
3124 raw_local_irq_restore(flags); 3133 raw_local_irq_restore(flags);
3125} 3134}