diff mbox series

[05/12] lnet: Allow specifying a source NID for lnetctl ping

Message ID 1639321683-22909-6-git-send-email-jsimmons@infradead.org (mailing list archive)
State New, archived
Headers show
Series lustre: backport OpenSFS work Dec 12, 2021 | expand

Commit Message

James Simmons Dec. 12, 2021, 3:07 p.m. UTC
From: Chris Horn <chris.horn@hpe.com>

Add a new --source option for lnetctl ping command. This allows the
user to specify a local NI from which to send the ping. This also
ensures that the specified destination NID is also used. Otherwise,
pings to multi-rail peers may end up going to a different peer NI
based on the multi-rail selection algorithm. The ability to specify
a source NI, and thus fix the destination NI, is a great help in
troubleshooting communication issues between multi-rail peers.

Add test to exercise lnetctl ping --source option.

HPE-bug-id: LUS-10296
WC-bug-id: https://jira.whamcloud.com/browse/LU-14939
Lustre-commit: 48ef9982c474a02c4 ("LU-14939 lnet: Allow specifying a source NID for lnetctl ping")
Signed-off-by: Chris Horn <chris.horn@hpe.com>
Reviewed-on: https://review.whamcloud.com/44727
Reviewed-by: Serguei Smirnov <ssmirnov@whamcloud.com>
Reviewed-by: Andriy Skulysh <andriy.skulysh@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Signed-off-by: James Simmons <jsimmons@infradead.org>
---
 include/uapi/linux/lnet/lnet-dlc.h |  1 +
 net/lnet/lnet/api-ni.c             | 29 ++++++++++++++++++++++-------
 2 files changed, 23 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/include/uapi/linux/lnet/lnet-dlc.h b/include/uapi/linux/lnet/lnet-dlc.h
index 2ca70eb..415968a 100644
--- a/include/uapi/linux/lnet/lnet-dlc.h
+++ b/include/uapi/linux/lnet/lnet-dlc.h
@@ -132,6 +132,7 @@  struct lnet_ioctl_ping_data {
 	__u32 mr_info;
 	struct lnet_process_id ping_id;
 	struct lnet_process_id __user *ping_buf;
+	lnet_nid_t ping_src;
 };
 
 struct lnet_ioctl_config_data {
diff --git a/net/lnet/lnet/api-ni.c b/net/lnet/lnet/api-ni.c
index 3ed3f0b..550f035 100644
--- a/net/lnet/lnet/api-ni.c
+++ b/net/lnet/lnet/api-ni.c
@@ -205,8 +205,9 @@  static void lnet_set_lnd_timeout(void)
  */
 static atomic_t lnet_dlc_seq_no = ATOMIC_INIT(0);
 
-static int lnet_ping(struct lnet_process_id id, signed long timeout,
-		     struct lnet_process_id __user *ids, int n_ids);
+static int lnet_ping(struct lnet_process_id id, lnet_nid_t src_nid,
+		     signed long timeout, struct lnet_process_id __user *ids,
+		     int n_ids);
 
 static int lnet_discover(struct lnet_process_id id, u32 force,
 			 struct lnet_process_id __user *ids, int n_ids);
@@ -4267,7 +4268,7 @@  u32 lnet_get_dlc_seq_locked(void)
 		else
 			timeout = msecs_to_jiffies(data->ioc_u32[1]);
 
-		rc = lnet_ping(id, timeout, data->ioc_pbuf1,
+		rc = lnet_ping(id, LNET_NID_ANY, timeout, data->ioc_pbuf1,
 			       data->ioc_plen1 / sizeof(struct lnet_process_id));
 
 		if (rc < 0)
@@ -4281,6 +4282,19 @@  u32 lnet_get_dlc_seq_locked(void)
 		struct lnet_ioctl_ping_data *ping = arg;
 		struct lnet_peer *lp;
 		signed long timeout;
+		lnet_nid_t src_nid = LNET_NID_ANY;
+
+		/* Check if the supplied ping data supports source nid
+		 * NB: This check is sufficient if lnet_ioctl_ping_data has
+		 * additional fields added, but if they are re-ordered or
+		 * fields removed then this will break. It is expected that
+		 * these ioctls will be replaced with netlink implementation, so
+		 * it is probably not worth coming up with a more robust version
+		 * compatibility scheme.
+		 */
+		if (ping->ping_hdr.ioc_len >=
+		    sizeof(struct lnet_ioctl_ping_data))
+			src_nid = ping->ping_src;
 
 		/* If timeout is negative then set default of 3 minutes */
 		if (((s32)ping->op_param) <= 0 ||
@@ -4289,7 +4303,7 @@  u32 lnet_get_dlc_seq_locked(void)
 		else
 			timeout = msecs_to_jiffies(ping->op_param);
 
-		rc = lnet_ping(ping->ping_id, timeout,
+		rc = lnet_ping(ping->ping_id, src_nid, timeout,
 			       ping->ping_buf,
 			       ping->ping_count);
 		if (rc < 0)
@@ -4526,8 +4540,9 @@  struct ping_data {
 		complete(&pd->completion);
 }
 
-static int lnet_ping(struct lnet_process_id id, signed long timeout,
-		     struct lnet_process_id __user *ids, int n_ids)
+static int lnet_ping(struct lnet_process_id id, lnet_nid_t src_nid,
+		     signed long timeout, struct lnet_process_id __user *ids,
+		     int n_ids)
 {
 	struct lnet_md md = { NULL };
 	struct ping_data pd = { 0 };
@@ -4572,7 +4587,7 @@  static int lnet_ping(struct lnet_process_id id, signed long timeout,
 		goto fail_ping_buffer_decref;
 	}
 
-	rc = LNetGet(LNET_NID_ANY, pd.mdh, id,
+	rc = LNetGet(src_nid, pd.mdh, id,
 		     LNET_RESERVED_PORTAL,
 		     LNET_PROTO_PING_MATCHBITS, 0, false);
 	if (rc) {