diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2007-07-19 04:48:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-19 13:04:49 -0400 |
commit | c46261de0d98372112d8edf16f74ce418a268d46 (patch) | |
tree | b502a5872f3d4bd11254755defac0720ef072faf /kernel/lockdep.c | |
parent | f20786ff4da51e56b1956acf30be2552be266746 (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.c | 44 |
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 | ||
152 | static 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 | |||
160 | struct 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 | |||
183 | void 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 | |||
152 | static struct lock_class_stats *get_lock_stats(struct lock_class *class) | 196 | static 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]; |