}
/* Store relevant fields to generate a bulk response. */
- tn->tn_response_mr_key = rxmsg->proto.bulk_req.key;
- tn->tn_response_rx = rxmsg->proto.bulk_req.response_rx;
+ if (rxmsg->version == KFILND_MSG_VERSION_1) {
+ tn->tn_response_mr_key = rxmsg->proto.bulk_req.key;
+ tn->tn_response_rx = rxmsg->proto.bulk_req.response_rx;
+ tn->tn_response_session_key = tn->tn_kp->kp_remote_session_key;
+ } else {
+ tn->tn_response_mr_key = rxmsg->proto.bulk_req_v2.kbrm2_key;
+ tn->tn_response_rx = rxmsg->proto.bulk_req_v2.kbrm2_response_rx;
+ tn->tn_response_session_key =
+ rxmsg->proto.bulk_req_v2.kbrm2_session_key;
+ }
#if 0
tn->tn_tx_msg.length = kfilnd_init_proto(tn->tn_tx_msg.msg,
__u16 key;
} __packed;
+struct kfilnd_bulk_req_msg_v2 {
+ /* Entire LNet header needed by the destination to match incoming
+ * message.
+ */
+ struct lnet_hdr_nid4 kbrm2_hdr;
+
+ /* Specific RX context the target must target to push/pull LNet
+ * payload.
+ */
+ __u32 kbrm2_response_rx;
+
+ /* Memory key needed by the target to push/pull LNet payload. */
+ __u16 kbrm2_key;
+
+ /* Session key used by peer. */
+ __u32 kbrm2_session_key;
+} __packed;
+
/* Kfilnd message. Includes base transport header plus embedded protocol
* message.
*/
struct kfilnd_immed_msg immed;
struct kfilnd_bulk_req_msg bulk_req;
struct kfilnd_hello_msg hello;
+ struct kfilnd_bulk_req_msg_v2 bulk_req_v2;
} __packed proto;
} __packed;
#define KFILND_MSG_MAGIC LNET_PROTO_KFI_MAGIC /* unique magic */
#define KFILND_MSG_VERSION_1 0x1
-#define KFILND_MSG_VERSION KFILND_MSG_VERSION_1
+#define KFILND_MSG_VERSION_2 0x2
+#define KFILND_MSG_VERSION KFILND_MSG_VERSION_2
/* Get the KFI RX context from a KFI RX address. RX context information is
* stored in the MSBs of the KFI address.
!IS_ERR_OR_NULL((tn)->tn_kp)
#define KFILND_TN_DIR_DEBUG(tn, fmt, dir, ...) \
- CDEBUG(D_NET, "%s Transaction ID %p: %s:%u %s %s(%p):0x%llx " fmt "\n", \
+ CDEBUG(D_NET, "%s TN %p: %s:%u %s %s(%p):0x%llx lsk %u rsk %u tsk %u trmk %u tmk %u trr %u tta 0x%llx " fmt "\n", \
msg_type_to_str(tn->msg_type), \
(tn), \
libcfs_nidstr(&(tn)->tn_ep->end_dev->kfd_ni->ni_nid), \
- (tn)->tn_ep->end_context_id, dir, \
- libcfs_nid2str((tn)->tn_kp->kp_nid), tn->tn_kp, \
- KFILND_TN_PEER_VALID(tn) ? \
- KFILND_RX_CONTEXT((tn)->tn_kp->kp_addr) : 0, \
+ (tn)->tn_ep->end_context_id, \
+ dir, \
+ libcfs_nid2str((tn)->tn_kp->kp_nid), \
+ (tn)->tn_kp, \
+ KFILND_RX_CONTEXT((tn)->tn_kp->kp_addr), \
+ (tn)->tn_kp->kp_local_session_key, \
+ (tn)->tn_kp->kp_remote_session_key, \
+ (tn)->tn_response_session_key, \
+ (tn)->tn_response_mr_key, \
+ (tn)->tn_mr_key, \
+ (tn)->tn_response_rx, \
+ (tn)->tn_target_addr, \
##__VA_ARGS__)
#define KFILND_TN_DEBUG(tn, fmt, ...) \
[TN_EVENT_RX_FAIL] = "TN_EVENT_RX_FAIL",
[TN_EVENT_INIT_TAG_RMA] = "TN_EVENT_INIT_TAG_RMA",
[TN_EVENT_SKIP_TAG_RMA] = "TN_EVENT_SKIP_TAG_RMA",
+ [TN_EVENT_TAG_TX_OK] = "TN_EVENT_TAG_TX_OK",
[TN_EVENT_TAG_TX_FAIL] = "TN_EVENT_TAG_TX_FAIL",
};
*/
u16 tn_response_mr_key;
u8 tn_response_rx;
+ u32 tn_response_session_key;
/* Immediate data used to convey transaction state from LNet target to
* LNet intiator.
static uint64_t gen_init_tag_bits(struct kfilnd_transaction *tn)
{
- return (tn->tn_kp->kp_remote_session_key << KFILND_EP_KEY_BITS) |
+ return (tn->tn_response_session_key << KFILND_EP_KEY_BITS) |
tn->tn_response_mr_key;
}
+static bool tn_session_key_is_valid(struct kfilnd_transaction *tn)
+{
+ if (tn->tn_response_session_key == tn->tn_kp->kp_remote_session_key)
+ return true;
+
+ KFILND_TN_DEBUG(tn, "Detected session key mismatch %u != %u\n",
+ tn->tn_response_session_key,
+ tn->tn_kp->kp_remote_session_key);
+ return false;
+}
+
/**
* kfilnd_ep_post_tagged_send() - Post a tagged send operation.
* @ep: KFI LND endpoint used to post the tagged receivce operation.
if (ep->end_dev->kfd_state != KFILND_STATE_INITIALIZED)
return -EINVAL;
+ if (!tn_session_key_is_valid(tn))
+ return -EINVAL;
+
/* Progress transaction to failure if send should fail. */
if (CFS_FAIL_CHECK(CFS_KFI_FAIL_TAGGED_SEND_EVENT)) {
rc = kfilnd_ep_gen_fake_err(ep, &fake_error);
return -EAGAIN;
}
+ KFILND_TN_DEBUG(tn, "tagged_data: %llu tn_status: %d\n",
+ tn->tagged_data, tn->tn_status);
+
rc = kfi_tsenddata(ep->end_tx, NULL, 0, NULL, tn->tagged_data,
tn->tn_target_addr, gen_init_tag_bits(tn), tn);
switch (rc) {
if (ep->end_dev->kfd_state != KFILND_STATE_INITIALIZED)
return -EINVAL;
+ if (!tn_session_key_is_valid(tn))
+ return -EINVAL;
+
/* Progress transaction to failure if read should fail. */
if (CFS_FAIL_CHECK(CFS_KFI_FAIL_WRITE_EVENT)) {
rc = kfilnd_ep_gen_fake_err(ep, &fake_error);
case 0:
case -EAGAIN:
KFILND_EP_DEBUG(ep,
- "Transaction ID %p: %s write of %u bytes in %u frags with key 0x%x to peer 0x%llx: rc=%d",
+ "TN ID %p: %s write of %u bytes in %u frags kp %s(%p) rma_iov.key %llu: rc=%d",
tn, rc ? "Failed to post" : "Posted",
tn->tn_nob, tn->tn_num_iovec,
- tn->tn_response_mr_key, tn->tn_target_addr, rc);
+ libcfs_nid2str(tn->tn_kp->kp_nid), tn->tn_kp,
+ rma_iov.key, rc);
break;
default:
KFILND_EP_ERROR(ep,
- "Transaction ID %p: Failed to post write of %u bytes in %u frags with key 0x%x to peer 0x%llx: rc=%d",
+ "TN %p: Failed to post write of %u bytes in %u frags kp %s(%p) rma_iov.key %llu: rc=%d",
tn, tn->tn_nob, tn->tn_num_iovec,
- tn->tn_response_mr_key, tn->tn_target_addr,
- rc);
+ libcfs_nid2str(tn->tn_kp->kp_nid), tn->tn_kp,
+ rma_iov.key, rc);
}
return rc;
if (ep->end_dev->kfd_state != KFILND_STATE_INITIALIZED)
return -EINVAL;
+ if (!tn_session_key_is_valid(tn))
+ return -EINVAL;
+
/* Progress transaction to failure if read should fail. */
if (CFS_FAIL_CHECK(CFS_KFI_FAIL_READ_EVENT)) {
rc = kfilnd_ep_gen_fake_err(ep, &fake_error);
case 0:
case -EAGAIN:
KFILND_EP_DEBUG(ep,
- "Transaction ID %p: %s read of %u bytes in %u frags with key 0x%x to peer 0x%llx: rc=%d",
+ "TN %p: %s read of %u bytes in %u frags kp %s(%p) rma_iov.key %llu: rc=%d",
tn, rc ? "Failed to post" : "Posted",
tn->tn_nob, tn->tn_num_iovec,
- tn->tn_response_mr_key, tn->tn_target_addr, rc);
+ libcfs_nid2str(tn->tn_kp->kp_nid), tn->tn_kp,
+ rma_iov.key, rc);
break;
default:
KFILND_EP_ERROR(ep,
- "Transaction ID %p: Failed to post read of %u bytes in %u frags with key 0x%x to peer 0x%llx: rc=%d",
+ "TN %p: Failed to post read of %u bytes in %u frags kp %s(%p) rma_iov.key %llu: rc=%d",
tn, tn->tn_nob, tn->tn_num_iovec,
- tn->tn_response_mr_key, tn->tn_target_addr, rc);
+ libcfs_nid2str(tn->tn_kp->kp_nid), tn->tn_kp,
+ rma_iov.key, rc);
}
return rc;
return NO_CHECKSUM;
}
-static int kfilnd_tn_msgtype2size(enum kfilnd_msg_type type)
+static int kfilnd_tn_msgtype2size(struct kfilnd_msg *msg)
{
const int hdr_size = offsetof(struct kfilnd_msg, proto);
- switch (type) {
+ switch (msg->type) {
case KFILND_MSG_IMMEDIATE:
return offsetof(struct kfilnd_msg, proto.immed.payload[0]);
case KFILND_MSG_BULK_PUT_REQ:
case KFILND_MSG_BULK_GET_REQ:
- return hdr_size + sizeof(struct kfilnd_bulk_req_msg);
-
+ if (msg->version == KFILND_MSG_VERSION_1)
+ return hdr_size + sizeof(struct kfilnd_bulk_req_msg);
+ else if (msg->version == KFILND_MSG_VERSION_2)
+ return hdr_size + sizeof(struct kfilnd_bulk_req_msg_v2);
+ fallthrough;
default:
return -1;
}
{
struct kfilnd_msg *msg = tn->tn_tx_msg.msg;
- /* Pack the protocol header and payload. */
- lnet_hdr_to_nid4(&tn->tn_lntmsg->msg_hdr, &msg->proto.bulk_req.hdr);
- msg->proto.bulk_req.key = tn->tn_mr_key;
- msg->proto.bulk_req.response_rx = tn->tn_response_rx;
-
/* Pack the transport header. */
msg->magic = KFILND_MSG_MAGIC;
- msg->version = KFILND_MSG_VERSION;
+ msg->version = tn->tn_kp->kp_version;
msg->type = tn->msg_type;
- msg->nob = sizeof(struct kfilnd_bulk_req_msg) +
- offsetof(struct kfilnd_msg, proto);
msg->cksum = NO_CHECKSUM;
msg->srcnid = lnet_nid_to_nid4(&tn->tn_ep->end_dev->kfd_ni->ni_nid);
msg->dstnid = tn->tn_kp->kp_nid;
+ if (msg->version == KFILND_MSG_VERSION_1) {
+ msg->nob = sizeof(struct kfilnd_bulk_req_msg) +
+ offsetof(struct kfilnd_msg, proto);
+
+ /* Pack the protocol header and payload. */
+ lnet_hdr_to_nid4(&tn->tn_lntmsg->msg_hdr,
+ &msg->proto.bulk_req.hdr);
+ msg->proto.bulk_req.key = tn->tn_mr_key;
+ msg->proto.bulk_req.response_rx = tn->tn_response_rx;
+ } else {
+ msg->nob = sizeof(struct kfilnd_bulk_req_msg_v2) +
+ offsetof(struct kfilnd_msg, proto);
+
+ /* Pack the protocol header and payload. */
+ lnet_hdr_to_nid4(&tn->tn_lntmsg->msg_hdr,
+ &msg->proto.bulk_req_v2.kbrm2_hdr);
+ msg->proto.bulk_req_v2.kbrm2_key = tn->tn_mr_key;
+ msg->proto.bulk_req_v2.kbrm2_response_rx = tn->tn_response_rx;
+ msg->proto.bulk_req_v2.kbrm2_session_key =
+ tn->tn_kp->kp_local_session_key;
+ }
+
/* Checksum entire message. */
msg->cksum = kfilnd_tn_cksum(msg, msg->nob);
/* Pack the transport header. */
msg->magic = KFILND_MSG_MAGIC;
- msg->version = KFILND_MSG_VERSION;
+ msg->version = tn->tn_kp->kp_version;
msg->type = tn->msg_type;
msg->nob = offsetof(struct kfilnd_msg, proto.immed.payload[tn->tn_nob]);
msg->cksum = NO_CHECKSUM;
return -EPROTO;
}
- if (msg->nob < kfilnd_tn_msgtype2size(msg->type)) {
+ if (msg->nob < kfilnd_tn_msgtype2size(msg)) {
KFILND_EP_ERROR(ep, "Short %s: %d(%d)\n",
msg_type_to_str(msg->type),
- msg->nob, kfilnd_tn_msgtype2size(msg->type));
+ msg->nob, kfilnd_tn_msgtype2size(msg));
return -EPROTO;
}
rc = lnet_parse(tn->tn_ep->end_dev->kfd_ni,
&hdr, &srcnid, tn, 0);
} else {
- lnet_hdr_from_nid4(&hdr, &msg->proto.bulk_req.hdr);
+ if (msg->version == KFILND_MSG_VERSION_1)
+ lnet_hdr_from_nid4(&hdr, &msg->proto.bulk_req.hdr);
+ else
+ lnet_hdr_from_nid4(&hdr, &msg->proto.bulk_req_v2.kbrm2_hdr);
rc = lnet_parse(tn->tn_ep->end_dev->kfd_ni,
&hdr, &srcnid, tn, 1);
}