aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSunil Mushran <sunil.mushran@oracle.com>2008-05-13 16:45:15 -0400
committerMark Fasheh <mfasheh@suse.com>2008-07-14 16:57:14 -0400
commit8ddb7b004dfa1832a750e199df8bff4b75b73565 (patch)
tree92adac97690c27e44a65825864d4d5f9a6a2ca22
parentce7231e92dac381f6e4f9cfdfdf9e0ea055223ad (diff)
[PATCH 2/2] ocfs2: Instrument fs cluster locks
This patch adds code to track the number of times the fs takes various cluster locks as well as the times associated with it. The information is made available to users via debugfs. This patch was originally written by Jan Kara <jack@suse.cz>. Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
-rw-r--r--fs/ocfs2/dlmglue.c122
-rw-r--r--fs/ocfs2/ocfs2.h12
2 files changed, 133 insertions, 1 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 80e20d9f2780..80537b769e41 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -31,6 +31,7 @@
31#include <linux/pagemap.h> 31#include <linux/pagemap.h>
32#include <linux/debugfs.h> 32#include <linux/debugfs.h>
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34#include <linux/time.h>
34 35
35#define MLOG_MASK_PREFIX ML_DLM_GLUE 36#define MLOG_MASK_PREFIX ML_DLM_GLUE
36#include <cluster/masklog.h> 37#include <cluster/masklog.h>
@@ -59,6 +60,9 @@ struct ocfs2_mask_waiter {
59 struct completion mw_complete; 60 struct completion mw_complete;
60 unsigned long mw_mask; 61 unsigned long mw_mask;
61 unsigned long mw_goal; 62 unsigned long mw_goal;
63#ifdef CONFIG_OCFS2_FS_STATS
64 unsigned long long mw_lock_start;
65#endif
62}; 66};
63 67
64static struct ocfs2_super *ocfs2_get_dentry_osb(struct ocfs2_lock_res *lockres); 68static struct ocfs2_super *ocfs2_get_dentry_osb(struct ocfs2_lock_res *lockres);
@@ -366,6 +370,75 @@ static void ocfs2_remove_lockres_tracking(struct ocfs2_lock_res *res)
366 spin_unlock(&ocfs2_dlm_tracking_lock); 370 spin_unlock(&ocfs2_dlm_tracking_lock);
367} 371}
368 372
373#ifdef CONFIG_OCFS2_FS_STATS
374static void ocfs2_init_lock_stats(struct ocfs2_lock_res *res)
375{
376 res->l_lock_num_prmode = 0;
377 res->l_lock_num_prmode_failed = 0;
378 res->l_lock_total_prmode = 0;
379 res->l_lock_max_prmode = 0;
380 res->l_lock_num_exmode = 0;
381 res->l_lock_num_exmode_failed = 0;
382 res->l_lock_total_exmode = 0;
383 res->l_lock_max_exmode = 0;
384 res->l_lock_refresh = 0;
385}
386
387static void ocfs2_update_lock_stats(struct ocfs2_lock_res *res, int level,
388 struct ocfs2_mask_waiter *mw, int ret)
389{
390 unsigned long long *num, *sum;
391 unsigned int *max, *failed;
392 struct timespec ts = current_kernel_time();
393 unsigned long long time = timespec_to_ns(&ts) - mw->mw_lock_start;
394
395 if (level == LKM_PRMODE) {
396 num = &res->l_lock_num_prmode;
397 sum = &res->l_lock_total_prmode;
398 max = &res->l_lock_max_prmode;
399 failed = &res->l_lock_num_prmode_failed;
400 } else if (level == LKM_EXMODE) {
401 num = &res->l_lock_num_exmode;
402 sum = &res->l_lock_total_exmode;
403 max = &res->l_lock_max_exmode;
404 failed = &res->l_lock_num_exmode_failed;
405 } else
406 return;
407
408 (*num)++;
409 (*sum) += time;
410 if (time > *max)
411 *max = time;
412 if (ret)
413 (*failed)++;
414}
415
416static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres)
417{
418 lockres->l_lock_refresh++;
419}
420
421static inline void ocfs2_init_start_time(struct ocfs2_mask_waiter *mw)
422{
423 struct timespec ts = current_kernel_time();
424 mw->mw_lock_start = timespec_to_ns(&ts);
425}
426#else
427static inline void ocfs2_init_lock_stats(struct ocfs2_lock_res *res)
428{
429}
430static inline void ocfs2_update_lock_stats(struct ocfs2_lock_res *res,
431 int level, struct ocfs2_mask_waiter *mw, int ret)
432{
433}
434static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres)
435{
436}
437static inline void ocfs2_init_start_time(struct ocfs2_mask_waiter *mw)
438{
439}
440#endif
441
369static void ocfs2_lock_res_init_common(struct ocfs2_super *osb, 442static void ocfs2_lock_res_init_common(struct ocfs2_super *osb,
370 struct ocfs2_lock_res *res, 443 struct ocfs2_lock_res *res,
371 enum ocfs2_lock_type type, 444 enum ocfs2_lock_type type,
@@ -385,6 +458,8 @@ static void ocfs2_lock_res_init_common(struct ocfs2_super *osb,
385 res->l_flags = OCFS2_LOCK_INITIALIZED; 458 res->l_flags = OCFS2_LOCK_INITIALIZED;
386 459
387 ocfs2_add_lockres_tracking(res, osb->osb_dlm_debug); 460 ocfs2_add_lockres_tracking(res, osb->osb_dlm_debug);
461
462 ocfs2_init_lock_stats(res);
388} 463}
389 464
390void ocfs2_lock_res_init_once(struct ocfs2_lock_res *res) 465void ocfs2_lock_res_init_once(struct ocfs2_lock_res *res)
@@ -1048,6 +1123,7 @@ static void ocfs2_init_mask_waiter(struct ocfs2_mask_waiter *mw)
1048{ 1123{
1049 INIT_LIST_HEAD(&mw->mw_item); 1124 INIT_LIST_HEAD(&mw->mw_item);
1050 init_completion(&mw->mw_complete); 1125 init_completion(&mw->mw_complete);
1126 ocfs2_init_start_time(mw);
1051} 1127}
1052 1128
1053static int ocfs2_wait_for_mask(struct ocfs2_mask_waiter *mw) 1129static int ocfs2_wait_for_mask(struct ocfs2_mask_waiter *mw)
@@ -1254,6 +1330,7 @@ out:
1254 goto again; 1330 goto again;
1255 mlog_errno(ret); 1331 mlog_errno(ret);
1256 } 1332 }
1333 ocfs2_update_lock_stats(lockres, level, &mw, ret);
1257 1334
1258 mlog_exit(ret); 1335 mlog_exit(ret);
1259 return ret; 1336 return ret;
@@ -1983,6 +2060,7 @@ static int ocfs2_inode_lock_update(struct inode *inode,
1983 le32_to_cpu(fe->i_flags)); 2060 le32_to_cpu(fe->i_flags));
1984 2061
1985 ocfs2_refresh_inode(inode, fe); 2062 ocfs2_refresh_inode(inode, fe);
2063 ocfs2_track_lock_refresh(lockres);
1986 } 2064 }
1987 2065
1988 status = 0; 2066 status = 0;
@@ -2267,6 +2345,7 @@ int ocfs2_super_lock(struct ocfs2_super *osb,
2267 2345
2268 if (status < 0) 2346 if (status < 0)
2269 mlog_errno(status); 2347 mlog_errno(status);
2348 ocfs2_track_lock_refresh(lockres);
2270 } 2349 }
2271bail: 2350bail:
2272 mlog_exit(status); 2351 mlog_exit(status);
@@ -2461,7 +2540,7 @@ static void *ocfs2_dlm_seq_next(struct seq_file *m, void *v, loff_t *pos)
2461} 2540}
2462 2541
2463/* So that debugfs.ocfs2 can determine which format is being used */ 2542/* So that debugfs.ocfs2 can determine which format is being used */
2464#define OCFS2_DLM_DEBUG_STR_VERSION 1 2543#define OCFS2_DLM_DEBUG_STR_VERSION 2
2465static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) 2544static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
2466{ 2545{
2467 int i; 2546 int i;
@@ -2502,6 +2581,47 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
2502 for(i = 0; i < DLM_LVB_LEN; i++) 2581 for(i = 0; i < DLM_LVB_LEN; i++)
2503 seq_printf(m, "0x%x\t", lvb[i]); 2582 seq_printf(m, "0x%x\t", lvb[i]);
2504 2583
2584#ifdef CONFIG_OCFS2_FS_STATS
2585# define lock_num_prmode(_l) (_l)->l_lock_num_prmode
2586# define lock_num_exmode(_l) (_l)->l_lock_num_exmode
2587# define lock_num_prmode_failed(_l) (_l)->l_lock_num_prmode_failed
2588# define lock_num_exmode_failed(_l) (_l)->l_lock_num_exmode_failed
2589# define lock_total_prmode(_l) (_l)->l_lock_total_prmode
2590# define lock_total_exmode(_l) (_l)->l_lock_total_exmode
2591# define lock_max_prmode(_l) (_l)->l_lock_max_prmode
2592# define lock_max_exmode(_l) (_l)->l_lock_max_exmode
2593# define lock_refresh(_l) (_l)->l_lock_refresh
2594#else
2595# define lock_num_prmode(_l) (0)
2596# define lock_num_exmode(_l) (0)
2597# define lock_num_prmode_failed(_l) (0)
2598# define lock_num_exmode_failed(_l) (0)
2599# define lock_total_prmode(_l) (0)
2600# define lock_total_exmode(_l) (0)
2601# define lock_max_prmode(_l) (0)
2602# define lock_max_exmode(_l) (0)
2603# define lock_refresh(_l) (0)
2604#endif
2605 /* The following seq_print was added in version 2 of this output */
2606 seq_printf(m, "%llu\t"
2607 "%llu\t"
2608 "%u\t"
2609 "%u\t"
2610 "%llu\t"
2611 "%llu\t"
2612 "%u\t"
2613 "%u\t"
2614 "%u\t",
2615 lock_num_prmode(lockres),
2616 lock_num_exmode(lockres),
2617 lock_num_prmode_failed(lockres),
2618 lock_num_exmode_failed(lockres),
2619 lock_total_prmode(lockres),
2620 lock_total_exmode(lockres),
2621 lock_max_prmode(lockres),
2622 lock_max_exmode(lockres),
2623 lock_refresh(lockres));
2624
2505 /* End the line */ 2625 /* End the line */
2506 seq_printf(m, "\n"); 2626 seq_printf(m, "\n");
2507 return 0; 2627 return 0;
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index 31692379c170..1cb814be8ef1 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -132,6 +132,18 @@ struct ocfs2_lock_res {
132 wait_queue_head_t l_event; 132 wait_queue_head_t l_event;
133 133
134 struct list_head l_debug_list; 134 struct list_head l_debug_list;
135
136#ifdef CONFIG_OCFS2_FS_STATS
137 unsigned long long l_lock_num_prmode; /* PR acquires */
138 unsigned long long l_lock_num_exmode; /* EX acquires */
139 unsigned int l_lock_num_prmode_failed; /* Failed PR gets */
140 unsigned int l_lock_num_exmode_failed; /* Failed EX gets */
141 unsigned long long l_lock_total_prmode; /* Tot wait for PR */
142 unsigned long long l_lock_total_exmode; /* Tot wait for EX */
143 unsigned int l_lock_max_prmode; /* Max wait for PR */
144 unsigned int l_lock_max_exmode; /* Max wait for EX */
145 unsigned int l_lock_refresh; /* Disk refreshes */
146#endif
135}; 147};
136 148
137struct ocfs2_dlm_debug { 149struct ocfs2_dlm_debug {