diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2008-08-20 20:02:21 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-08-21 07:52:59 -0400 |
commit | f8eca41f0afcc7042dc3398c8ba5878c59b1cf1b (patch) | |
tree | 5190084f3edc7b9adaea498d41d634d9e908df35 /arch/x86/xen | |
parent | 1e696f638b523958ee3d95e655becdb4c4b6fcde (diff) |
xen: measure how long spinlocks spend blocking
Measure how long spinlocks spend blocked. Also rename some fields to
be more consistent.
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Acked-by: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/xen')
-rw-r--r-- | arch/x86/xen/spinlock.c | 62 |
1 files changed, 42 insertions, 20 deletions
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index e6061f2e64f2..d072823bc06d 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c | |||
@@ -29,12 +29,14 @@ static struct xen_spinlock_stats | |||
29 | u32 released_slow; | 29 | u32 released_slow; |
30 | u32 released_slow_kicked; | 30 | u32 released_slow_kicked; |
31 | 31 | ||
32 | #define HISTO_BUCKETS 20 | 32 | #define HISTO_BUCKETS 30 |
33 | u32 histo_spin_fast[HISTO_BUCKETS+1]; | 33 | u32 histo_spin_total[HISTO_BUCKETS+1]; |
34 | u32 histo_spin[HISTO_BUCKETS+1]; | 34 | u32 histo_spin_spinning[HISTO_BUCKETS+1]; |
35 | 35 | u32 histo_spin_blocked[HISTO_BUCKETS+1]; | |
36 | u64 spinning_time; | 36 | |
37 | u64 total_time; | 37 | u64 time_total; |
38 | u64 time_spinning; | ||
39 | u64 time_blocked; | ||
38 | } spinlock_stats; | 40 | } spinlock_stats; |
39 | 41 | ||
40 | static u8 zero_stats; | 42 | static u8 zero_stats; |
@@ -70,20 +72,28 @@ static void __spin_time_accum(u64 delta, u32 *array) | |||
70 | array[HISTO_BUCKETS]++; | 72 | array[HISTO_BUCKETS]++; |
71 | } | 73 | } |
72 | 74 | ||
73 | static inline void spin_time_accum_fast(u64 start) | 75 | static inline void spin_time_accum_spinning(u64 start) |
76 | { | ||
77 | u32 delta = xen_clocksource_read() - start; | ||
78 | |||
79 | __spin_time_accum(delta, spinlock_stats.histo_spin_spinning); | ||
80 | spinlock_stats.time_spinning += delta; | ||
81 | } | ||
82 | |||
83 | static inline void spin_time_accum_total(u64 start) | ||
74 | { | 84 | { |
75 | u32 delta = xen_clocksource_read() - start; | 85 | u32 delta = xen_clocksource_read() - start; |
76 | 86 | ||
77 | __spin_time_accum(delta, spinlock_stats.histo_spin_fast); | 87 | __spin_time_accum(delta, spinlock_stats.histo_spin_total); |
78 | spinlock_stats.spinning_time += delta; | 88 | spinlock_stats.time_total += delta; |
79 | } | 89 | } |
80 | 90 | ||
81 | static inline void spin_time_accum(u64 start) | 91 | static inline void spin_time_accum_blocked(u64 start) |
82 | { | 92 | { |
83 | u32 delta = xen_clocksource_read() - start; | 93 | u32 delta = xen_clocksource_read() - start; |
84 | 94 | ||
85 | __spin_time_accum(delta, spinlock_stats.histo_spin); | 95 | __spin_time_accum(delta, spinlock_stats.histo_spin_blocked); |
86 | spinlock_stats.total_time += delta; | 96 | spinlock_stats.time_blocked += delta; |
87 | } | 97 | } |
88 | #else /* !CONFIG_XEN_DEBUG_FS */ | 98 | #else /* !CONFIG_XEN_DEBUG_FS */ |
89 | #define TIMEOUT (1 << 10) | 99 | #define TIMEOUT (1 << 10) |
@@ -94,10 +104,13 @@ static inline u64 spin_time_start(void) | |||
94 | return 0; | 104 | return 0; |
95 | } | 105 | } |
96 | 106 | ||
97 | static inline void spin_time_accum_fast(u64 start) | 107 | static inline void spin_time_accum_total(u64 start) |
108 | { | ||
109 | } | ||
110 | static inline void spin_time_accum_spinning(u64 start) | ||
98 | { | 111 | { |
99 | } | 112 | } |
100 | static inline void spin_time_accum(u64 start) | 113 | static inline void spin_time_accum_blocked(u64 start) |
101 | { | 114 | { |
102 | } | 115 | } |
103 | #endif /* CONFIG_XEN_DEBUG_FS */ | 116 | #endif /* CONFIG_XEN_DEBUG_FS */ |
@@ -175,11 +188,14 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl | |||
175 | int irq = __get_cpu_var(lock_kicker_irq); | 188 | int irq = __get_cpu_var(lock_kicker_irq); |
176 | int ret; | 189 | int ret; |
177 | unsigned long flags; | 190 | unsigned long flags; |
191 | u64 start; | ||
178 | 192 | ||
179 | /* If kicker interrupts not initialized yet, just spin */ | 193 | /* If kicker interrupts not initialized yet, just spin */ |
180 | if (irq == -1) | 194 | if (irq == -1) |
181 | return 0; | 195 | return 0; |
182 | 196 | ||
197 | start = spin_time_start(); | ||
198 | |||
183 | /* announce we're spinning */ | 199 | /* announce we're spinning */ |
184 | prev = spinning_lock(xl); | 200 | prev = spinning_lock(xl); |
185 | 201 | ||
@@ -230,6 +246,8 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl | |||
230 | out: | 246 | out: |
231 | raw_local_irq_restore(flags); | 247 | raw_local_irq_restore(flags); |
232 | unspinning_lock(xl, prev); | 248 | unspinning_lock(xl, prev); |
249 | spin_time_accum_blocked(start); | ||
250 | |||
233 | return ret; | 251 | return ret; |
234 | } | 252 | } |
235 | 253 | ||
@@ -262,12 +280,12 @@ static inline void __xen_spin_lock(struct raw_spinlock *lock, bool irq_enable) | |||
262 | : "1" (1) | 280 | : "1" (1) |
263 | : "memory"); | 281 | : "memory"); |
264 | 282 | ||
265 | spin_time_accum_fast(start_spin_fast); | 283 | spin_time_accum_spinning(start_spin_fast); |
266 | 284 | ||
267 | } while (unlikely(oldval != 0 && | 285 | } while (unlikely(oldval != 0 && |
268 | (TIMEOUT == ~0 || !xen_spin_lock_slow(lock, irq_enable)))); | 286 | (TIMEOUT == ~0 || !xen_spin_lock_slow(lock, irq_enable)))); |
269 | 287 | ||
270 | spin_time_accum(start_spin); | 288 | spin_time_accum_total(start_spin); |
271 | } | 289 | } |
272 | 290 | ||
273 | static void xen_spin_lock(struct raw_spinlock *lock) | 291 | static void xen_spin_lock(struct raw_spinlock *lock) |
@@ -385,14 +403,18 @@ static int __init xen_spinlock_debugfs(void) | |||
385 | &spinlock_stats.released_slow_kicked); | 403 | &spinlock_stats.released_slow_kicked); |
386 | 404 | ||
387 | debugfs_create_u64("time_spinning", 0444, d_spin_debug, | 405 | debugfs_create_u64("time_spinning", 0444, d_spin_debug, |
388 | &spinlock_stats.spinning_time); | 406 | &spinlock_stats.time_spinning); |
407 | debugfs_create_u64("time_blocked", 0444, d_spin_debug, | ||
408 | &spinlock_stats.time_blocked); | ||
389 | debugfs_create_u64("time_total", 0444, d_spin_debug, | 409 | debugfs_create_u64("time_total", 0444, d_spin_debug, |
390 | &spinlock_stats.total_time); | 410 | &spinlock_stats.time_total); |
391 | 411 | ||
392 | xen_debugfs_create_u32_array("histo_total", 0444, d_spin_debug, | 412 | xen_debugfs_create_u32_array("histo_total", 0444, d_spin_debug, |
393 | spinlock_stats.histo_spin, HISTO_BUCKETS + 1); | 413 | spinlock_stats.histo_spin_total, HISTO_BUCKETS + 1); |
394 | xen_debugfs_create_u32_array("histo_spinning", 0444, d_spin_debug, | 414 | xen_debugfs_create_u32_array("histo_spinning", 0444, d_spin_debug, |
395 | spinlock_stats.histo_spin_fast, HISTO_BUCKETS + 1); | 415 | spinlock_stats.histo_spin_spinning, HISTO_BUCKETS + 1); |
416 | xen_debugfs_create_u32_array("histo_blocked", 0444, d_spin_debug, | ||
417 | spinlock_stats.histo_spin_blocked, HISTO_BUCKETS + 1); | ||
396 | 418 | ||
397 | return 0; | 419 | return 0; |
398 | } | 420 | } |