Beispiel #1
0
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;
}
Beispiel #2
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;
}