Whamcloud - gitweb
LU-10391 socklnd: add hello message version 4
[fs/lustre-release.git] / lnet / klnds / socklnd / socklnd_proto.c
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,
+};