]) # LIBCFS_HLIST_ADD_AFTER
#
+# Kernel version 3.17 introduced struct timespec64
+#
+AC_DEFUN([LIBCFS_TIMESPEC64],[
+LB_CHECK_COMPILE([does 'struct timespec64' exist],
+timespec64, [
+ #include <linux/time.h>
+],[
+ struct timespec64 ts;
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+],[
+ AC_DEFINE(HAVE_TIMESPEC64, 1,
+ ['struct timespec64' is available])
+])
+]) # LIBCFS_TIMESPEC64
+
+#
+# Kernel version 3.17 introduced ktime_get_real_ts64
+#
+AC_DEFUN([LIBCFS_KTIME_GET_REAL_TS64],[
+LB_CHECK_COMPILE([does function 'ktime_get_real_ts64' exist],
+ktime_get_real_ts64, [
+ #include <linux/ktime.h>
+],[
+ struct timespec64 *ts = NULL;
+
+ ktime_get_real_ts64(ts);
+],[
+ AC_DEFINE(HAVE_KTIME_GET_REAL_TS64, 1,
+ ['ktime_get_real_ts64' is available])
+])
+]) # LIBCFS_KTIME_GET_REAL_TS64
+
+#
# Kernel version 4.2 changed topology_thread_cpumask
# to topology_sibling_cpumask
#
LIBCFS_SHRINKER_COUNT
# 3.17
LIBCFS_HLIST_ADD_AFTER
+LIBCFS_TIMESPEC64
+LIBCFS_KTIME_GET_REAL_TS64
# 4.2
LIBCFS_HAVE_TOPOLOGY_SIBLING_CPUMASK
LIBCFS_FPU_API
#ifndef __LIBCFS_TIME_H__
#define __LIBCFS_TIME_H__
+
/*
* generic time manipulation functions.
*/
result; \
})
-/*
- * helper function similar to do_gettimeofday() of Linux kernel
- */
-static inline void cfs_fs_timeval(struct timeval *tv)
-{
- cfs_fs_time_t time;
-
- cfs_fs_time_current(&time);
- cfs_fs_time_usec(&time, tv);
-}
-
#define CFS_TICK 1
/*
* cfs_duration_t represents time interval with resolution of internal
* platform clock
*
- * cfs_fs_time_t represents instance in world-visible time. This is
- * used in file-system time-stamps
- *
* cfs_time_t cfs_time_current(void);
* cfs_time_t cfs_time_add (cfs_time_t, cfs_duration_t);
* cfs_duration_t cfs_time_sub (cfs_time_t, cfs_time_t);
* void cfs_duration_usec(cfs_duration_t, struct timeval *);
* void cfs_duration_nsec(cfs_duration_t, struct timespec *);
*
- * void cfs_fs_time_current(cfs_fs_time_t *);
- * time_t cfs_fs_time_sec (cfs_fs_time_t *);
- * void cfs_fs_time_usec (cfs_fs_time_t *, struct timeval *);
- * void cfs_fs_time_nsec (cfs_fs_time_t *, struct timespec *);
- * int cfs_fs_time_before (cfs_fs_time_t *, cfs_fs_time_t *);
- * int cfs_fs_time_beforeq(cfs_fs_time_t *, cfs_fs_time_t *);
- *
* CFS_TIME_FORMAT
* CFS_DURATION_FORMAT
*
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
+#include <linux/jiffies.h>
+#include <linux/types.h>
#include <linux/time.h>
#include <asm/div64.h>
/*
- * post 2.5 kernels.
+ * Generic kernel stuff
*/
-#include <linux/jiffies.h>
+typedef unsigned long cfs_time_t; /* jiffies */
+typedef long cfs_duration_t;
+typedef cycles_t cfs_cycles_t;
-typedef struct timespec cfs_fs_time_t;
+#ifndef HAVE_TIMESPEC64
-static inline void cfs_fs_time_usec(cfs_fs_time_t *t, struct timeval *v)
-{
- v->tv_sec = t->tv_sec;
- v->tv_usec = t->tv_nsec / 1000;
-}
+typedef __s64 time64_t;
-static inline void cfs_fs_time_nsec(cfs_fs_time_t *t, struct timespec *s)
+#if __BITS_PER_LONG == 64
+
+# define timespec64 timespec
+
+static inline struct timespec64 timespec_to_timespec64(const struct timespec ts)
{
- *s = *t;
+ return ts;
}
-/*
- * internal helper function used by cfs_fs_time_before*()
- */
-static inline unsigned long long __cfs_fs_time_flat(cfs_fs_time_t *t)
+#else
+struct timespec64 {
+ time64_t tv_sec; /* seconds */
+ long tv_nsec; /* nanoseconds */
+};
+
+static inline struct timespec64 timespec_to_timespec64(const struct timespec ts)
{
- return (unsigned long long)t->tv_sec * NSEC_PER_SEC + t->tv_nsec;
+ struct timespec64 ret;
+
+ ret.tv_sec = ts.tv_sec;
+ ret.tv_nsec = ts.tv_nsec;
+ return ret;
}
+#endif /* __BITS_PER_LONG != 64 */
+#endif /* HAVE_TIMESPEC64 */
-/*
- * Generic kernel stuff
- */
-
-typedef unsigned long cfs_time_t; /* jiffies */
-typedef long cfs_duration_t;
-typedef cycles_t cfs_cycles_t;
+#ifndef HAVE_KTIME_GET_REAL_TS64
+void ktime_get_real_ts64(struct timespec64 *ts);
+#endif /* HAVE_KTIME_GET_REAL_TS */
static inline int cfs_time_before(cfs_time_t t1, cfs_time_t t2)
{
return get_seconds();
}
-static inline void cfs_fs_time_current(cfs_fs_time_t *t)
-{
- *t = CURRENT_TIME;
-}
-
-static inline time_t cfs_fs_time_sec(cfs_fs_time_t *t)
-{
- return t->tv_sec;
-}
-
-static inline int cfs_fs_time_before(cfs_fs_time_t *t1, cfs_fs_time_t *t2)
-{
- return __cfs_fs_time_flat(t1) < __cfs_fs_time_flat(t2);
-}
-
-static inline int cfs_fs_time_beforeq(cfs_fs_time_t *t1, cfs_fs_time_t *t2)
-{
- return __cfs_fs_time_flat(t1) <= __cfs_fs_time_flat(t2);
-}
-
static inline cfs_duration_t cfs_time_seconds(int seconds)
{
return (__s64)t2 - (__s64)t1 >= 0;
}
-
/*
* One jiffy
*/
}
EXPORT_SYMBOL(cfs_timer_deadline);
+#ifndef HAVE_KTIME_GET_REAL_TS64
+void ktime_get_real_ts64(struct timespec64 *ts)
+{
+ *ts = timespec_to_timespec64(CURRENT_TIME);
+}
+EXPORT_SYMBOL(ktime_get_real_ts64);
+#endif /* HAVE_KTIME_GET_REAL_TS64 */
+
sigset_t
cfs_block_allsigs(void)
{
srpc_ping_reqst_t *req;
sfw_test_instance_t *tsi = tsu->tsu_instance;
sfw_session_t *sn = tsi->tsi_batch->bat_session;
- struct timeval tv;
+ struct timespec64 ts;
int rc;
LASSERT(sn != NULL);
req->pnr_seq = lst_ping_data.pnd_counter++;
spin_unlock(&lst_ping_data.pnd_lock);
- cfs_fs_timeval(&tv);
- req->pnr_time_sec = tv.tv_sec;
- req->pnr_time_usec = tv.tv_usec;
+ ktime_get_real_ts64(&ts);
+ req->pnr_time_sec = ts.tv_sec;
+ req->pnr_time_nsec = ts.tv_nsec;
return rc;
}
ping_client_done_rpc (sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc)
{
sfw_test_instance_t *tsi = tsu->tsu_instance;
- sfw_session_t *sn = tsi->tsi_batch->bat_session;
- srpc_ping_reqst_t *reqst = &rpc->crpc_reqstmsg.msg_body.ping_reqst;
- srpc_ping_reply_t *reply = &rpc->crpc_replymsg.msg_body.ping_reply;
- struct timeval tv;
+ sfw_session_t *sn = tsi->tsi_batch->bat_session;
+ srpc_ping_reqst_t *reqst = &rpc->crpc_reqstmsg.msg_body.ping_reqst;
+ srpc_ping_reply_t *reply = &rpc->crpc_replymsg.msg_body.ping_reply;
+ struct timespec64 ts;
- LASSERT (sn != NULL);
+ LASSERT(sn != NULL);
if (rpc->crpc_status != 0) {
if (!tsi->tsi_stopping) /* rpc could have been aborted */
return;
}
- cfs_fs_timeval(&tv);
- CDEBUG (D_NET, "%d reply in %u usec\n", reply->pnr_seq,
- (unsigned)((tv.tv_sec - (unsigned)reqst->pnr_time_sec) * 1000000
- + (tv.tv_usec - reqst->pnr_time_usec)));
+ ktime_get_real_ts64(&ts);
+ CDEBUG(D_NET, "%d reply in %llu nsec\n", reply->pnr_seq,
+ (u64)((ts.tv_sec - reqst->pnr_time_sec) * NSEC_PER_SEC +
+ (ts.tv_nsec - reqst->pnr_time_nsec)));
return;
}
__swab32s(&req->pnr_seq);
__swab32s(&req->pnr_magic);
__swab64s(&req->pnr_time_sec);
- __swab64s(&req->pnr_time_usec);
+ __swab64s(&req->pnr_time_nsec);
}
LASSERT (reqstmsg->msg_type == srpc_service2request(sv->sv_id));
__u32 pnr_magic;
__u32 pnr_seq;
__u64 pnr_time_sec;
- __u64 pnr_time_usec;
+ __u64 pnr_time_nsec;
} WIRE_ATTR srpc_ping_reqst_t;
typedef struct {
int mc_lastuser;
};
-static inline __u64 cl_time(void) {
- cfs_fs_time_t time;
+static inline __u64 cl_time(void)
+{
+ struct timespec64 time;
- cfs_fs_time_current(&time);
+ ktime_get_real_ts64(&time);
return (((__u64)time.tv_sec) << 30) + time.tv_nsec;
}