Whamcloud - gitweb
LU-4423 lnet: Better cookie gen 82/24682/6
authorTina Ruchandani <ruchandani.tina@gmail.com>
Thu, 5 Jan 2017 14:53:30 +0000 (09:53 -0500)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 24 Jan 2017 05:23:34 +0000 (05:23 +0000)
api-ni.c uses do_gettimeofday to get a 'cookie' or timestamp.
This patch replaces it with ktime_get_ns for the following reasons:

1. ktime_get_ns returns a __u64 which is safer than 'struct timeval'
   which will overflow on 32-bit systems in year 2038 and beyond.
2. Improved resolution: nsecs instead of usecs.
3. Reduced compute: ktime_get_ns is faster than the multiply/add
   combination used in this function

Linux-commit: 9056be30542bfff51190bdda67088f319cf4c9f5

Drop unneeded wrapper function Remove the function
lnet_create_interface_cookie() and replace its call
with the function ktime_get_ns().

Linux-commit: 7bcd831b8579212303ec7c30e975432b914493dc

The ln_interface_cookie is used to ensure that a node can tell whether
the following sequence of events has happened:

node sends GET or PUT to peer
node is rebooted
peer sends REPLY or ACK to node

The ln_interface_cookie is set once, when LNet starts, and remains
unchanged afterwards. To avoid accidentally obtaining the same cookie
after a reboot, the code generated ths cookie using ktime_get_ns().
Once generated, the value of the cookie is not interpreted, only
compared for equality. Olaf Weber reported that due to the use of
ktime_get_ns() a small chance exist of generating a cookie of identical
value across reboots. Using ktime_get_real_ns() removes any chance of
this from happening.

Change-Id: I159a0ff2573afb87f279a8e8f282b0ac076d9bf3
Signed-off-by: Tina Ruchandani <ruchandani.tina@gmail.com>
Signed-off-by: Shivani Bhardwaj <shivanib134@gmail.com>
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-on: https://review.whamcloud.com/24682
Reviewed-by: Doug Oucharek <doug.s.oucharek@intel.com>
Reviewed-by: Olaf Weber <olaf@sgi.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Dmitry Eremin <dmitry.eremin@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
libcfs/autoconf/lustre-libcfs.m4
libcfs/include/libcfs/linux/linux-time.h
lnet/lnet/api-ni.c

index 95b25c0..3740297 100644 (file)
@@ -365,6 +365,23 @@ ktime_get_real_seconds, [
 ]) # LIBCFS_KTIME_GET_REAL_SECONDS
 
 #
 ]) # LIBCFS_KTIME_GET_REAL_SECONDS
 
 #
+# Kernel version 3.17 created ktime_get_ns wrapper
+#
+AC_DEFUN([LIBCFS_KTIME_GET_REAL_NS],[
+LB_CHECK_COMPILE([does function 'ktime_get_real_ns' exist],
+ktime_get_ns, [
+       #include <linux/ktime.h>
+],[
+       u64 nanoseconds;
+
+       nanoseconds = ktime_get_real_ns();
+],[
+       AC_DEFINE(HAVE_KTIME_GET_REAL_NS, 1,
+               ['ktime_get_real_ns' is available])
+])
+]) # LIBCFS_KTIME_GET_REAL_NS
+
+#
 # Kernel version 3.19 introduced ktime_get_seconds
 #
 AC_DEFUN([LIBCFS_KTIME_GET_SECONDS],[
 # Kernel version 3.19 introduced ktime_get_seconds
 #
 AC_DEFUN([LIBCFS_KTIME_GET_SECONDS],[
@@ -505,6 +522,7 @@ LIBCFS_HLIST_ADD_AFTER
 LIBCFS_TIMESPEC64
 LIBCFS_KTIME_GET_REAL_TS64
 LIBCFS_KTIME_GET_REAL_SECONDS
 LIBCFS_TIMESPEC64
 LIBCFS_KTIME_GET_REAL_TS64
 LIBCFS_KTIME_GET_REAL_SECONDS
+LIBCFS_KTIME_GET_REAL_NS
 # 3.19
 LIBCFS_KTIME_GET_SECONDS
 # 4.2
 # 3.19
 LIBCFS_KTIME_GET_SECONDS
 # 4.2
index e65d2f7..bf403ff 100644 (file)
@@ -145,6 +145,13 @@ time64_t ktime_get_real_seconds(void);
 time64_t ktime_get_seconds(void);
 #endif /* HAVE_KTIME_GET_SECONDS */
 
 time64_t ktime_get_seconds(void);
 #endif /* HAVE_KTIME_GET_SECONDS */
 
+#ifndef HAVE_KTIME_GET_REAL_NS
+static inline u64 ktime_get_real_ns(void)
+{
+       return ktime_to_ns(ktime_get_real());
+}
+#endif /* HAVE_KTIME_GET_NS */
+
 static inline int cfs_time_before(cfs_time_t t1, cfs_time_t t2)
 {
         return time_before(t1, t2);
 static inline int cfs_time_before(cfs_time_t t1, cfs_time_t t2)
 {
         return time_before(t1, t2);
index 16465b5..270629d 100644 (file)
@@ -32,6 +32,8 @@
 
 #define DEBUG_SUBSYSTEM S_LNET
 #include <linux/log2.h>
 
 #define DEBUG_SUBSYSTEM S_LNET
 #include <linux/log2.h>
+#include <linux/ktime.h>
+
 #include <lnet/lib-lnet.h>
 
 #define D_LNI D_CONSOLE
 #include <lnet/lib-lnet.h>
 
 #define D_LNI D_CONSOLE
@@ -396,21 +398,6 @@ lnet_counters_reset(void)
        lnet_net_unlock(LNET_LOCK_EX);
 }
 
        lnet_net_unlock(LNET_LOCK_EX);
 }
 
-static __u64 lnet_create_interface_cookie(void)
-{
-       /* NB the interface cookie in wire handles guards against delayed
-        * replies and ACKs appearing valid after reboot. Initialisation time,
-        * even if it's only implemented to millisecond resolution is probably
-        * easily good enough. */
-       struct timeval tv;
-       __u64          cookie;
-       do_gettimeofday(&tv);
-       cookie = tv.tv_sec;
-       cookie *= 1000000;
-       cookie += tv.tv_usec;
-       return cookie;
-}
-
 static char *
 lnet_res_type2str(int type)
 {
 static char *
 lnet_res_type2str(int type)
 {
@@ -612,7 +599,11 @@ lnet_prepare(lnet_pid_t requested_pid)
        if (rc != 0)
                goto failed;
 
        if (rc != 0)
                goto failed;
 
-       the_lnet.ln_interface_cookie = lnet_create_interface_cookie();
+       /*
+        * NB the interface cookie in wire handles guards against delayed
+        * replies and ACKs appearing valid after reboot.
+        */
+       the_lnet.ln_interface_cookie = ktime_get_real_ns();
 
        the_lnet.ln_counters = cfs_percpt_alloc(lnet_cpt_table(),
                                                sizeof(lnet_counters_t));
 
        the_lnet.ln_counters = cfs_percpt_alloc(lnet_cpt_table(),
                                                sizeof(lnet_counters_t));