File 0015-LU-13344-lnet-stop-using-struct-timeval.patch of Package lustre_2_12

From 5b1422c99ce6a2350f1ad6426a7f13915649361a Mon Sep 17 00:00:00 2001
From: James Simmons <jsimmons@infradead.org>
Date: Wed, 6 May 2020 17:41:58 -0400
Subject: [PATCH 15/35] LU-13344 lnet: stop using struct timeval

The struct timeval is not 2038 safe so the Linux kernel is moving
away from its use. The use of rpe_stamp hasn't been used since
Lustre 2.2 so remove the userland use of this field. This frees
use to change rpe_stamp to an equivalent struct timespec64 for
future use. Greatly simplify lnet_sock_[read|write] by using
jiffies values of sk_sndtimeo, sk_rcvtimeo cached in struct sock.

Change-Id: Ib58193756ec4a526e55bc810c05abd3920b2b269
Signed-off-by: James Simmons <jsimmons@infradead.org>
Reviewed-on: https://review.whamcloud.com/38105
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Tested-by: Maloo <maloo@whamcloud.com>
---
 libcfs/autoconf/lustre-libcfs.m4              | 21 +++++++
 libcfs/include/libcfs/linux/linux-time.h      | 20 +++++++
 lnet/include/uapi/linux/lnet/lnetst.h         |  8 ++-
 lnet/lnet/lib-socket.c                        | 55 ++++++-------------
 lnet/selftest/conctl.c                        |  1 -
 lnet/selftest/conrpc.c                        |  6 +-
 lnet/selftest/conrpc.h                        |  1 -
 lnet/selftest/console.h                       |  1 -
 lnet/utils/lst.c                              | 45 ++++-----------
 .../include/uapi/linux/lustre/lustre_user.h   |  2 +-
 10 files changed, 78 insertions(+), 82 deletions(-)

diff --git a/libcfs/autoconf/lustre-libcfs.m4 b/libcfs/autoconf/lustre-libcfs.m4
index 4b40e3e64c8e..c5d31ac92e39 100644
--- a/libcfs/autoconf/lustre-libcfs.m4
+++ b/libcfs/autoconf/lustre-libcfs.m4
@@ -445,6 +445,26 @@ LB_CHECK_LINUX_HEADER([linux/rhashtable.h], [
 ])
 ]) # LIBCFS_LINUX_RHASHTABLE_H
 
+#
+# LIBCFS_HAVE_NS_TO_TIMESPEC64
+#
+# Kernel version 4.16-rc3 commit a84d1169164b274f13b97a23ff235c000efe3b49
+# introduced struct __kernel_old_timeval
+#
+AC_DEFUN([LIBCFS_HAVE_NS_TO_TIMESPEC64],[
+LB_CHECK_COMPILE([does 'ns_to_timespec64()' exist],
+kernel_old_timeval, [
+	#include <linux/time.h>
+],[
+	struct timespec64 kts;
+
+	kts = ns_to_timespec64(0);
+],[
+	AC_DEFINE(HAVE_NS_TO_TIMESPEC64, 1,
+		[ns_to_timespec64() is available])
+])
+]) # LIBCFS_HAVE_NS_TO_TIMESPEC64
+
 #
 # Kernel version 3.17 changed hlist_add_after to
 # hlist_add_behind
@@ -1324,6 +1344,7 @@ LIBCFS_SHRINKER_COUNT
 LIBCFS_IOV_ITER_HAS_TYPE
 # 3.16
 LIBCFS_LINUX_RHASHTABLE_H
+LIBCFS_HAVE_NS_TO_TIMESPEC64
 # 3.17
 LIBCFS_HLIST_ADD_AFTER
 LIBCFS_TIMESPEC64
