]) # 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 <linux/ktime.h>
+],[
+ 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 <linux/ktime.h>
+],[
+ 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
]) # 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 <linux/ktime.h>
+],[
+ 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],[
# 3.11
LIBCFS_KTIME_GET_TS64
# 3.12
+LIBCFS_KTIME_ADD
+LIBCFS_KTIME_AFTER
LIBCFS_SHRINKER_COUNT
# 3.17
LIBCFS_HLIST_ADD_AFTER
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
#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 */
}
#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);
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;
};
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;
};
/* --------- 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)
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);
}
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 {
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);
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)