From 6567c835b9261b1cb64621716206c68f98136b6f Mon Sep 17 00:00:00 2001 From: James Simmons Date: Thu, 9 Mar 2017 12:59:33 -0500 Subject: [PATCH] LU-9019 msg : migrate IR stats to 64 bit time Replace the struct timeval usage due to the overflow issues in 2038 on 32-bit systems. Use of struct timeval upstream is deprecated as well. Replace its use with timespec64 and use ktime to store the fsdb_notify_* fields. Change-Id: I7771710723d6717cbff93e64abdf794957c42be5 Signed-off-by: James Simmons Reviewed-on: https://review.whamcloud.com/24919 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Jinshan Xiong Reviewed-by: Andreas Dilger Reviewed-by: John L. Hammond Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin --- libcfs/autoconf/lustre-libcfs.m4 | 56 ++++++++++++++++++++++++++++ libcfs/include/libcfs/linux/linux-time.h | 20 ++++++++++ lustre/mgs/mgs_internal.h | 7 ++-- lustre/mgs/mgs_nids.c | 64 ++++++++++++++++---------------- 4 files changed, 111 insertions(+), 36 deletions(-) diff --git a/libcfs/autoconf/lustre-libcfs.m4 b/libcfs/autoconf/lustre-libcfs.m4 index 979b815..175d98b 100644 --- a/libcfs/autoconf/lustre-libcfs.m4 +++ b/libcfs/autoconf/lustre-libcfs.m4 @@ -279,6 +279,41 @@ ktime_get_ts64, [ ]) # LIBCFS_KTIME_GET_TS64 # +# Kernel version 3.12 introduced ktime_add +# +AC_DEFUN([LIBCFS_KTIME_ADD],[ +LB_CHECK_COMPILE([does function 'ktime_add' exist], +ktime_add, [ + #include +],[ + ktime_t start = ktime_set(0, 0); + ktime_t end = start; + ktime_t total; + + total = ktime_add(start, end); +],[ + AC_DEFINE(HAVE_KTIME_ADD, 1, + [ktime_add is available]) +]) +]) # LIBCFS_KTIME_ADD + +# +# Kernel version 3.12 introduced ktime_after +# +AC_DEFUN([LIBCFS_KTIME_AFTER],[ +LB_CHECK_COMPILE([does function 'ktime_after' exist], +ktime_after, [ + #include +],[ + ktime_t start = ktime_set(0, 0); + ktime_t end = start; + + ktime_after(start, end); +],[ + AC_DEFINE(HAVE_KTIME_AFTER, 1, + [ktime_after is available]) +]) +]) # LIBCFS_KTIME_AFTER # # FC19 3.12 kernel struct shrinker change @@ -382,6 +417,24 @@ ktime_get_real_ns, [ ]) # LIBCFS_KTIME_GET_REAL_NS # +# Kernel version 3.17 introduced ktime_to_timespec64 +# +AC_DEFUN([LIBCFS_KTIME_TO_TIMESPEC64],[ +LB_CHECK_COMPILE([does function 'ktime_to_timespec64' exist], +ktime_to_timespec64, [ + #include +],[ + struct timespec64 ts; + ktime_t now; + + ts = ktime_to_timespec64(now); +],[ + AC_DEFINE(HAVE_KTIME_TO_TIMESPEC64, 1, + ['ktime_to_timespec64' is available]) +]) +]) # LIBCFS_KTIME_TO_TIMESPEC64 + +# # Kernel version 3.19 introduced ktime_get_seconds # AC_DEFUN([LIBCFS_KTIME_GET_SECONDS],[ @@ -516,6 +569,8 @@ LIBCFS_ENABLE_CRC32C_ACCEL # 3.11 LIBCFS_KTIME_GET_TS64 # 3.12 +LIBCFS_KTIME_ADD +LIBCFS_KTIME_AFTER LIBCFS_SHRINKER_COUNT # 3.17 LIBCFS_HLIST_ADD_AFTER @@ -523,6 +578,7 @@ LIBCFS_TIMESPEC64 LIBCFS_KTIME_GET_REAL_TS64 LIBCFS_KTIME_GET_REAL_SECONDS LIBCFS_KTIME_GET_REAL_NS +LIBCFS_KTIME_TO_TIMESPEC64 # 3.19 LIBCFS_KTIME_GET_SECONDS # 4.2 diff --git a/libcfs/include/libcfs/linux/linux-time.h b/libcfs/include/libcfs/linux/linux-time.h index 6c1004d..6d1b085 100644 --- a/libcfs/include/libcfs/linux/linux-time.h +++ b/libcfs/include/libcfs/linux/linux-time.h @@ -129,6 +129,17 @@ static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) #endif /* HAVE_TIMESPEC64 */ +#ifndef HAVE_KTIME_ADD +# define ktime_add(lhs, rhs) ({ (ktime_t){ .tv64 = (lhs).tv64 + (rhs).tv64 }; }) +#endif /* !HAVE_KTIME_ADD */ + +#ifndef HAVE_KTIME_AFTER +static inline bool ktime_after(const ktime_t cmp1, const ktime_t cmp2) +{ + return cmp1.tv64 > cmp2.tv64; +} +#endif /* !HAVE_KTIME_AFTER */ + #ifndef HAVE_KTIME_GET_TS64 void ktime_get_ts64(struct timespec64 *ts); #endif /* HAVE_KTIME_GET_TS */ @@ -152,6 +163,15 @@ static inline u64 ktime_get_real_ns(void) } #endif /* NEED_KTIME_GET_REAL_NS */ +#ifndef HAVE_KTIME_TO_TIMESPEC64 +static inline struct timespec64 ktime_to_timespec64(ktime_t kt) +{ + struct timespec ts = ns_to_timespec((kt).tv64); + + return timespec_to_timespec64(ts); +} +#endif /* HAVE_KTIME_TO_TIMESPEC64 */ + static inline int cfs_time_before(cfs_time_t t1, cfs_time_t t2) { return time_before(t1, t2); diff --git a/lustre/mgs/mgs_internal.h b/lustre/mgs/mgs_internal.h index 634a9fe..0f2463c 100644 --- a/lustre/mgs/mgs_internal.h +++ b/lustre/mgs/mgs_internal.h @@ -53,7 +53,6 @@ struct mgs_nidtbl_target { struct mgs_nidtbl *mnt_fs; u64 mnt_version; int mnt_type; /* OST or MDT */ - cfs_time_t mnt_last_active; struct mgs_target_info mnt_mti; }; @@ -152,15 +151,15 @@ struct fs_db { struct mgs_device *fsdb_mgs; wait_queue_head_t fsdb_notify_waitq; struct completion fsdb_notify_comp; - cfs_time_t fsdb_notify_start; + ktime_t fsdb_notify_start; atomic_t fsdb_notify_phase; volatile unsigned int fsdb_notify_async:1, fsdb_notify_stop:1, fsdb_has_lproc_entry:1, fsdb_barrier_disabled:1; /* statistic data */ - unsigned int fsdb_notify_total; - unsigned int fsdb_notify_max; + ktime_t fsdb_notify_total; + ktime_t fsdb_notify_max; unsigned int fsdb_notify_count; __u32 fsdb_gen; }; diff --git a/lustre/mgs/mgs_nids.c b/lustre/mgs/mgs_nids.c index 3376fb2..fecd6d5 100644 --- a/lustre/mgs/mgs_nids.c +++ b/lustre/mgs/mgs_nids.c @@ -398,21 +398,21 @@ static int mgs_nidtbl_init_fs(const struct lu_env *env, struct fs_db *fsdb) /* --------- Imperative Recovery relies on nidtbl stuff ------- */ void mgs_ir_notify_complete(struct fs_db *fsdb) { - struct timeval tv; - cfs_duration_t delta; + struct timespec64 ts; + ktime_t delta; atomic_set(&fsdb->fsdb_notify_phase, 0); - /* do statistic */ - fsdb->fsdb_notify_count++; - delta = cfs_time_sub(cfs_time_current(), fsdb->fsdb_notify_start); - fsdb->fsdb_notify_total += delta; - if (delta > fsdb->fsdb_notify_max) - fsdb->fsdb_notify_max = delta; + /* do statistic */ + fsdb->fsdb_notify_count++; + delta = ktime_sub(ktime_get(), fsdb->fsdb_notify_start); + fsdb->fsdb_notify_total = ktime_add(fsdb->fsdb_notify_total, delta); + if (ktime_after(delta, fsdb->fsdb_notify_max)) + fsdb->fsdb_notify_max = delta; - cfs_duration_usec(delta, &tv); - CDEBUG(D_MGS, "Revoke recover lock of %s completed after %ld.%06lds\n", - fsdb->fsdb_name, tv.tv_sec, tv.tv_usec); + ts = ktime_to_timespec64(fsdb->fsdb_notify_max); + CDEBUG(D_MGS, "Revoke recover lock of %s completed after %lld.%09lds\n", + fsdb->fsdb_name, (s64)ts.tv_sec, ts.tv_nsec); } static int mgs_ir_notify(void *arg) @@ -440,7 +440,7 @@ static int mgs_ir_notify(void *arg) CDEBUG(D_MGS, "%s woken up, phase is %d\n", name, atomic_read(&fsdb->fsdb_notify_phase)); - fsdb->fsdb_notify_start = cfs_time_current(); + fsdb->fsdb_notify_start = ktime_get(); mgs_revoke_lock(fsdb->fsdb_mgs, fsdb, CONFIG_T_RECOVER); } @@ -721,13 +721,13 @@ static int lprocfs_ir_set_timeout(struct fs_db *fsdb, const char *buf) static int lprocfs_ir_clear_stats(struct fs_db *fsdb, const char *buf) { - if (*buf) - return -EINVAL; + if (*buf) + return -EINVAL; - fsdb->fsdb_notify_total = 0; - fsdb->fsdb_notify_max = 0; - fsdb->fsdb_notify_count = 0; - return 0; + fsdb->fsdb_notify_total = ktime_set(0, 0); + fsdb->fsdb_notify_max = ktime_set(0, 0); + fsdb->fsdb_notify_count = 0; + return 0; } static struct lproc_ir_cmd { @@ -800,11 +800,11 @@ int lprocfs_wr_ir_state(struct file *file, const char __user *buffer, int lprocfs_rd_ir_state(struct seq_file *seq, void *data) { - struct fs_db *fsdb = data; - struct mgs_nidtbl *tbl = &fsdb->fsdb_nidtbl; - const char *ir_strings[] = IR_STRINGS; - struct timeval tv_max; - struct timeval tv; + struct fs_db *fsdb = data; + struct mgs_nidtbl *tbl = &fsdb->fsdb_nidtbl; + const char *ir_strings[] = IR_STRINGS; + struct timespec64 ts_max; + struct timespec64 ts; /* mgs_live_seq_show() already holds fsdb_mutex. */ ir_state_graduate(fsdb); @@ -817,17 +817,17 @@ int lprocfs_rd_ir_state(struct seq_file *seq, void *data) ir_strings[fsdb->fsdb_ir_state], fsdb->fsdb_nonir_clients, tbl->mn_version); - cfs_duration_usec(fsdb->fsdb_notify_total, &tv); - cfs_duration_usec(fsdb->fsdb_notify_max, &tv_max); + ts = ktime_to_timespec64(fsdb->fsdb_notify_total); + ts_max = ktime_to_timespec64(fsdb->fsdb_notify_max); - seq_printf(seq, " notify_duration_total: %lu.%06lu\n" - " notify_duation_max: %lu.%06lu\n" - " notify_count: %u\n", - tv.tv_sec, tv.tv_usec, - tv_max.tv_sec, tv_max.tv_usec, - fsdb->fsdb_notify_count); + seq_printf(seq, " notify_duration_total: %lld.%09ld\n" + " notify_duation_max: %lld.%09ld\n" + " notify_count: %u\n", + (s64)ts.tv_sec, ts.tv_nsec, + (s64)ts_max.tv_sec, ts_max.tv_nsec, + fsdb->fsdb_notify_count); - return 0; + return 0; } int lprocfs_ir_timeout_seq_show(struct seq_file *m, void *data) -- 1.8.3.1