aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 {