diff --git a/configure.ac b/configure.ac index aa4dd1ee..ac334cf9 100755 --- a/configure.ac +++ b/configure.ac @@ -393,6 +393,11 @@ if [test $HAVE_IBV_WR_API = yes]; then if [test $HAVE_RDMA_WRITE_SRD = yes]; then AC_DEFINE([HAVE_SRD_WITH_RDMA_WRITE], [1], [Have SRD with RDMA write support]) fi + AC_TRY_LINK([#include ], + [int x = EFADV_DEVICE_ATTR_CAPS_UNSOLICITED_WRITE_RECV;], [HAVE_UNSOLICITED_WRITE_RECV_SRD=yes], [HAVE_UNSOLICITED_WRITE_RECV_SRD=no]) + if [test $HAVE_UNSOLICITED_WRITE_RECV_SRD = yes]; then + AC_DEFINE([HAVE_SRD_WITH_UNSOLICITED_WRITE_RECV], [1], [Have SRD with unsolicited RDMA write with imm. support]) + fi else AC_CHECK_LIB([efa], [efadv_create_driver_qp], [HAVE_SRD=yes], [HAVE_SRD=no]) fi diff --git a/src/perftest_parameters.c b/src/perftest_parameters.c index 766adfa4..6c0bd568 100755 --- a/src/perftest_parameters.c +++ b/src/perftest_parameters.c @@ -645,7 +645,12 @@ static void usage(const char *argv0, VerbType verb, TestType tst, int connection if ((tst == LAT || tst == BW) && verb == WRITE) { printf(" --write_with_imm "); - printf(" use write-with-immediate verb instead of write\n"); + printf(" Use write-with-immediate verb instead of write\n"); + + #ifdef HAVE_SRD_WITH_UNSOLICITED_WRITE_RECV + printf(" --unsolicited_write "); + printf(" Use unsolicited receive for write-with-immediate\n"); + #endif } putchar('\n'); @@ -883,6 +888,7 @@ static void init_perftest_params(struct perftest_parameters *user_param) user_param->source_ip = NULL; user_param->has_source_ip = 0; user_param->use_write_with_imm = 0; + user_param->use_unsolicited_write = 0; user_param->congest_type = OFF; user_param->no_lock = OFF; } @@ -1617,6 +1623,19 @@ static void force_dependecies(struct perftest_parameters *user_param) user_param->cq_mod = 1; } + if (user_param->use_unsolicited_write) { + if (user_param->connection_type != SRD) { + printf(RESULT_LINE); + fprintf(stderr, " Unsolicited write receive is supported only for SRD\n"); + exit(1); + } + if (user_param->verb != WRITE_IMM) { + printf(RESULT_LINE); + fprintf(stderr, " Unsolicited write receive can only be used with write-with-immediate\n"); + exit(1); + } + } + if ((user_param->use_srq && (user_param->tst == LAT || user_param->machine == SERVER || user_param->duplex == ON)) || user_param->use_xrc) user_param->srq_exists = 1; @@ -2323,6 +2342,9 @@ int parser(struct perftest_parameters *user_param,char *argv[], int argc) static int recv_post_list_flag = 0; static int payload_flag = 0; static int use_write_with_imm_flag = 0; + #ifdef HAVE_SRD_WITH_UNSOLICITED_WRITE_RECV + static int unsolicited_write_flag = 0; + #endif #ifdef HAVE_DCS static int log_dci_streams_flag = 0; static int log_active_dci_streams_flag = 0; @@ -2506,6 +2528,9 @@ int parser(struct perftest_parameters *user_param,char *argv[], int argc) #endif {.name = "bind_source_ip", .has_arg = 1, .flag = &source_ip_flag, .val = 1}, {.name = "write_with_imm", .has_arg = 0, .flag = &use_write_with_imm_flag, .val = 1 }, + #ifdef HAVE_SRD_WITH_UNSOLICITED_WRITE_RECV + {.name = "unsolicited_write", .has_arg = 0, .flag = &unsolicited_write_flag, .val = 1 }, + #endif {0} }; if (!duplicates_checker) { @@ -3146,6 +3171,12 @@ int parser(struct perftest_parameters *user_param,char *argv[], int argc) user_param->verb = WRITE_IMM; use_write_with_imm_flag = 0; } + #ifdef HAVE_SRD_WITH_UNSOLICITED_WRITE_RECV + if (unsolicited_write_flag) { + user_param->use_unsolicited_write = 1; + unsolicited_write_flag = 0; + } + #endif break; default: fprintf(stderr," Invalid Command or flag.\n"); diff --git a/src/perftest_parameters.h b/src/perftest_parameters.h index 5a774f0c..fa37af74 100755 --- a/src/perftest_parameters.h +++ b/src/perftest_parameters.h @@ -639,6 +639,7 @@ struct perftest_parameters { int has_source_ip; int ah_allocated; int use_write_with_imm; + int use_unsolicited_write; }; struct report_options { diff --git a/src/perftest_resources.c b/src/perftest_resources.c index 814ffdb0..1cb2defc 100755 --- a/src/perftest_resources.c +++ b/src/perftest_resources.c @@ -2434,6 +2434,10 @@ struct ibv_qp* ctx_qp_create(struct pingpong_context *ctx, #ifdef HAVE_SRD #ifdef HAVE_IBV_WR_API efa_attr.driver_qp_type = EFADV_QP_DRIVER_TYPE_SRD; + #ifdef HAVE_SRD_WITH_UNSOLICITED_WRITE_RECV + if (user_param->use_unsolicited_write) + efa_attr.flags |= EFADV_QP_FLAGS_UNSOLICITED_WRITE_RECV; + #endif qp = efadv_create_qp_ex(ctx->context, &attr_ex, &efa_attr, sizeof(efa_attr)); #else @@ -3800,7 +3804,7 @@ int run_iter_bw_server(struct pingpong_context *ctx, struct perftest_parameters } //coverity[uninit_use] if ((user_param->test_type==DURATION || posted_per_qp[wc_id] + user_param->recv_post_list <= user_param->iters) && - unused_recv_for_qp[wc_id] >= user_param->recv_post_list) { + unused_recv_for_qp[wc_id] >= user_param->recv_post_list && !user_param->use_unsolicited_write) { if (user_param->use_srq) { if (ibv_post_srq_recv(ctx->srq, &ctx->rwr[wc_id * user_param->recv_post_list], &bad_wr_recv)) { fprintf(stderr, "Couldn't post recv SRQ. QP = %d: counter=%lu\n", wc_id,rcnt); @@ -4087,7 +4091,7 @@ int run_iter_bw_infinitely_server(struct pingpong_context *ctx, struct perftest_ } user_param->iters++; unused_recv_for_qp[wc[i].wr_id]++; - if (unused_recv_for_qp[wc[i].wr_id] >= user_param->recv_post_list) { + if (unused_recv_for_qp[wc[i].wr_id] >= user_param->recv_post_list && !user_param->use_unsolicited_write) { if (user_param->use_srq) { if (ibv_post_srq_recv(ctx->srq, &ctx->rwr[wc[i].wr_id * user_param->recv_post_list],&bad_wr_recv)) { fprintf(stderr, "Couldn't post recv SRQ. QP = %d:\n",(int)wc[i].wr_id); @@ -4341,7 +4345,7 @@ int run_iter_bi(struct pingpong_context *ctx, } if ((user_param->test_type==DURATION || posted_per_qp[wc[i].wr_id] + user_param->recv_post_list <= user_param->iters) && - unused_recv_for_qp[wc[i].wr_id] >= user_param->recv_post_list) { + unused_recv_for_qp[wc[i].wr_id] >= user_param->recv_post_list && !user_param->use_unsolicited_write) { if (user_param->use_srq) { if (ibv_post_srq_recv(ctx->srq, &ctx->rwr[wc[i].wr_id * user_param->recv_post_list],&bad_wr_recv)) { fprintf(stderr, "Couldn't post recv SRQ. QP = %d: counter=%d\n",(int)wc[i].wr_id,(int)totrcnt); @@ -4685,7 +4689,8 @@ int run_iter_lat_write_imm(struct pingpong_context *ctx,struct perftest_paramete * is enough space in the rx_depth, * post that you received a packet. */ - if (user_param->test_type == DURATION || (rcnt + size_per_qp <= user_param->iters)) { + if ((user_param->test_type == DURATION || (rcnt + size_per_qp <= user_param->iters)) && + !user_param->use_unsolicited_write) { if (user_param->use_srq) { if (ibv_post_srq_recv(ctx->srq, &ctx->rwr[wc.wr_id], &bad_wr_recv)) { fprintf(stderr, "Couldn't post recv SRQ. QP = %d: counter=%lu\n",(int)wc.wr_id, rcnt); diff --git a/src/write_bw.c b/src/write_bw.c index 1d3109ad..21d88dd5 100755 --- a/src/write_bw.c +++ b/src/write_bw.c @@ -301,7 +301,8 @@ int main(int argc, char *argv[]) if (user_param.machine == CLIENT || user_param.duplex) ctx_set_send_wqes(&ctx,&user_param,rem_dest); - if (user_param.verb == WRITE_IMM && (user_param.machine == SERVER || user_param.duplex)) { + if (user_param.verb == WRITE_IMM && !user_param.use_unsolicited_write && + (user_param.machine == SERVER || user_param.duplex)) { if (ctx_set_recv_wqes(&ctx,&user_param)) { fprintf(stderr," Failed to post receive recv_wqes\n"); goto free_mem; diff --git a/src/write_lat.c b/src/write_lat.c index 782eb706..0e618253 100755 --- a/src/write_lat.c +++ b/src/write_lat.c @@ -262,10 +262,12 @@ int main(int argc, char *argv[]) user_param.size = (uint64_t)1 << i; if (user_param.verb == WRITE_IMM) { - /* Post receive recv_wqes fo current message size */ - if (ctx_set_recv_wqes(&ctx,&user_param)) { - fprintf(stderr," Failed to post receive recv_wqes\n"); - goto free_mem; + if (!user_param.use_unsolicited_write) { + /* Post receive recv_wqes fo current message size */ + if (ctx_set_recv_wqes(&ctx,&user_param)) { + fprintf(stderr," Failed to post receive recv_wqes\n"); + goto free_mem; + } } /* Sync between the client and server so the client won't send packets