diff --git a/libcfs/include/libcfs/linux/linux-time.h b/libcfs/include/libcfs/linux/linux-time.h
index 5af8134221c5..3934635dcd32 100644
--- a/libcfs/include/libcfs/linux/linux-time.h
+++ b/libcfs/include/libcfs/linux/linux-time.h
@@ -98,6 +98,26 @@ static inline struct timespec timespec64_to_timespec(const struct timespec64 ts6
 
 #endif /* HAVE_TIMESPEC64 */
 
+#ifndef HAVE_NS_TO_TIMESPEC64
+static inline struct timespec64 ns_to_timespec64(const s64 nsec)
+{
+	struct timespec64 ts;
+	s32 rem;
+
+	if (!nsec)
+		return (struct timespec64) {0, 0};
+
+	ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);
+	if (unlikely(rem < 0)) {
+		ts.tv_sec--;
+		rem += NSEC_PER_SEC;
+	}
+	ts.tv_nsec = rem;
+
+	return ts;
+}
+#endif
+
 #ifndef HAVE_KTIME_ADD
 # define ktime_add(lhs, rhs) ({ (ktime_t){ .tv64 = (lhs).tv64 + (rhs).tv64 }; })
 #endif /* !HAVE_KTIME_ADD */
diff --git a/lnet/include/uapi/linux/lnet/lnetst.h b/lnet/include/uapi/linux/lnet/lnetst.h
index 804e5e846a38..ca871cac02b7 100644
--- a/lnet/include/uapi/linux/lnet/lnetst.h
+++ b/lnet/include/uapi/linux/lnet/lnetst.h
@@ -120,7 +120,13 @@ struct lstcon_test_batch_ent {
 struct lstcon_rpc_ent {
 	struct list_head	rpe_link;		/* link chain */
 	struct lnet_process_id	rpe_peer;		/* peer's id */
-	struct timeval		rpe_stamp;		/* time stamp of RPC */
+	/* This has not been used since Lustre 2.2 so its safe to use.
+	 * Update to allow future use of timespec64
+	 */
+	struct {
+		__s64		tv_sec;
+		__s64		tv_nsec;
+	} rpe_stamp;					/* time stamp of RPC */
 	int			rpe_state;		/* peer's state */
 	int			rpe_rpc_errno;		/* RPC errno */
 
diff --git a/lnet/lnet/lib-socket.c b/lnet/lnet/lib-socket.c
index fe532c3f0e08..f78866f8d66a 100644
--- a/lnet/lnet/lib-socket.c
+++ b/lnet/lnet/lib-socket.c
@@ -40,16 +40,16 @@
 #include <linux/syscalls.h>
 #include <net/sock.h>
 
+#include <libcfs/linux/linux-time.h>
 #include <libcfs/libcfs.h>
 #include <lnet/lib-lnet.h>
 
 int
 lnet_sock_write(struct socket *sock, void *buffer, int nob, int timeout)
 {
-	int		rc;
-	long		jiffies_left = timeout * msecs_to_jiffies(MSEC_PER_SEC);
-	unsigned long	then;
-	struct timeval	tv;
+	int rc;
+	long jiffies_left = timeout * msecs_to_jiffies(MSEC_PER_SEC);
+	unsigned long then;
 
 	LASSERT(nob > 0);
 	/* Caller may pass a zero timeout if she thinks the socket buffer is
@@ -65,24 +65,12 @@ lnet_sock_write(struct socket *sock, void *buffer, int nob, int timeout)
 		};
 
 		if (timeout != 0) {
+			struct sock *sk = sock->sk;
+
 			/* Set send timeout to remaining time */
-			tv = (struct timeval) {
-				.tv_sec = jiffies_left /
-					  msecs_to_jiffies(MSEC_PER_SEC),
-				.tv_usec = ((jiffies_left %
-					     msecs_to_jiffies(MSEC_PER_SEC)) *
-					     USEC_PER_SEC) /
-					     msecs_to_jiffies(MSEC_PER_SEC)
-			};
-
-			rc = kernel_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO,
-					       (char *)&tv, sizeof(tv));
-			if (rc != 0) {
-				CERROR("Can't set socket send timeout "
-				       "%ld.%06d: %d\n",
-				       (long)tv.tv_sec, (int)tv.tv_usec, rc);
-				return rc;
-			}
+			lock_sock(sk);
+			sk->sk_sndtimeo = jiffies_left;
+			release_sock(sk);
 		}
 
 		then = jiffies;
@@ -113,10 +101,9 @@ EXPORT_SYMBOL(lnet_sock_write);
 int
 lnet_sock_read(struct socket *sock, void *buffer, int nob, int timeout)
 {
-	int		rc;
-	long		jiffies_left = timeout * msecs_to_jiffies(MSEC_PER_SEC);
-	unsigned long	then;
-	struct timeval	tv;
+	int rc;
+	long jiffies_left = timeout * msecs_to_jiffies(MSEC_PER_SEC);
+	unsigned long then;
 
 	LASSERT(nob > 0);
 	LASSERT(jiffies_left > 0);
@@ -129,22 +116,12 @@ lnet_sock_read(struct socket *sock, void *buffer, int nob, int timeout)
 		struct msghdr msg = {
 			.msg_flags	= 0
 		};
+		struct sock *sk = sock->sk;
 
 		/* Set receive timeout to remaining time */
-		tv = (struct timeval) {
-			.tv_sec = jiffies_left / msecs_to_jiffies(MSEC_PER_SEC),
-			.tv_usec = ((jiffies_left %
-					msecs_to_jiffies(MSEC_PER_SEC)) *
-					USEC_PER_SEC) /
-					msecs_to_jiffies(MSEC_PER_SEC)
-		};
-		rc = kernel_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
-				       (char *)&tv, sizeof(tv));
-		if (rc != 0) {
-			CERROR("Can't set socket recv timeout %ld.%06d: %d\n",
-			       (long)tv.tv_sec, (int)tv.tv_usec, rc);
-			return rc;
-		}
+		lock_sock(sk);
+		sk->sk_rcvtimeo = jiffies_left;
+		release_sock(sk);
 
 		then = jiffies;
 		rc = kernel_recvmsg(sock, &msg, &iov, 1, nob, 0);
diff --git a/lnet/selftest/conctl.c b/lnet/selftest/conctl.c
index 642a878d3dd4..7ce53bbabff3 100644
--- a/lnet/selftest/conctl.c
+++ b/lnet/selftest/conctl.c
@@ -38,7 +38,6 @@
 
 #include <libcfs/libcfs.h>
 #include <lnet/lib-lnet.h>
-#include <uapi/linux/lnet/lnetst.h>
 #include "console.h"
 
 static int
diff --git a/lnet/selftest/conrpc.c b/lnet/selftest/conrpc.c
index e5d7787932fa..b39756f724a2 100644
--- a/lnet/selftest/conrpc.c
+++ b/lnet/selftest/conrpc.c
@@ -473,7 +473,7 @@ lstcon_rpc_trans_interpreter(struct lstcon_rpc_trans *trans,
 	struct lstcon_rpc *crpc;
 	struct srpc_msg *msg;
 	struct lstcon_node *nd;
-	struct timeval tv;
+	struct timespec64 ts;
 	int error;
 	s64 dur;
 
@@ -501,11 +501,11 @@ lstcon_rpc_trans_interpreter(struct lstcon_rpc_trans *trans,
 
 		dur = crpc->crp_stamp_ns -
 		      console_session.ses_id.ses_stamp * NSEC_PER_MSEC;
-		tv = ns_to_timeval(dur);
+		ts = ns_to_timespec64(dur);
 
 		if (copy_to_user(&ent->rpe_peer,
 				 &nd->nd_id, sizeof(struct lnet_process_id)) ||
-		    copy_to_user(&ent->rpe_stamp, &tv, sizeof(tv)) ||
+		    copy_to_user(&ent->rpe_stamp, &ts, sizeof(ts)) ||
 		    copy_to_user(&ent->rpe_state,
 				 &nd->nd_state, sizeof(nd->nd_state)) ||
 		    copy_to_user(&ent->rpe_rpc_errno, &error,
diff --git a/lnet/selftest/conrpc.h b/lnet/selftest/conrpc.h
index 6eaeaa7c4cd3..51d4ee90e07c 100644
--- a/lnet/selftest/conrpc.h
+++ b/lnet/selftest/conrpc.h
@@ -41,7 +41,6 @@
 
 #include <libcfs/libcfs.h>
 #include <lnet/lib-types.h>
-#include <uapi/linux/lnet/lnetst.h>
 #include "rpc.h"
 #include "selftest.h"
 
diff --git a/lnet/selftest/console.h b/lnet/selftest/console.h
index 09cd0e86fa50..02c76a89627e 100644
--- a/lnet/selftest/console.h
+++ b/lnet/selftest/console.h
@@ -43,7 +43,6 @@
 
 #include <libcfs/libcfs.h>
 #include <lnet/lib-types.h>
-#include <uapi/linux/lnet/lnetst.h>
 #include "selftest.h"
 #include "conrpc.h"
 
diff --git a/lnet/utils/lst.c b/lnet/utils/lst.c
index 6c8aaead3162..adabb339760c 100644
--- a/lnet/utils/lst.c
+++ b/lnet/utils/lst.c
@@ -44,6 +44,7 @@
 #include <string.h>
 #include <sys/ioctl.h>
 #include <time.h>
+#include <linux/types.h>
 
 #include <libcfs/util/list.h>
 #include <libcfs/util/ioctl.h>
@@ -1629,22 +1630,6 @@ lst_lnet_stat_value(int bw, int send, int off)
         return *p;
 }
 
-static void
-lst_timeval_diff(struct timeval *tv1,
-		 struct timeval *tv2, struct timeval *df)
-{
-	if (tv1->tv_usec >= tv2->tv_usec) {
-		df->tv_sec  = tv1->tv_sec - tv2->tv_sec;
-		df->tv_usec = tv1->tv_usec - tv2->tv_usec;
-		return;
-	}
-
-	df->tv_sec  = tv1->tv_sec - 1 - tv2->tv_sec;
-	df->tv_usec = tv1->tv_usec + 1000000 - tv2->tv_usec;
-
-	return;
-}
-
 static void
 lst_cal_lnet_stat(float delta, struct lnet_counters_common *lnet_new,
 		  struct lnet_counters_common *lnet_old, int mbs)
@@ -1835,26 +1820,16 @@ lst_print_stat(char *name, struct list_head *resultp,
 		lnet_old = (struct lnet_counters_common *)((char *)srpc_old +
 							   sizeof(*srpc_old));
 
-		/* Prior to version 2.3, the running_ms field was a counter for
-		 * the number of running tests.  We are looking at this value
-		 * to determine if it is a millisecond timestamep (>= 2.3) or a
-		 * test counter (< 2.3).  The number 500 is being used for this
-		 * barrier as the test counter should never get this high, and
-		 * the timestamp should never get this low.
+		/* Prior to version 2.3, the running_ms was a counter for
+		 * the number of running tests. Since 2.3, running_ms is
+		 * changed to hold the millisecond since the start of
+		 * the work item. The rpe_stamp field was formerly used,
+		 * but is no longer. In 2.12 rpe_stamp was changed to
+		 * struct timespec64 and has nanosecond resolution, in
+		 * case it is needed in the future.
 		 */
-		if (sfwk_new->running_ms > 500) {
-			/* use the timestamp from the remote node, not our
-			 * rpe_stamp from when we copied up the data out of
-			 * the kernel.
-			 */
-			delta = (float)(sfwk_new->running_ms -
-					sfwk_old->running_ms) / 1000;
-		} else {
-			struct timeval tv;
-
-			lst_timeval_diff(&new->rpe_stamp, &old->rpe_stamp, &tv);
-			delta = tv.tv_sec + (float)tv.tv_usec / 1000000;
-		}
+		delta = (float)(sfwk_new->running_ms -
+				sfwk_old->running_ms) / 1000;
 
 		if (!lnet) /* TODO */
 			continue;
diff --git a/lustre/include/uapi/linux/lustre/lustre_user.h b/lustre/include/uapi/linux/lustre/lustre_user.h
index 055542cb8546..ec8fbd1de686 100644
--- a/lustre/include/uapi/linux/lustre/lustre_user.h
+++ b/lustre/include/uapi/linux/lustre/lustre_user.h
@@ -1134,7 +1134,7 @@ struct identity_downcall_data {
 
 struct sepol_downcall_data {
 	__u32		sdd_magic;
-	__kernel_time_t	sdd_sepol_mtime;
+	__s64		sdd_sepol_mtime;
 	__u16		sdd_sepol_len;
 	char		sdd_sepol[0];
 };
-- 
2.41.0

openSUSE Build Service is sponsored by