aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
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
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')
-rw-r--r--kernel/lockdep.c33
-rw-r--r--kernel/lockdep_proc.c21
-rw-r--r--kernel/mutex.c2
3 files changed, 41 insertions, 15 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}
diff --git a/kernel/lockdep_proc.c b/kernel/lockdep_proc.c
index 8d3a6eba8d5a..13716b813896 100644
--- a/kernel/lockdep_proc.c
+++ b/kernel/lockdep_proc.c
@@ -557,7 +557,7 @@ static void seq_stats(struct seq_file *m, struct lock_stat_data *data)
557 if (stats->read_holdtime.nr) 557 if (stats->read_holdtime.nr)
558 namelen += 2; 558 namelen += 2;
559 559
560 for (i = 0; i < ARRAY_SIZE(class->contention_point); i++) { 560 for (i = 0; i < LOCKSTAT_POINTS; i++) {
561 char sym[KSYM_SYMBOL_LEN]; 561 char sym[KSYM_SYMBOL_LEN];
562 char ip[32]; 562 char ip[32];
563 563
@@ -574,6 +574,23 @@ static void seq_stats(struct seq_file *m, struct lock_stat_data *data)
574 stats->contention_point[i], 574 stats->contention_point[i],
575 ip, sym); 575 ip, sym);
576 } 576 }
577 for (i = 0; i < LOCKSTAT_POINTS; i++) {
578 char sym[KSYM_SYMBOL_LEN];
579 char ip[32];
580
581 if (class->contending_point[i] == 0)
582 break;
583
584 if (!i)
585 seq_line(m, '-', 40-namelen, namelen);
586
587 sprint_symbol(sym, class->contending_point[i]);
588 snprintf(ip, sizeof(ip), "[<%p>]",
589 (void *)class->contending_point[i]);
590 seq_printf(m, "%40s %14lu %29s %s\n", name,
591 stats->contending_point[i],
592 ip, sym);
593 }
577 if (i) { 594 if (i) {
578 seq_puts(m, "\n"); 595 seq_puts(m, "\n");
579 seq_line(m, '.', 0, 40 + 1 + 10 * (14 + 1)); 596 seq_line(m, '.', 0, 40 + 1 + 10 * (14 + 1));
@@ -583,7 +600,7 @@ static void seq_stats(struct seq_file *m, struct lock_stat_data *data)
583 600
584static void seq_header(struct seq_file *m) 601static void seq_header(struct seq_file *m)
585{ 602{
586 seq_printf(m, "lock_stat version 0.2\n"); 603 seq_printf(m, "lock_stat version 0.3\n");
587 seq_line(m, '-', 0, 40 + 1 + 10 * (14 + 1)); 604 seq_line(m, '-', 0, 40 + 1 + 10 * (14 + 1));
588 seq_printf(m, "%40s %14s %14s %14s %14s %14s %14s %14s %14s " 605 seq_printf(m, "%40s %14s %14s %14s %14s %14s %14s %14s %14s "
589 "%14s %14s\n", 606 "%14s %14s\n",
diff --git a/kernel/mutex.c b/kernel/mutex.c
index 12c779dc65d4..39a3816b68d9 100644
--- a/kernel/mutex.c
+++ b/kernel/mutex.c
@@ -184,7 +184,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass,
184 } 184 }
185 185
186done: 186done:
187 lock_acquired(&lock->dep_map); 187 lock_acquired(&lock->dep_map, ip);
188 /* got the lock - rejoice! */ 188 /* got the lock - rejoice! */
189 mutex_remove_waiter(lock, &waiter, task_thread_info(task)); 189 mutex_remove_waiter(lock, &waiter, task_thread_info(task));
190 debug_mutex_set_owner(lock, task_thread_info(task)); 190 debug_mutex_set_owner(lock, task_thread_info(task));