Skip to content

Commit

Permalink
Add SRD support for RDMA read
Browse files Browse the repository at this point in the history
Support posting new RDMA read Work Requests over SRD connection, using the
extended QP send WR API.  Since the WR cannot contain both rdma and ud data,
get the ah and remote qpn from the test context instead.

Signed-off-by: Daniel Kranzdorf <dkkranzd@amazon.com>
  • Loading branch information
dkkranz authored and Dmitry Akhmedzhanov committed Jun 11, 2020
1 parent 95b1ffc commit 04a0fd1
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 28 deletions.
5 changes: 5 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,11 @@ fi

if [test $HAVE_IBV_WR_API = yes]; then
AC_CHECK_LIB([efa], [efadv_create_qp_ex], [HAVE_SRD=yes], [HAVE_SRD=no])
AC_TRY_LINK([#include <infiniband/efadv.h>],
[int x = EFADV_DEVICE_ATTR_CAPS_RDMA_READ;], [HAVE_RDMA_READ_SRD=yes], [HAVE_RDMA_READ_SRD=no])
if [test $HAVE_RDMA_READ_SRD = yes]; then
AC_DEFINE([HAVE_SRD_WITH_RDMA_READ], [1], [Have SRD with RDMA read support])
fi
else
AC_CHECK_LIB([efa], [efadv_create_driver_qp], [HAVE_SRD=yes], [HAVE_SRD=no])
fi
Expand Down
63 changes: 48 additions & 15 deletions src/perftest_communication.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
#include <sys/socket.h>
#include <netdb.h>
#include "perftest_communication.h"
#ifdef HAVE_SRD
#include <infiniband/efadv.h>
#endif
#if defined(__FreeBSD__)
#include <ctype.h>
#endif
Expand Down Expand Up @@ -1783,24 +1786,54 @@ int check_mtu(struct ibv_context *context,struct perftest_parameters *user_param
user_param->size = RAWETH_MIN_MSG_SIZE;
}
} else if (user_param->connection_type == SRD) {
struct ibv_port_attr port_attr;
if (user_param->verb == SEND) {
struct ibv_port_attr port_attr;

if (ibv_query_port(context, user_param->ib_port, &port_attr)) {
fprintf(stderr, " Error when trying to query port\n");
exit(1);
}
if (ibv_query_port(context, user_param->ib_port, &port_attr)) {
fprintf(stderr, " Error when trying to query port\n");
exit(1);
}

if (user_param->size > port_attr.max_msg_sz) {
if (user_param->test_method == RUN_ALL || !user_param->req_size) {
fprintf(stderr, " Max msg size is %u\n",
port_attr.max_msg_sz);
fprintf(stderr, " Changing to this size\n");
user_param->size = port_attr.max_msg_sz;
} else {
fprintf(stderr," Max message size in SRD cannot be greater than %u \n",
port_attr.max_msg_sz);
return FAILURE;
if (user_param->size > port_attr.max_msg_sz) {
if (user_param->test_method == RUN_ALL || !user_param->req_size) {
fprintf(stderr, " Max msg size is %u\n",
port_attr.max_msg_sz);
fprintf(stderr, " Changing to this size\n");
user_param->size = port_attr.max_msg_sz;
} else {
fprintf(stderr," Max message size in SRD cannot be greater than %u \n",
port_attr.max_msg_sz);
return FAILURE;
}
}
} else if (user_param->verb == READ) {
#ifdef HAVE_SRD_WITH_RDMA_READ
struct efadv_device_attr efa_device_attr = {};

if (efadv_query_device(context, &efa_device_attr, sizeof(efa_device_attr))) {
fprintf(stderr, " Error when trying to query EFA device\n");
exit(1);
}
if (!(efa_device_attr.device_caps & EFADV_DEVICE_ATTR_CAPS_RDMA_READ)) {
fprintf(stderr, "Read verb is not supported with this EFA device\n");
exit(1);
}
if (user_param->size > efa_device_attr.max_rdma_size) {
if (user_param->test_method == RUN_ALL || !user_param->req_size) {
fprintf(stderr, " Max RDMA request size is %u\n",
efa_device_attr.max_rdma_size);
fprintf(stderr, " Changing to this size\n");
user_param->size = efa_device_attr.max_rdma_size;
} else {
fprintf(stderr," Max RDMA read size in SRD cannot be greater than %u\n",
efa_device_attr.max_rdma_size);
return FAILURE;
}
}
#else
fprintf(stderr, "SRD connection not possible in READ verb\n");
exit(1);
#endif
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/perftest_parameters.c
Original file line number Diff line number Diff line change
Expand Up @@ -801,8 +801,8 @@ static void change_conn_type(int *cptr, VerbType verb, const char *optarg)
#endif
} else if (strcmp(connStr[6], optarg) == 0) {
#ifdef HAVE_SRD
if (verb != SEND) {
fprintf(stderr, " SRD connection only possible in SEND verb\n");
if (verb != SEND && verb != READ ) {
fprintf(stderr, " SRD connection only possible in SEND/READ verbs\n");
exit(1);
}
*cptr = SRD;
Expand Down
42 changes: 31 additions & 11 deletions src/perftest_resources.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,13 +308,18 @@ static inline int _new_post_send(struct pingpong_context *ctx,
}
else
#endif
if (qpt == IBV_QPT_UD ||
(qpt == IBV_QPT_DRIVER && connection_type == SRD)) {
if (qpt == IBV_QPT_UD) {
ibv_wr_set_ud_addr(
ctx->qpx[index],
wr->wr.ud.ah,
wr->wr.ud.remote_qpn,
wr->wr.ud.remote_qkey);
} else if (qpt == IBV_QPT_DRIVER && connection_type == SRD) {
ibv_wr_set_ud_addr(
ctx->qpx[index],
ctx->ah[index],
ctx->rem_qpn[index],
DEF_QKEY);
}

#ifdef HAVE_XRCD
Expand Down Expand Up @@ -498,6 +503,12 @@ static int new_post_send_inl_srd(struct pingpong_context *ctx, int index,
return _new_post_send(ctx, user_param, 1, index, IBV_QPT_DRIVER, IBV_WR_SEND, SRD);
}

static int new_post_read_sge_srd(struct pingpong_context *ctx, int index,
struct perftest_parameters *user_param)
{
return _new_post_send(ctx, user_param, 0, index, IBV_QPT_DRIVER, IBV_WR_RDMA_READ, SRD);
}

#ifdef HAVE_XRCD
static int new_post_send_sge_xrc(struct pingpong_context *ctx, int index,
struct perftest_parameters *user_param)
Expand Down Expand Up @@ -836,10 +847,13 @@ void alloc_ctx(struct pingpong_context *ctx,struct perftest_parameters *user_par

ALLOCATE(ctx->sge_list, struct ibv_sge,user_param->num_of_qps * user_param->post_list);
ALLOCATE(ctx->wr, struct ibv_send_wr, user_param->num_of_qps * user_param->post_list);
ALLOCATE(ctx->rem_qpn, uint32_t, user_param->num_of_qps);
if ((user_param->verb == SEND && user_param->connection_type == UD) ||
user_param->connection_type == DC || user_param->connection_type == SRD) {
ALLOCATE(ctx->ah, struct ibv_ah*, user_param->num_of_qps);
}
} else if (user_param->verb == READ && user_param->connection_type == SRD) {
ALLOCATE(ctx->ah, struct ibv_ah*, user_param->num_of_qps);
}

if (user_param->verb == SEND && (user_param->tst == LAT || user_param->machine == SERVER || user_param->duplex)) {
Expand Down Expand Up @@ -912,10 +926,11 @@ int destroy_ctx(struct pingpong_context *ctx,
first = 0;
for (i = first; i < user_param->num_of_qps; i++) {

if (((user_param->connection_type == DC && !((!(user_param->duplex || user_param->tst == LAT) && user_param->machine == SERVER)
if ((((user_param->connection_type == DC && !((!(user_param->duplex || user_param->tst == LAT) && user_param->machine == SERVER)
|| ((user_param->duplex || user_param->tst == LAT) && i >= num_of_qps))) ||
user_param->connection_type == UD || user_param->connection_type == SRD) &&
(user_param->tst == LAT || user_param->machine == CLIENT || user_param->duplex)) {
(user_param->tst == LAT || user_param->machine == CLIENT || user_param->duplex)) ||
(user_param->connection_type == SRD && user_param->verb == READ)) {
if (ibv_destroy_ah(ctx->ah[i])) {
fprintf(stderr, "Failed to destroy AH\n");
test_result = 1;
Expand Down Expand Up @@ -2076,8 +2091,9 @@ int ctx_connect(struct pingpong_context *ctx,
}
}

if ((user_param->connection_type == UD || user_param->connection_type == DC || user_param->connection_type == SRD) &&
(user_param->tst == LAT || user_param->machine == CLIENT || user_param->duplex)) {
if (((user_param->connection_type == UD || user_param->connection_type == DC || user_param->connection_type == SRD) &&
(user_param->tst == LAT || user_param->machine == CLIENT || user_param->duplex)) ||
(user_param->connection_type == SRD && user_param->verb == READ)) {

ctx->ah[i] = ibv_create_ah(ctx->pd,&(attr.ah_attr));

Expand Down Expand Up @@ -2298,6 +2314,9 @@ static void ctx_post_send_work_request_func_pointer(struct pingpong_context *ctx
ctx->new_post_send_work_request_func_pointer = &new_post_send_sge_srd;
}
break;
case READ:
ctx->new_post_send_work_request_func_pointer = &new_post_read_sge_srd;
break;
default:
fprintf(stderr, "The post send properties are not supported on SRD.\n");
}
Expand All @@ -2318,7 +2337,7 @@ void ctx_set_send_reg_wqes(struct pingpong_context *ctx,
int i,j;
int num_of_qps = user_param->num_of_qps;
int xrc_offset = 0;
uint32_t remote_qpn, remote_qkey;
uint32_t remote_qkey;

if((user_param->use_xrc || user_param->connection_type == DC) && (user_param->duplex || user_param->tst == LAT)) {
num_of_qps /= 2;
Expand Down Expand Up @@ -2398,7 +2417,8 @@ void ctx_set_send_reg_wqes(struct pingpong_context *ctx,
if (user_param->verb == WRITE || user_param->verb == READ) {

ctx->wr[i*user_param->post_list + j].wr.rdma.rkey = rem_dest[xrc_offset + i].rkey;

if (user_param->connection_type == SRD)
ctx->rem_qpn[xrc_offset + i] = rem_dest[xrc_offset + i].qpn;
if (j > 0) {

ctx->wr[i*user_param->post_list + j].wr.rdma.remote_addr =
Expand Down Expand Up @@ -2435,14 +2455,14 @@ void ctx_set_send_reg_wqes(struct pingpong_context *ctx,

ctx->wr[i*user_param->post_list + j].wr.ud.ah = ctx->ah[i];
if (user_param->work_rdma_cm) {
remote_qpn = ctx->cma_master.nodes[i].remote_qpn;
ctx->rem_qpn[xrc_offset + i] = ctx->cma_master.nodes[i].remote_qpn;
remote_qkey = ctx->cma_master.nodes[i].remote_qkey;
} else {
remote_qpn = rem_dest[xrc_offset + i].qpn;
ctx->rem_qpn[xrc_offset + i] = rem_dest[xrc_offset + i].qpn;
remote_qkey = DEF_QKEY;
}
ctx->wr[i*user_param->post_list + j].wr.ud.remote_qkey = remote_qkey;
ctx->wr[i*user_param->post_list + j].wr.ud.remote_qpn = remote_qpn;
ctx->wr[i*user_param->post_list + j].wr.ud.remote_qpn = ctx->rem_qpn[xrc_offset + i];
}
}

Expand Down
1 change: 1 addition & 0 deletions src/perftest_resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ struct pingpong_context {
uint64_t *my_addr;
uint64_t *rx_buffer_addr;
uint64_t *rem_addr;
uint32_t *rem_qpn;
uint64_t buff_size;
uint64_t send_qp_buff_size;
uint64_t flow_buff_size;
Expand Down

0 comments on commit 04a0fd1

Please sign in to comment.