@@ -426,6 +426,7 @@ static void ocfs2_remove_lockres_tracking(struct ocfs2_lock_res *res)
426426static 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+
472488static 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,
484500static 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+ }
487506static 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}
882902static 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
30903112static 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" );
0 commit comments