int run_iter(struct pingpong_context *ctx, struct perftest_parameters *user_param, struct pingpong_dest *rem_dest) { int scnt = 0; int ne; struct ibv_sge list; struct ibv_send_wr wr; struct ibv_send_wr *bad_wr; struct ibv_wc wc; uint64_t my_addr,rem_addr; memset(&wr,0,sizeof(struct ibv_send_wr)); list.addr = (uintptr_t)ctx->buf; list.length = user_param->size; list.lkey = ctx->mr->lkey; wr.sg_list = &list; wr.wr.rdma.remote_addr = rem_dest->vaddr; wr.wr.rdma.rkey = rem_dest->rkey; wr.wr_id = PINGPONG_READ_WRID; wr.num_sge = MAX_RECV_SGE; wr.opcode = IBV_WR_RDMA_READ; wr.send_flags = IBV_SEND_SIGNALED; wr.next = NULL; my_addr = list.addr; rem_addr = wr.wr.rdma.remote_addr; while (scnt < user_param->iters) { tstamp[scnt] = get_cycles(); if (ibv_post_send(ctx->qp[0],&wr,&bad_wr)) { fprintf(stderr, "Couldn't post send: scnt=%d\n",scnt); return 11; } if (user_param->size <= (CYCLE_BUFFER / 2)) { increase_rem_addr(&wr,user_param->size,scnt,rem_addr,READ); increase_loc_addr(&list,user_param->size,scnt,my_addr,0); } scnt++; if (user_param->use_event) { if (ctx_notify_events(ctx->channel)) { fprintf(stderr, "Couldn't request CQ notification\n"); return 1; } } do { ne = ibv_poll_cq(ctx->send_cq, 1, &wc); if(ne > 0) { if (wc.status != IBV_WC_SUCCESS) NOTIFY_COMP_ERROR_SEND(wc,scnt,scnt); } } while (!user_param->use_event && ne == 0); if (ne < 0) { fprintf(stderr, "poll CQ failed %d\n", ne); return 12; } } return 0; }
int run_iter(struct pingpong_context *ctx, struct perftest_parameters *user_param, struct pingpong_dest *rem_dest, int size,int maxpostsofqpiniteration) { int totscnt = 0; int totccnt = 0; int i = 0; int index,ne; int warmindex; struct ibv_send_wr *bad_wr; struct ibv_wc *wc = NULL; struct ibv_sge *sge_list = NULL; struct ibv_send_wr *wr = NULL; uint64_t *my_addr = NULL; uint64_t *rem_addr = NULL; ALLOCATE(wr ,struct ibv_send_wr , user_param->num_of_qps); ALLOCATE(sge_list ,struct ibv_sge , user_param->num_of_qps); ALLOCATE(my_addr ,uint64_t ,user_param->num_of_qps); ALLOCATE(rem_addr ,uint64_t ,user_param->num_of_qps); ALLOCATE(wc ,struct ibv_wc , DEF_WC_SIZE); // Each QP has its own wr and sge , that holds the qp addresses and attr. // We write in cycles on the buffer to exploid the "Nahalem" system. for (index = 0 ; index < user_param->num_of_qps ; index++) { sge_list[index].addr = (uintptr_t)ctx->buf + (index*BUFF_SIZE(ctx->size)); sge_list[index].length = size; sge_list[index].lkey = ctx->mr->lkey; wr[index].sg_list = &sge_list[index]; wr[index].num_sge = MAX_SEND_SGE; wr[index].opcode = IBV_WR_RDMA_WRITE; wr[index].next = NULL; wr[index].wr.rdma.remote_addr = rem_dest[index].vaddr; wr[index].wr.rdma.rkey = rem_dest[index].rkey; wr[index].wr_id = index; wr[index].send_flags = IBV_SEND_SIGNALED; if (size <= user_param->inline_size) wr[index].send_flags |= IBV_SEND_INLINE; ctx->scnt[index] = 0; ctx->ccnt[index] = 0; my_addr[index] = sge_list[index].addr; rem_addr[index] = wr[index].wr.rdma.remote_addr; } // Done with setup. Start the test. warm up posting of total 100 wq's per // qp 1 for each qp till all qps have 100. for (warmindex = 0 ;warmindex < maxpostsofqpiniteration ;warmindex ++ ) { for (index =0 ; index < user_param->num_of_qps ; index++) { if (totscnt % CQ_MODERATION == 0) wr[index].send_flags &= ~IBV_SEND_SIGNALED; tposted[totscnt] = get_cycles(); if (ibv_post_send(ctx->qp[index],&wr[index],&bad_wr)) { fprintf(stderr,"Couldn't post send: qp %d scnt=%d \n",index,ctx->scnt[index]); return 1; } // If we can increase the remote address , so the next write will be to other address , // We do it. if (size <= (CYCLE_BUFFER / 2)) { increase_rem_addr(&wr[index],size,ctx->scnt[index],rem_addr[index]); increase_loc_addr(wr[index].sg_list,size,ctx->scnt[index],my_addr[index],0); } ctx->scnt[index]++; totscnt++; if (totscnt%CQ_MODERATION == CQ_MODERATION - 1 || totscnt == user_param->iters - 1) wr[index].send_flags |= IBV_SEND_SIGNALED; } } // main loop for posting while (totscnt < (user_param->iters * user_param->num_of_qps) || totccnt < (user_param->iters * user_param->num_of_qps) ) { // main loop to run over all the qps and post each time n messages for (index =0 ; index < user_param->num_of_qps ; index++) { while (ctx->scnt[index] < user_param->iters && (ctx->scnt[index] - ctx->ccnt[index]) < maxpostsofqpiniteration) { if (totscnt % CQ_MODERATION == 0) wr[index].send_flags &= ~IBV_SEND_SIGNALED; tposted[totscnt] = get_cycles(); if (ibv_post_send(ctx->qp[index],&wr[index],&bad_wr)) { fprintf(stderr,"Couldn't post send: qp %d scnt=%d \n",index,ctx->scnt[index]); return 1; } if (size <= (CYCLE_BUFFER / 2)) { increase_rem_addr(&wr[index],size,ctx->scnt[index],rem_addr[index]); increase_loc_addr(wr[index].sg_list,size,ctx->scnt[index],my_addr[index],0); } ctx->scnt[index] = ctx->scnt[index]+1; totscnt++; if (totscnt%CQ_MODERATION == CQ_MODERATION - 1 || totscnt == user_param->iters - 1) wr[index].send_flags |= IBV_SEND_SIGNALED; } } // finished posting now polling if (totccnt < (user_param->iters * user_param->num_of_qps) ) { do { ne = ibv_poll_cq(ctx->cq, DEF_WC_SIZE, wc); if (ne > 0) { for (i = 0; i < ne; i++) { if (wc[i].status != IBV_WC_SUCCESS) NOTIFY_COMP_ERROR_SEND(wc[i],totscnt,totccnt); ctx->ccnt[(int)wc[i].wr_id] += CQ_MODERATION; totccnt += CQ_MODERATION; if (totccnt >= user_param->iters - 1) tcompleted[user_param->iters - 1] = get_cycles(); else tcompleted[totccnt-1] = get_cycles(); } } } while (ne > 0); if (ne < 0) { fprintf(stderr, "poll CQ failed %d\n", ne); return 1; } } } free(wr); free(sge_list); free(my_addr); free(rem_addr); free(wc); return 0; }