diff options
Diffstat (limited to 'fs/ocfs2/dlmglue.c')
-rw-r--r-- | fs/ocfs2/dlmglue.c | 136 |
1 files changed, 128 insertions, 8 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 394d25a131a5..eae3d643a5e4 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 | ||
64 | static struct ocfs2_super *ocfs2_get_dentry_osb(struct ocfs2_lock_res *lockres); | 68 | static 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 | ||
374 | static 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 | |||
387 | static 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 | |||
416 | static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres) | ||
417 | { | ||
418 | lockres->l_lock_refresh++; | ||
419 | } | ||
420 | |||
421 | static 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 | ||
427 | static inline void ocfs2_init_lock_stats(struct ocfs2_lock_res *res) | ||
428 | { | ||
429 | } | ||
430 | static inline void ocfs2_update_lock_stats(struct ocfs2_lock_res *res, | ||
431 | int level, struct ocfs2_mask_waiter *mw, int ret) | ||
432 | { | ||
433 | } | ||
434 | static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres) | ||
435 | { | ||
436 | } | ||
437 | static inline void ocfs2_init_start_time(struct ocfs2_mask_waiter *mw) | ||
438 | { | ||
439 | } | ||
440 | #endif | ||
441 | |||
369 | static void ocfs2_lock_res_init_common(struct ocfs2_super *osb, | 442 | static 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 | ||
390 | void ocfs2_lock_res_init_once(struct ocfs2_lock_res *res) | 465 | void 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 | ||
1053 | static int ocfs2_wait_for_mask(struct ocfs2_mask_waiter *mw) | 1129 | static 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; |
@@ -1554,8 +1631,8 @@ out: | |||
1554 | */ | 1631 | */ |
1555 | int ocfs2_file_lock(struct file *file, int ex, int trylock) | 1632 | int ocfs2_file_lock(struct file *file, int ex, int trylock) |
1556 | { | 1633 | { |
1557 | int ret, level = ex ? LKM_EXMODE : LKM_PRMODE; | 1634 | int ret, level = ex ? DLM_LOCK_EX : DLM_LOCK_PR; |
1558 | unsigned int lkm_flags = trylock ? LKM_NOQUEUE : 0; | 1635 | unsigned int lkm_flags = trylock ? DLM_LKF_NOQUEUE : 0; |
1559 | unsigned long flags; | 1636 | unsigned long flags; |
1560 | struct ocfs2_file_private *fp = file->private_data; | 1637 | struct ocfs2_file_private *fp = file->private_data; |
1561 | struct ocfs2_lock_res *lockres = &fp->fp_flock; | 1638 | struct ocfs2_lock_res *lockres = &fp->fp_flock; |
@@ -1582,7 +1659,7 @@ int ocfs2_file_lock(struct file *file, int ex, int trylock) | |||
1582 | * Get the lock at NLMODE to start - that way we | 1659 | * Get the lock at NLMODE to start - that way we |
1583 | * can cancel the upconvert request if need be. | 1660 | * can cancel the upconvert request if need be. |
1584 | */ | 1661 | */ |
1585 | ret = ocfs2_lock_create(osb, lockres, LKM_NLMODE, 0); | 1662 | ret = ocfs2_lock_create(osb, lockres, DLM_LOCK_NL, 0); |
1586 | if (ret < 0) { | 1663 | if (ret < 0) { |
1587 | mlog_errno(ret); | 1664 | mlog_errno(ret); |
1588 | goto out; | 1665 | goto out; |
@@ -1597,7 +1674,7 @@ int ocfs2_file_lock(struct file *file, int ex, int trylock) | |||
1597 | } | 1674 | } |
1598 | 1675 | ||
1599 | lockres->l_action = OCFS2_AST_CONVERT; | 1676 | lockres->l_action = OCFS2_AST_CONVERT; |
1600 | lkm_flags |= LKM_CONVERT; | 1677 | lkm_flags |= DLM_LKF_CONVERT; |
1601 | lockres->l_requested = level; | 1678 | lockres->l_requested = level; |
1602 | lockres_or_flags(lockres, OCFS2_LOCK_BUSY); | 1679 | lockres_or_flags(lockres, OCFS2_LOCK_BUSY); |
1603 | 1680 | ||
@@ -1664,7 +1741,7 @@ void ocfs2_file_unlock(struct file *file) | |||
1664 | if (!(lockres->l_flags & OCFS2_LOCK_ATTACHED)) | 1741 | if (!(lockres->l_flags & OCFS2_LOCK_ATTACHED)) |
1665 | return; | 1742 | return; |
1666 | 1743 | ||
1667 | if (lockres->l_level == LKM_NLMODE) | 1744 | if (lockres->l_level == DLM_LOCK_NL) |
1668 | return; | 1745 | return; |
1669 | 1746 | ||
1670 | mlog(0, "Unlock: \"%s\" flags: 0x%lx, level: %d, act: %d\n", | 1747 | mlog(0, "Unlock: \"%s\" flags: 0x%lx, level: %d, act: %d\n", |
@@ -1678,11 +1755,11 @@ void ocfs2_file_unlock(struct file *file) | |||
1678 | lockres_or_flags(lockres, OCFS2_LOCK_BLOCKED); | 1755 | lockres_or_flags(lockres, OCFS2_LOCK_BLOCKED); |
1679 | lockres->l_blocking = DLM_LOCK_EX; | 1756 | lockres->l_blocking = DLM_LOCK_EX; |
1680 | 1757 | ||
1681 | gen = ocfs2_prepare_downconvert(lockres, LKM_NLMODE); | 1758 | gen = ocfs2_prepare_downconvert(lockres, DLM_LOCK_NL); |
1682 | lockres_add_mask_waiter(lockres, &mw, OCFS2_LOCK_BUSY, 0); | 1759 | lockres_add_mask_waiter(lockres, &mw, OCFS2_LOCK_BUSY, 0); |
1683 | spin_unlock_irqrestore(&lockres->l_lock, flags); | 1760 | spin_unlock_irqrestore(&lockres->l_lock, flags); |
1684 | 1761 | ||
1685 | ret = ocfs2_downconvert_lock(osb, lockres, LKM_NLMODE, 0, gen); | 1762 | ret = ocfs2_downconvert_lock(osb, lockres, DLM_LOCK_NL, 0, gen); |
1686 | if (ret) { | 1763 | if (ret) { |
1687 | mlog_errno(ret); | 1764 | mlog_errno(ret); |
1688 | return; | 1765 | return; |
@@ -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 | } |
2271 | bail: | 2350 | bail: |
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 |
2465 | static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) | 2544 | static 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) (0ULL) | ||
2596 | # define lock_num_exmode(_l) (0ULL) | ||
2597 | # define lock_num_prmode_failed(_l) (0) | ||
2598 | # define lock_num_exmode_failed(_l) (0) | ||
2599 | # define lock_total_prmode(_l) (0ULL) | ||
2600 | # define lock_total_exmode(_l) (0ULL) | ||
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; |