diff options
author | Sunil Mushran <sunil.mushran@oracle.com> | 2010-12-29 02:26:03 -0500 |
---|---|---|
committer | Joel Becker <jlbec@evilplan.org> | 2011-02-20 06:56:07 -0500 |
commit | 5bc970e803ad2b1f26771f39376a79dbf0f5bf64 (patch) | |
tree | cc2c0dd4a49ddad9691d0ef0312475db76bc6464 /fs/ocfs2/dlmglue.c | |
parent | 0cc9d5257857608ba85885b75fcada13d359b5d1 (diff) |
ocfs2: Use hrtimer to track ocfs2 fs lock stats
Patch makes use of the hrtimer to track times in ocfs2 lock stats.
The patch is a bit involved to ensure no additional impact on the memory
footprint. The size of ocfs2_inode_cache remains 1280 bytes on 32-bit systems.
A related change was to modify the unit of the max wait time from nanosec to
microsec allowing us to track max time larger than 4 secs. This change
necessitated the bumping of the output version in the debugfs file,
locking_state, from 2 to 3.
Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
Signed-off-by: Joel Becker <jlbec@evilplan.org>
Diffstat (limited to 'fs/ocfs2/dlmglue.c')
-rw-r--r-- | fs/ocfs2/dlmglue.c | 97 |
1 files changed, 50 insertions, 47 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index e8d94d722ecb..7484bb9a3438 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
@@ -64,7 +64,7 @@ struct ocfs2_mask_waiter { | |||
64 | unsigned long mw_mask; | 64 | unsigned long mw_mask; |
65 | unsigned long mw_goal; | 65 | unsigned long mw_goal; |
66 | #ifdef CONFIG_OCFS2_FS_STATS | 66 | #ifdef CONFIG_OCFS2_FS_STATS |
67 | unsigned long long mw_lock_start; | 67 | ktime_t mw_lock_start; |
68 | #endif | 68 | #endif |
69 | }; | 69 | }; |
70 | 70 | ||
@@ -435,44 +435,41 @@ static void ocfs2_remove_lockres_tracking(struct ocfs2_lock_res *res) | |||
435 | #ifdef CONFIG_OCFS2_FS_STATS | 435 | #ifdef CONFIG_OCFS2_FS_STATS |
436 | static void ocfs2_init_lock_stats(struct ocfs2_lock_res *res) | 436 | static void ocfs2_init_lock_stats(struct ocfs2_lock_res *res) |
437 | { | 437 | { |
438 | res->l_lock_num_prmode = 0; | ||
439 | res->l_lock_num_prmode_failed = 0; | ||
440 | res->l_lock_total_prmode = 0; | ||
441 | res->l_lock_max_prmode = 0; | ||
442 | res->l_lock_num_exmode = 0; | ||
443 | res->l_lock_num_exmode_failed = 0; | ||
444 | res->l_lock_total_exmode = 0; | ||
445 | res->l_lock_max_exmode = 0; | ||
446 | res->l_lock_refresh = 0; | 438 | res->l_lock_refresh = 0; |
439 | memset(&res->l_lock_prmode, 0, sizeof(struct ocfs2_lock_stats)); | ||
440 | memset(&res->l_lock_exmode, 0, sizeof(struct ocfs2_lock_stats)); | ||
447 | } | 441 | } |
448 | 442 | ||
449 | static void ocfs2_update_lock_stats(struct ocfs2_lock_res *res, int level, | 443 | static void ocfs2_update_lock_stats(struct ocfs2_lock_res *res, int level, |
450 | struct ocfs2_mask_waiter *mw, int ret) | 444 | struct ocfs2_mask_waiter *mw, int ret) |
451 | { | 445 | { |
452 | unsigned long long *num, *sum; | 446 | u32 usec; |
453 | unsigned int *max, *failed; | 447 | ktime_t kt; |
454 | struct timespec ts = current_kernel_time(); | 448 | struct ocfs2_lock_stats *stats; |
455 | unsigned long long time = timespec_to_ns(&ts) - mw->mw_lock_start; | 449 | |
456 | 450 | if (level == LKM_PRMODE) | |
457 | if (level == LKM_PRMODE) { | 451 | stats = &res->l_lock_prmode; |
458 | num = &res->l_lock_num_prmode; | 452 | else if (level == LKM_EXMODE) |
459 | sum = &res->l_lock_total_prmode; | 453 | stats = &res->l_lock_exmode; |
460 | max = &res->l_lock_max_prmode; | 454 | else |
461 | failed = &res->l_lock_num_prmode_failed; | ||
462 | } else if (level == LKM_EXMODE) { | ||
463 | num = &res->l_lock_num_exmode; | ||
464 | sum = &res->l_lock_total_exmode; | ||
465 | max = &res->l_lock_max_exmode; | ||
466 | failed = &res->l_lock_num_exmode_failed; | ||
467 | } else | ||
468 | return; | 455 | return; |
469 | 456 | ||
470 | (*num)++; | 457 | kt = ktime_sub(ktime_get(), mw->mw_lock_start); |
471 | (*sum) += time; | 458 | usec = ktime_to_us(kt); |
472 | if (time > *max) | 459 | |
473 | *max = time; | 460 | stats->ls_gets++; |
461 | stats->ls_total += ktime_to_ns(kt); | ||
462 | /* overflow */ | ||
463 | if (unlikely(stats->ls_gets) == 0) { | ||
464 | stats->ls_gets++; | ||
465 | stats->ls_total = ktime_to_ns(kt); | ||
466 | } | ||
467 | |||
468 | if (stats->ls_max < usec) | ||
469 | stats->ls_max = usec; | ||
470 | |||
474 | if (ret) | 471 | if (ret) |
475 | (*failed)++; | 472 | stats->ls_fail++; |
476 | } | 473 | } |
477 | 474 | ||
478 | static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres) | 475 | static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres) |
@@ -482,8 +479,7 @@ static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres) | |||
482 | 479 | ||
483 | static inline void ocfs2_init_start_time(struct ocfs2_mask_waiter *mw) | 480 | static inline void ocfs2_init_start_time(struct ocfs2_mask_waiter *mw) |
484 | { | 481 | { |
485 | struct timespec ts = current_kernel_time(); | 482 | mw->mw_lock_start = ktime_get(); |
486 | mw->mw_lock_start = timespec_to_ns(&ts); | ||
487 | } | 483 | } |
488 | #else | 484 | #else |
489 | static inline void ocfs2_init_lock_stats(struct ocfs2_lock_res *res) | 485 | static inline void ocfs2_init_lock_stats(struct ocfs2_lock_res *res) |
@@ -2869,8 +2865,15 @@ static void *ocfs2_dlm_seq_next(struct seq_file *m, void *v, loff_t *pos) | |||
2869 | return iter; | 2865 | return iter; |
2870 | } | 2866 | } |
2871 | 2867 | ||
2872 | /* So that debugfs.ocfs2 can determine which format is being used */ | 2868 | /* |
2873 | #define OCFS2_DLM_DEBUG_STR_VERSION 2 | 2869 | * Version is used by debugfs.ocfs2 to determine the format being used |
2870 | * | ||
2871 | * New in version 2 | ||
2872 | * - Lock stats printed | ||
2873 | * New in version 3 | ||
2874 | * - Max time in lock stats is in usecs (instead of nsecs) | ||
2875 | */ | ||
2876 | #define OCFS2_DLM_DEBUG_STR_VERSION 3 | ||
2874 | static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) | 2877 | static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) |
2875 | { | 2878 | { |
2876 | int i; | 2879 | int i; |
@@ -2912,18 +2915,18 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) | |||
2912 | seq_printf(m, "0x%x\t", lvb[i]); | 2915 | seq_printf(m, "0x%x\t", lvb[i]); |
2913 | 2916 | ||
2914 | #ifdef CONFIG_OCFS2_FS_STATS | 2917 | #ifdef CONFIG_OCFS2_FS_STATS |
2915 | # define lock_num_prmode(_l) (_l)->l_lock_num_prmode | 2918 | # define lock_num_prmode(_l) ((_l)->l_lock_prmode.ls_gets) |
2916 | # define lock_num_exmode(_l) (_l)->l_lock_num_exmode | 2919 | # define lock_num_exmode(_l) ((_l)->l_lock_exmode.ls_gets) |
2917 | # define lock_num_prmode_failed(_l) (_l)->l_lock_num_prmode_failed | 2920 | # define lock_num_prmode_failed(_l) ((_l)->l_lock_prmode.ls_fail) |
2918 | # define lock_num_exmode_failed(_l) (_l)->l_lock_num_exmode_failed | 2921 | # define lock_num_exmode_failed(_l) ((_l)->l_lock_exmode.ls_fail) |
2919 | # define lock_total_prmode(_l) (_l)->l_lock_total_prmode | 2922 | # define lock_total_prmode(_l) ((_l)->l_lock_prmode.ls_total) |
2920 | # define lock_total_exmode(_l) (_l)->l_lock_total_exmode | 2923 | # define lock_total_exmode(_l) ((_l)->l_lock_exmode.ls_total) |
2921 | # define lock_max_prmode(_l) (_l)->l_lock_max_prmode | 2924 | # define lock_max_prmode(_l) ((_l)->l_lock_prmode.ls_max) |
2922 | # define lock_max_exmode(_l) (_l)->l_lock_max_exmode | 2925 | # define lock_max_exmode(_l) ((_l)->l_lock_exmode.ls_max) |
2923 | # define lock_refresh(_l) (_l)->l_lock_refresh | 2926 | # define lock_refresh(_l) ((_l)->l_lock_refresh) |
2924 | #else | 2927 | #else |
2925 | # define lock_num_prmode(_l) (0ULL) | 2928 | # define lock_num_prmode(_l) (0) |
2926 | # define lock_num_exmode(_l) (0ULL) | 2929 | # define lock_num_exmode(_l) (0) |
2927 | # define lock_num_prmode_failed(_l) (0) | 2930 | # define lock_num_prmode_failed(_l) (0) |
2928 | # define lock_num_exmode_failed(_l) (0) | 2931 | # define lock_num_exmode_failed(_l) (0) |
2929 | # define lock_total_prmode(_l) (0ULL) | 2932 | # define lock_total_prmode(_l) (0ULL) |
@@ -2933,8 +2936,8 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) | |||
2933 | # define lock_refresh(_l) (0) | 2936 | # define lock_refresh(_l) (0) |
2934 | #endif | 2937 | #endif |
2935 | /* The following seq_print was added in version 2 of this output */ | 2938 | /* The following seq_print was added in version 2 of this output */ |
2936 | seq_printf(m, "%llu\t" | 2939 | seq_printf(m, "%u\t" |
2937 | "%llu\t" | 2940 | "%u\t" |
2938 | "%u\t" | 2941 | "%u\t" |
2939 | "%u\t" | 2942 | "%u\t" |
2940 | "%llu\t" | 2943 | "%llu\t" |