Skip to content

Commit

Permalink
prov/verbs: CM req header is part of private data with AF_INET
Browse files Browse the repository at this point in the history
With AF_INET, the CM request header is part of the private
data and it is defined in the first 36 bytes. To comply with
the CM REQ private data format, user private data must be
stored starting at byte 36. Worse, any data saved at the
beginning of the private data buffer would be corrupted as
the first byte would be overwritten with 0.

References:
- https://www.spinics.net/lists/linux-rdma/msg22381.html
- IBTA Architecture Specification Vol 1. Annex A11: RDMA
  IP CM Service.

Signed-off-by: Sylvain Didelot <sdidelot@ddn.com>
  • Loading branch information
sydidelot committed Jun 29, 2020
1 parent 4d0da60 commit f06c9e1
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 12 deletions.
2 changes: 2 additions & 0 deletions prov/verbs/src/fi_verbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@

#define VERBS_NO_COMP_FLAG ((uint64_t)-1)

#define VRB_CM_REQ_HDR_SIZE (36)
#define VRB_CM_DATA_SIZE (56)
#define VERBS_CM_DATA_SIZE (VRB_CM_DATA_SIZE - \
sizeof(struct vrb_cm_data_hdr))
Expand Down Expand Up @@ -575,6 +576,7 @@ struct vrb_ep {
size_t rx_cq_size;
struct rdma_conn_param conn_param;
struct vrb_cm_data_hdr *cm_hdr;
void *cm_priv_data;
};


Expand Down
30 changes: 19 additions & 11 deletions prov/verbs/src/verbs_cm.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,10 @@ vrb_msg_ep_prepare_cm_data(const void *param, size_t param_size,

static inline void
vrb_ep_prepare_rdma_cm_param(struct rdma_conn_param *conn_param,
struct vrb_cm_data_hdr *cm_hdr,
size_t cm_hdr_data_size)
void *priv_data, size_t priv_data_size)
{
conn_param->private_data = cm_hdr;
conn_param->private_data_len = (uint8_t)cm_hdr_data_size;
conn_param->private_data = priv_data;
conn_param->private_data_len = (uint8_t)priv_data_size;
conn_param->responder_resources = RDMA_MAX_RESP_RES;
conn_param->initiator_depth = RDMA_MAX_INIT_DEPTH;
conn_param->flow_control = 1;
Expand All @@ -142,6 +141,9 @@ vrb_msg_ep_connect(struct fid_ep *ep_fid, const void *addr,
{
struct vrb_ep *ep =
container_of(ep_fid, struct vrb_ep, util_ep.ep_fid);
size_t priv_data_len;
struct vrb_cm_data_hdr *cm_hdr;
off_t cm_hdr_offset = 0;
int ret;

if (OFI_UNLIKELY(paramlen > VERBS_CM_DATA_SIZE))
Expand All @@ -153,13 +155,19 @@ vrb_msg_ep_connect(struct fid_ep *ep_fid, const void *addr,
return ret;
}

ep->cm_hdr = malloc(sizeof(*(ep->cm_hdr)) + paramlen);
if (!ep->cm_hdr)
if (ep->id->route.addr.src_addr.sa_family == AF_IB)
cm_hdr_offset = VRB_CM_REQ_HDR_SIZE;

priv_data_len = cm_hdr_offset + sizeof(*cm_hdr) + paramlen;
ep->cm_priv_data = malloc(priv_data_len);
if (!ep->cm_priv_data)
return -FI_ENOMEM;

vrb_msg_ep_prepare_cm_data(param, paramlen, ep->cm_hdr);
vrb_ep_prepare_rdma_cm_param(&ep->conn_param, ep->cm_hdr,
sizeof(*(ep->cm_hdr)) + paramlen);
cm_hdr = (void*)((char *)ep->cm_priv_data + cm_hdr_offset);

vrb_msg_ep_prepare_cm_data(param, paramlen, cm_hdr);
vrb_ep_prepare_rdma_cm_param(&ep->conn_param, ep->cm_priv_data,
priv_data_len);
ep->conn_param.retry_count = 15;

if (ep->srq_ep)
Expand All @@ -170,8 +178,8 @@ vrb_msg_ep_connect(struct fid_ep *ep_fid, const void *addr,
FI_WARN(&vrb_prov, FI_LOG_EP_CTRL,
"rdma_resolve_route failed: %s (%d)\n",
strerror(-ret), -ret);
free(ep->cm_hdr);
ep->cm_hdr = NULL;
free(ep->cm_priv_data);
ep->cm_priv_data = NULL;
return ret;
}
return 0;
Expand Down
2 changes: 1 addition & 1 deletion prov/verbs/src/verbs_ep.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ static int vrb_close_free_ep(struct vrb_ep *ep)

free(ep->util_ep.ep_fid.msg);
ep->util_ep.ep_fid.msg = NULL;
free(ep->cm_hdr);
free(ep->cm_priv_data);

if (ep->util_ep.rx_cq) {
cq = container_of(ep->util_ep.rx_cq, struct vrb_cq, util_cq);
Expand Down
11 changes: 11 additions & 0 deletions prov/verbs/src/verbs_eq.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,15 @@ static inline int vrb_eq_copy_event_data(struct fi_eq_cm_entry *entry,
return datalen;
}

static void vrb_eq_skip_cm_req_hdr(const void **priv_data,
size_t *priv_data_len)
{
if (*priv_data_len > VRB_CM_REQ_HDR_SIZE) {
*priv_data = (void*)((char *)*priv_data + VRB_CM_REQ_HDR_SIZE);
*priv_data_len -= VRB_CM_REQ_HDR_SIZE;
}
}

static void vrb_eq_skip_xrc_cm_data(const void **priv_data,
size_t *priv_data_len)
{
Expand Down Expand Up @@ -850,6 +859,8 @@ vrb_eq_cm_process_event(struct vrb_eq *eq,
&priv_data, &priv_datalen);
if (ret == -FI_EAGAIN || *event == FI_CONNECTED)
goto ack;
} else if (cma_event->id->route.addr.src_addr.sa_family == AF_IB) {
vrb_eq_skip_cm_req_hdr(&priv_data, &priv_datalen);
}
break;
case RDMA_CM_EVENT_CONNECT_RESPONSE:
Expand Down

0 comments on commit f06c9e1

Please sign in to comment.