Skip to content

Commit 5da844a

Browse files
Gang Hetorvalds
authored andcommitted
ocfs2: add first lock wait time in locking_state
ocfs2 file system uses locking_state file under debugfs to dump each ocfs2 file system's dlm lock resources, but the users ever encountered some hang(deadlock) problems in ocfs2 file system. I'd like to add first lock wait time in locking_state file, which can help the upper scripts detect these deadlock problems via comparing the first lock wait time with the current time. Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Gang He <[email protected]> Reviewed-by: Joseph Qi <[email protected]> Cc: Mark Fasheh <[email protected]> Cc: Joel Becker <[email protected]> Cc: Junxiao Bi <[email protected]> Cc: Changwei Ge <[email protected]> Cc: Gang He <[email protected]> Cc: Jun Piao <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 8056773 commit 5da844a

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

fs/ocfs2/dlmglue.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ static void ocfs2_remove_lockres_tracking(struct ocfs2_lock_res *res)
426426
static void ocfs2_init_lock_stats(struct ocfs2_lock_res *res)
427427
{
428428
res->l_lock_refresh = 0;
429+
res->l_lock_wait = 0;
429430
memset(&res->l_lock_prmode, 0, sizeof(struct ocfs2_lock_stats));
430431
memset(&res->l_lock_exmode, 0, sizeof(struct ocfs2_lock_stats));
431432
}
@@ -469,6 +470,21 @@ static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres)
469470
lockres->l_lock_refresh++;
470471
}
471472

473+
static inline void ocfs2_track_lock_wait(struct ocfs2_lock_res *lockres)
474+
{
475+
struct ocfs2_mask_waiter *mw;
476+
477+
if (list_empty(&lockres->l_mask_waiters)) {
478+
lockres->l_lock_wait = 0;
479+
return;
480+
}
481+
482+
mw = list_first_entry(&lockres->l_mask_waiters,
483+
struct ocfs2_mask_waiter, mw_item);
484+
lockres->l_lock_wait =
485+
ktime_to_us(ktime_mono_to_real(mw->mw_lock_start));
486+
}
487+
472488
static inline void ocfs2_init_start_time(struct ocfs2_mask_waiter *mw)
473489
{
474490
mw->mw_lock_start = ktime_get();
@@ -484,6 +500,9 @@ static inline void ocfs2_update_lock_stats(struct ocfs2_lock_res *res,
484500
static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres)
485501
{
486502
}
503+
static inline void ocfs2_track_lock_wait(struct ocfs2_lock_res *lockres)
504+
{
505+
}
487506
static inline void ocfs2_init_start_time(struct ocfs2_mask_waiter *mw)
488507
{
489508
}
@@ -877,6 +896,7 @@ static void lockres_set_flags(struct ocfs2_lock_res *lockres,
877896
list_del_init(&mw->mw_item);
878897
mw->mw_status = 0;
879898
complete(&mw->mw_complete);
899+
ocfs2_track_lock_wait(lockres);
880900
}
881901
}
882902
static void lockres_or_flags(struct ocfs2_lock_res *lockres, unsigned long or)
@@ -1388,6 +1408,7 @@ static void lockres_add_mask_waiter(struct ocfs2_lock_res *lockres,
13881408
list_add_tail(&mw->mw_item, &lockres->l_mask_waiters);
13891409
mw->mw_mask = mask;
13901410
mw->mw_goal = goal;
1411+
ocfs2_track_lock_wait(lockres);
13911412
}
13921413

13931414
/* returns 0 if the mw that was removed was already satisfied, -EBUSY
@@ -1404,6 +1425,7 @@ static int __lockres_remove_mask_waiter(struct ocfs2_lock_res *lockres,
14041425

14051426
list_del_init(&mw->mw_item);
14061427
init_completion(&mw->mw_complete);
1428+
ocfs2_track_lock_wait(lockres);
14071429
}
14081430

14091431
return ret;
@@ -3084,7 +3106,7 @@ static void *ocfs2_dlm_seq_next(struct seq_file *m, void *v, loff_t *pos)
30843106
* New in version 3
30853107
* - Max time in lock stats is in usecs (instead of nsecs)
30863108
* New in version 4
3087-
* - Add last pr/ex unlock times in usecs
3109+
* - Add last pr/ex unlock times and first lock wait time in usecs
30883110
*/
30893111
#define OCFS2_DLM_DEBUG_STR_VERSION 4
30903112
static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
@@ -3102,7 +3124,7 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
31023124
return -EINVAL;
31033125

31043126
#ifdef CONFIG_OCFS2_FS_STATS
3105-
if (dlm_debug->d_filter_secs) {
3127+
if (!lockres->l_lock_wait && dlm_debug->d_filter_secs) {
31063128
now = ktime_to_us(ktime_get_real());
31073129
if (lockres->l_lock_prmode.ls_last >
31083130
lockres->l_lock_exmode.ls_last)
@@ -3163,6 +3185,7 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
31633185
# define lock_refresh(_l) ((_l)->l_lock_refresh)
31643186
# define lock_last_prmode(_l) ((_l)->l_lock_prmode.ls_last)
31653187
# define lock_last_exmode(_l) ((_l)->l_lock_exmode.ls_last)
3188+
# define lock_wait(_l) ((_l)->l_lock_wait)
31663189
#else
31673190
# define lock_num_prmode(_l) (0)
31683191
# define lock_num_exmode(_l) (0)
@@ -3175,6 +3198,7 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
31753198
# define lock_refresh(_l) (0)
31763199
# define lock_last_prmode(_l) (0ULL)
31773200
# define lock_last_exmode(_l) (0ULL)
3201+
# define lock_wait(_l) (0ULL)
31783202
#endif
31793203
/* The following seq_print was added in version 2 of this output */
31803204
seq_printf(m, "%u\t"
@@ -3187,6 +3211,7 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
31873211
"%u\t"
31883212
"%u\t"
31893213
"%llu\t"
3214+
"%llu\t"
31903215
"%llu\t",
31913216
lock_num_prmode(lockres),
31923217
lock_num_exmode(lockres),
@@ -3198,7 +3223,8 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
31983223
lock_max_exmode(lockres),
31993224
lock_refresh(lockres),
32003225
lock_last_prmode(lockres),
3201-
lock_last_exmode(lockres));
3226+
lock_last_exmode(lockres),
3227+
lock_wait(lockres));
32023228

32033229
/* End the line */
32043230
seq_printf(m, "\n");

fs/ocfs2/ocfs2.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ struct ocfs2_lock_res {
192192
#ifdef CONFIG_OCFS2_FS_STATS
193193
struct ocfs2_lock_stats l_lock_prmode; /* PR mode stats */
194194
u32 l_lock_refresh; /* Disk refreshes */
195+
u64 l_lock_wait; /* First lock wait time */
195196
struct ocfs2_lock_stats l_lock_exmode; /* EX mode stats */
196197
#endif
197198
#ifdef CONFIG_DEBUG_LOCK_ALLOC

0 commit comments

Comments
 (0)