Whamcloud - gitweb
LU-10391 socklnd: add hello message version 4 11/43611/10
authorMr NeilBrown <neilb@suse.de>
Tue, 28 Apr 2020 04:57:09 +0000 (14:57 +1000)
committerOleg Drokin <green@whamcloud.com>
Wed, 26 Jan 2022 05:13:27 +0000 (05:13 +0000)
KSOCK_PROTO_V4 uses a 'hello' message that contains
lnet_hdr_nid16 with 16 byte addresses

Test-Parameters: trivial
Test-Parameters: serverversion=2.12 serverdistro=el7.9 testlist=runtests
Test-Parameters: clientversion=2.12 testlist=runtests
Signed-off-by: Mr NeilBrown <neilb@suse.de>
Change-Id: I52a36739d3a84dc059537059a586ce3dab2b20f0
Reviewed-on: https://review.whamcloud.com/43611
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Serguei Smirnov <ssmirnov@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lnet/include/lnet/lib-lnet.h
lnet/include/lnet/socklnd.h
lnet/include/uapi/linux/lnet/lnet-types.h
lnet/klnds/socklnd/socklnd.h
lnet/klnds/socklnd/socklnd_cb.c
lnet/klnds/socklnd/socklnd_proto.c

index e4658a8..7d11672 100644 (file)
@@ -547,6 +547,32 @@ static inline void lnet_hdr_to_nid4(const struct lnet_hdr *hdr,
        hdr_nid4->msg = hdr->msg;
 }
 
+static inline void lnet_hdr_from_nid16(struct lnet_hdr *hdr,
+                                       const struct lnet_hdr_nid16 *vhdr)
+{
+       const struct lnet_hdr *hdr16 = (void *)vhdr;
+
+       hdr->dest_nid = hdr16->dest_nid;
+       hdr->src_nid = hdr16->src_nid;
+       hdr->dest_pid = le32_to_cpu(hdr16->dest_pid);
+       hdr->src_pid = le32_to_cpu(hdr16->src_pid);
+       hdr->type = le32_to_cpu(hdr16->type);
+       hdr->payload_length = le32_to_cpu(hdr16->payload_length);
+}
+
+static inline void lnet_hdr_to_nid16(const struct lnet_hdr *hdr,
+                                     struct lnet_hdr_nid16 *vhdr)
+{
+       struct lnet_hdr *hdr16 = (void *)vhdr;
+
+       hdr16->dest_nid = hdr->dest_nid;
+       hdr16->src_nid = hdr->src_nid;
+       hdr16->dest_pid = cpu_to_le32(hdr->dest_pid);
+       hdr16->src_pid = cpu_to_le32(hdr->src_pid);
+       hdr16->type = cpu_to_le32(hdr->type);
+       hdr16->payload_length = cpu_to_le32(hdr->payload_length);
+}
+
 extern const struct lnet_lnd the_lolnd;
 extern int avoid_asym_router_failure;
 
index 22e60ed..ff1fe23 100644 (file)
@@ -80,6 +80,10 @@ struct ksock_msg {
                /* - nothing */
                /* case ksm_kh.ksh_type == KSOCK_MSG_LNET */
                struct lnet_hdr_nid4 lnetmsg_nid4;
+               /* case ksm_kh.ksh_type == KSOCK_MSG_LNET &&
+                *      kshm_version >= KSOCK_PROTO_V4
+                */
+               struct lnet_hdr_nid16 lnetmsg_nid16;
        } __packed ksm_u;
 } __packed;
 #define ksm_type ksm_kh.ksh_type
