aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/lockdep.c
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2007-07-19 04:48:57 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-19 13:04:49 -0400
commitc46261de0d98372112d8edf16f74ce418a268d46 (patch)
treeb502a5872f3d4bd11254755defac0720ef072faf /kernel/lockdep.c
parentf20786ff4da51e56b1956acf30be2552be266746 (diff)
lockstat: human readability tweaks
Present all this fancy new lock statistics information: *warning, _wide_ output ahead* (output edited for purpose of brevity) # cat /proc/lock_stat lock_stat version 0.1 ----------------------------------------------------------------------------------------------------------------------------------------------------------------- class name contentions waittime-min waittime-max waittime-total acquisitions holdtime-min holdtime-max holdtime-total ----------------------------------------------------------------------------------------------------------------------------------------------------------------- &inode->i_mutex: 14458 6.57 398832.75 2469412.23 6768876 0.34 11398383.65 339410830.89 --------------- &inode->i_mutex 4486 [<ffffffff802a08f9>] pipe_wait+0x86/0x8d &inode->i_mutex 0 [<ffffffff802a01e8>] pipe_write_fasync+0x29/0x5d &inode->i_mutex 0 [<ffffffff802a0e18>] pipe_read+0x74/0x3a5 &inode->i_mutex 0 [<ffffffff802a1a6a>] do_lookup+0x81/0x1ae ................................................................................................................................................................. &inode->i_data.tree_lock-W: 491 0.27 62.47 493.89 2477833 0.39 468.89 1146584.25 &inode->i_data.tree_lock-R: 65 0.44 4.27 48.78 26288792 0.36 184.62 10197458.24 -------------------------- &inode->i_data.tree_lock 46 [<ffffffff80277095>] __do_page_cache_readahead+0x69/0x24f &inode->i_data.tree_lock 31 [<ffffffff8026f9fb>] add_to_page_cache+0x31/0xba &inode->i_data.tree_lock 0 [<ffffffff802770ee>] __do_page_cache_readahead+0xc2/0x24f &inode->i_data.tree_lock 0 [<ffffffff8026f6e4>] find_get_page+0x1a/0x58 ................................................................................................................................................................. proc_inum_idr.lock: 0 0.00 0.00 0.00 36 0.00 65.60 148.26 proc_subdir_lock: 0 0.00 0.00 0.00 3049859 0.00 106.81 1563212.42 shrinker_rwsem-W: 0 0.00 0.00 0.00 5 0.00 1.73 3.68 shrinker_rwsem-R: 0 0.00 0.00 0.00 633 2.57 246.57 10909.76 'contentions' and 'acquisitions' are the number of such events measured (since the last reset). The waittime- and holdtime- (min, max, total) numbers are presented in microseconds. If there are any contention points, the lock class is presented in the block format (as i_mutex and tree_lock above), otherwise a single line of output is presented. The output is sorted on absolute number of contentions (read + write), this should get the worst offenders presented first, so that: # grep : /proc/lock_stat | head will quickly show who's bad. The stats can be reset using: # echo 0 > /proc/lock_stat [bunk@stusta.de: make 2 functions static] [akpm@linux-foundation.org: fix printk warning] Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Acked-by: Ingo Molnar <mingo@elte.hu> Acked-by: Jason Baron <jbaron@redhat.com> Signed-off-by: Adrian Bunk <bunk@stusta.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/lockdep.c')
-rw-r--r--kernel/lockdep.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 70ca4db28aff..a8dc99d9fef7 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -149,6 +149,50 @@ static void lock_time_inc(struct lock_time *lt, s64 time)
149 lt->nr++; 149 lt->nr++;
150} 150}
151 151
152static inline void lock_time_add(struct lock_time *src, struct lock_time *dst)
153{
154 dst->min += src->min;
155 dst->max += src->max;
156 dst->total += src->total;
157 dst->nr += src->nr;
158}
159
160struct lock_class_stats lock_stats(struct lock_class *class)
161{
162 struct lock_class_stats stats;
163 int cpu, i;
164
165 memset(&stats, 0, sizeof(struct lock_class_stats));
166 for_each_possible_cpu(cpu) {
167 struct lock_class_stats *pcs =
168 &per_cpu(lock_stats, cpu)[class - lock_classes];
169
170 for (i = 0; i < ARRAY_SIZE(stats.contention_point); i++)
171 stats.contention_point[i] += pcs->contention_point[i];
172
173 lock_time_add(&pcs->read_waittime, &stats.read_waittime);
174 lock_time_add(&pcs->write_waittime, &stats.write_waittime);
175
176 lock_time_add(&pcs->read_holdtime, &stats.read_holdtime);
177 lock_time_add(&pcs->write_holdtime, &stats.write_holdtime);
178 }
179
180 return stats;
181}
182
183void clear_lock_stats(struct lock_class *class)
184{
185 int cpu;
186
187 for_each_possible_cpu(cpu) {
188 struct lock_class_stats *cpu_stats =
189 &per_cpu(lock_stats, cpu)[class - lock_classes];
190
191 memset(cpu_stats, 0, sizeof(struct lock_class_stats));
192 }
193 memset(class->contention_point, 0, sizeof(class->contention_point));
194}
195
152static struct lock_class_stats *get_lock_stats(struct lock_class *class) 196static struct lock_class_stats *get_lock_stats(struct lock_class *class)
153{ 197{
154 return &get_cpu_var(lock_stats)[class - lock_classes]; 198 return &get_cpu_var(lock_stats)[class - lock_classes];