@@ -90,5 +94,6 @@ struct ksock_msg {
  * other LND (usocklnd, for example) */
 #define KSOCK_PROTO_V2         2
 #define KSOCK_PROTO_V3         3
+#define KSOCK_PROTO_V4         4
 
 #endif
index 02f1bb6..ff02f24 100644 (file)
@@ -307,6 +307,10 @@ enum lnet_ins_pos {
 /** \addtogroup lnet_md
  * @{ */
 
+struct lnet_hdr_nid16 {
+       char    _bytes[sizeof(struct lnet_hdr)];
+} __attribute__((packed));
+
 /**
  * Event queue handler function type.
  *
index 7ce64a4..81db1c3 100644 (file)
@@ -450,6 +450,7 @@ struct ksock_proto {
 extern const struct ksock_proto ksocknal_protocol_v1x;
 extern const struct ksock_proto ksocknal_protocol_v2x;
 extern const struct ksock_proto ksocknal_protocol_v3x;
+extern const struct ksock_proto ksocknal_protocol_v4x;
 
 #define KSOCK_PROTO_V1_MAJOR    LNET_PROTO_TCP_VERSION_MAJOR
 #define KSOCK_PROTO_V1_MINOR    LNET_PROTO_TCP_VERSION_MINOR
index fe3e6cb..2f7fc2a 100644 (file)
@@ -2046,7 +2046,8 @@ ksocknal_connect(struct ksock_conn_cb *conn_cb)
                conn = list_first_entry_or_null(&peer_ni->ksnp_conns,
                                                struct ksock_conn, ksnc_list);
                if (conn)
-                       LASSERT(conn->ksnc_proto == &ksocknal_protocol_v3x);
+                       LASSERT(conn->ksnc_proto == &ksocknal_protocol_v3x ||
+                               conn->ksnc_proto == &ksocknal_protocol_v4x);
 
                /* take all the blocked packets while I've got the lock and
                 * complete below...
@@ -2411,8 +2412,9 @@ __must_hold(&ksocknal_data.ksnd_global_lock)
        if (list_empty(&peer_ni->ksnp_conns))
                 return 0;
 
-        if (peer_ni->ksnp_proto != &ksocknal_protocol_v3x)
-                return 0;
+       if (peer_ni->ksnp_proto != &ksocknal_protocol_v3x &&
+           peer_ni->ksnp_proto != &ksocknal_protocol_v4x)
+               return 0;
 
         if (*ksocknal_tunables.ksnd_keepalive <= 0 ||
            ktime_get_seconds() < peer_ni->ksnp_last_alive +
index 789c4d5..40a1ffb 100644 (file)
@@ -361,6 +361,51 @@ ksocknal_match_tx_v3(struct ksock_conn *conn, struct ksock_tx *tx, int nonblk)
         }
 }
 
+static int
+ksocknal_match_tx_v4(struct ksock_conn *conn, struct ksock_tx *tx, int nonblk)
+{
+       int nob;
+
+       if (!tx || !tx->tx_lnetmsg)
+               nob = sizeof(struct ksock_msg_hdr);
+       else
+               nob = sizeof(struct ksock_msg_hdr) +
+                       sizeof(struct lnet_hdr_nid16) +
+                       tx->tx_lnetmsg->msg_len;
+
+       switch (conn->ksnc_type) {
+       default:
+               CERROR("ksnc_type bad: %u\n", conn->ksnc_type);
+               LBUG();
+       case SOCKLND_CONN_ANY:
+               return SOCKNAL_MATCH_NO;
+
+       case SOCKLND_CONN_ACK:
+               if (nonblk)
+                       return SOCKNAL_MATCH_YES;
+               else if (tx == NULL || tx->tx_lnetmsg == NULL)
+                       return SOCKNAL_MATCH_MAY;
+               else
+                       return SOCKNAL_MATCH_NO;
+
+       case SOCKLND_CONN_BULK_OUT:
+               if (nonblk)
+                       return SOCKNAL_MATCH_NO;
+               else if (nob < *ksocknal_tunables.ksnd_min_bulk)
+                       return SOCKNAL_MATCH_MAY;
+               else
+                       return SOCKNAL_MATCH_YES;
+
+       case SOCKLND_CONN_CONTROL:
+               if (nonblk)
+                       return SOCKNAL_MATCH_NO;
+               else if (nob >= *ksocknal_tunables.ksnd_min_bulk)
+                       return SOCKNAL_MATCH_MAY;
+               else
+                       return SOCKNAL_MATCH_YES;
+       }
+}
+
 /* (Sink) handle incoming ZC request from sender */
 static int
 ksocknal_handle_zcreq(struct ksock_conn *c, __u64 cookie, int remote)
@@ -420,11 +465,12 @@ ksocknal_handle_zcack(struct ksock_conn *conn, __u64 cookie1, __u64 cookie2)
 
         count = (cookie1 > cookie2) ? 2 : (cookie2 - cookie1 + 1);
 
-        if (cookie2 == SOCKNAL_KEEPALIVE_PING &&
-            conn->ksnc_proto == &ksocknal_protocol_v3x) {
-                /* keepalive PING for V3.x, just ignore it */
-                return count == 1 ? 0 : -EPROTO;
-        }
+       if (cookie2 == SOCKNAL_KEEPALIVE_PING &&
+           (conn->ksnc_proto == &ksocknal_protocol_v3x ||
+            conn->ksnc_proto == &ksocknal_protocol_v4x)) {
+               /* keepalive PING for V3.x, just ignore it */
+               return count == 1 ? 0 : -EPROTO;
+       }
 
        spin_lock(&peer_ni->ksnp_lock);
 
@@ -590,6 +636,24 @@ ksocknal_send_hello_v2(struct ksock_conn *conn, struct ksock_hello_msg *hello)
 }
 
 static int
+ksocknal_send_hello_v4(struct ksock_conn *conn, struct ksock_hello_msg *hello)
+{
+       struct socket *sock = conn->ksnc_sock;
+       int rc;
+
+       hello->kshm_magic   = LNET_PROTO_MAGIC;
+       hello->kshm_version = conn->ksnc_proto->pro_version;
+
+       rc = lnet_sock_write(sock, hello, sizeof(*hello),
+                            lnet_acceptor_timeout());
+
+       if (rc != 0)
+               CNETERR("Error %d sending HELLO hdr to %pISp\n",
+                       rc, &conn->ksnc_peeraddr);
+       return rc;
+}
+
+static int
 ksocknal_recv_hello_v1(struct ksock_conn *conn, struct ksock_hello_msg *hello,
                       int timeout)
 {
@@ -744,6 +808,40 @@ ksocknal_recv_hello_v2(struct ksock_conn *conn, struct ksock_hello_msg *hello,
        return 0;
 }
 
+static int
+ksocknal_recv_hello_v4(struct ksock_conn *conn, struct ksock_hello_msg *hello,
+                      int timeout)
+{
+       struct socket *sock = conn->ksnc_sock;
+       int rc;
+
+       if (hello->kshm_magic == LNET_PROTO_MAGIC)
+               conn->ksnc_flip = 0;
+       else
+               conn->ksnc_flip = 1;
+
+       rc = lnet_sock_read(sock, &hello->kshm_src_nid,
+                           sizeof(*hello) -
+                           offsetof(struct ksock_hello_msg, kshm_src_nid),
+                           timeout);
+       if (rc) {
+               CERROR("Error %d reading HELLO from %pIS\n",
+                      rc, &conn->ksnc_peeraddr);
+               LASSERT(rc < 0 && rc != -EALREADY);
+               return rc;
+       }
+
+       if (conn->ksnc_flip) {
+               __swab32s(&hello->kshm_src_pid);
+               __swab32s(&hello->kshm_dst_pid);
+               __swab64s(&hello->kshm_src_incarnation);
+               __swab64s(&hello->kshm_dst_incarnation);
+               __swab32s(&hello->kshm_ctype);
+       }
+
+       return 0;
+}
+
 static void
 ksocknal_pack_msg_v1(struct ksock_tx *tx)
 {
@@ -794,6 +892,39 @@ ksocknal_pack_msg_v2(struct ksock_tx *tx)
 }
 
 static void
+ksocknal_pack_msg_v4(struct ksock_tx *tx)
+{
+       int hdr_size;
+
+       tx->tx_hdr.iov_base = (void *)&tx->tx_msg;
+
+       switch (tx->tx_msg.ksm_type) {
+       case KSOCK_MSG_LNET:
+               LASSERT(tx->tx_lnetmsg != NULL);
+               hdr_size = (sizeof(struct ksock_msg_hdr) +
+                               sizeof(struct lnet_hdr_nid16));
+
+               lnet_hdr_to_nid16(&tx->tx_lnetmsg->msg_hdr,
+                                    &tx->tx_msg.ksm_u.lnetmsg_nid16);
+               tx->tx_hdr.iov_len = hdr_size;
+               tx->tx_resid = tx->tx_nob = hdr_size + tx->tx_lnetmsg->msg_len;
+               break;
+       case KSOCK_MSG_NOOP:
+               LASSERT(tx->tx_lnetmsg == NULL);
+               hdr_size = sizeof(struct ksock_msg_hdr);
+
+               tx->tx_hdr.iov_len = hdr_size;
+               tx->tx_resid = tx->tx_nob = hdr_size;
+               break;
+       default:
+               LASSERT(0);
+       }
+       /* Don't checksum before start sending, because packet can be
+        * piggybacked with ACK
+        */
+}
+
+static void
 ksocknal_unpack_msg_v1(struct ksock_msg *msg, struct lnet_hdr *hdr)
 {
        msg->ksm_csum           = 0;
@@ -808,6 +939,12 @@ ksocknal_unpack_msg_v2(struct ksock_msg *msg, struct lnet_hdr *hdr)
        lnet_hdr_from_nid4(hdr, &msg->ksm_u.lnetmsg_nid4);
 }
 
+static void
+ksocknal_unpack_msg_v4(struct ksock_msg *msg, struct lnet_hdr *hdr)
+{
+       lnet_hdr_from_nid16(hdr, &msg->ksm_u.lnetmsg_nid16);
+}
+
 const struct ksock_proto ksocknal_protocol_v1x =
 {
         .pro_version            = KSOCK_PROTO_V1,
@@ -850,3 +987,15 @@ const struct ksock_proto ksocknal_protocol_v3x =
         .pro_match_tx           = ksocknal_match_tx_v3
 };
 
+const struct ksock_proto ksocknal_protocol_v4x = {
+       .pro_version            = KSOCK_PROTO_V4,
+       .pro_send_hello         = ksocknal_send_hello_v4,
+       .pro_recv_hello         = ksocknal_recv_hello_v4,
+       .pro_pack               = ksocknal_pack_msg_v4,
+       .pro_unpack             = ksocknal_unpack_msg_v4,
+       .pro_queue_tx_msg       = ksocknal_queue_tx_msg_v2,
+       .pro_queue_tx_zcack     = ksocknal_queue_tx_zcack_v3,
+       .pro_handle_zcreq       = ksocknal_handle_zcreq,
+       .pro_handle_zcack       = ksocknal_handle_zcack,
+       .pro_match_tx           = ksocknal_match_tx_v4,
+};