+2005-10-25 Roland Dreier <roland@cisco.com>
+
+ * examples/rc_pingpong.c, examples/srq_pingpong.c,
+ examples/uc_pingpong.c, examples/ud_pingpong.c: Keep track of
+ whether send and/or receive is pending. This avoids failures when
+ the remote side receives data and posts a send very quickly, and
+ the local side completes the receive before the previous send.
+ With the old code, this could result in posting a send before the
+ previous send completed, and therefore overrun the send queue.
+
2005-10-23 Roland Dreier <roland@cisco.com>
* src/cmd.c (ibv_cmd_get_context_v2): Correct silly mistake in
void *buf;
int size;
int rx_depth;
+ int pending;
};
struct pingpong_dest {
return 1;
}
- if (servername)
+ ctx->pending = PINGPONG_RECV_WRID;
+
+ if (servername) {
if (pp_post_send(ctx)) {
fprintf(stderr, "Couldn't post send\n");
return 1;
}
+ ctx->pending |= PINGPONG_SEND_WRID;
+ }
if (gettimeofday(&start, NULL)) {
perror("gettimeofday");
}
}
- if (scnt < iters)
- if (pp_post_send(ctx)) {
- fprintf(stderr, "Couldn't post send\n");
- return 1;
- }
-
++rcnt;
break;
(int) wc[i].wr_id);
return 1;
}
+
+ ctx->pending &= ~(int) wc[i].wr_id;
+ if (scnt < iters && !ctx->pending) {
+ if (pp_post_send(ctx)) {
+ fprintf(stderr, "Couldn't post send\n");
+ return 1;
+ }
+ ctx->pending = PINGPONG_RECV_WRID |
+ PINGPONG_SEND_WRID;
+ }
}
}
}
int size;
int num_qp;
int rx_depth;
+ int pending[MAX_QP];
};
struct pingpong_dest {
.recv_cq = ctx->cq,
.srq = ctx->srq,
.cap = {
- .max_send_wr = 4,
+ .max_send_wr = 1,
.max_send_sge = 1,
},
.qp_type = IBV_QPT_RC
}
if (servername)
- for (i = 0; i < num_qp; ++i)
+ for (i = 0; i < num_qp; ++i) {
if (pp_post_send(ctx, i)) {
fprintf(stderr, "Couldn't post send\n");
return 1;
}
+ ctx->pending[i] = PINGPONG_SEND_WRID | PINGPONG_RECV_WRID;
+ }
+ else
+ for (i = 0; i < num_qp; ++i)
+ ctx->pending[i] = PINGPONG_RECV_WRID;
if (gettimeofday(&start, NULL)) {
perror("gettimeofday");
{
struct ibv_wc wc[2];
- int ne, j;
+ int ne, qp_ind;
do {
ne = ibv_poll_cq(ctx->cq, 2, wc);
return 1;
}
+ qp_ind = find_qp(wc[i].qp_num, ctx, num_qp);
+ if (qp_ind < 0) {
+ fprintf(stderr, "Couldn't find QPN %06x\n",
+ wc[i].qp_num);
+ return 1;
+ }
+
switch ((int) wc[i].wr_id) {
case PINGPONG_SEND_WRID:
++scnt;
}
}
- if (scnt < iters) {
- j = find_qp(wc[i].qp_num, ctx, num_qp);
- if (j < 0) {
- fprintf(stderr, "Couldn't find QPN %06x\n",
- wc[i].qp_num);
- return 1;
- }
-
- if (pp_post_send(ctx, j)) {
- fprintf(stderr, "Couldn't post send\n");
- return 1;
- }
- }
-
++rcnt;
break;
(int) wc[i].wr_id);
return 1;
}
+
+ ctx->pending[qp_ind] &= ~(int) wc[i].wr_id;
+ if (scnt < iters && !ctx->pending[qp_ind]) {
+ if (pp_post_send(ctx, qp_ind)) {
+ fprintf(stderr, "Couldn't post send\n");
+ return 1;
+ }
+ ctx->pending[qp_ind] = PINGPONG_RECV_WRID |
+ PINGPONG_SEND_WRID;
+ }
+
}
}
}
void *buf;
int size;
int rx_depth;
+ int pending;
};
struct pingpong_dest {
return 1;
}
- if (servername)
+ ctx->pending = PINGPONG_RECV_WRID;
+
+ if (servername) {
if (pp_post_send(ctx)) {
fprintf(stderr, "Couldn't post send\n");
return 1;
}
+ ctx->pending |= PINGPONG_SEND_WRID;
+ }
if (gettimeofday(&start, NULL)) {
perror("gettimeofday");
}
}
- if (scnt < iters)
- if (pp_post_send(ctx)) {
- fprintf(stderr, "Couldn't post send\n");
- return 1;
- }
-
++rcnt;
break;
(int) wc[i].wr_id);
return 1;
}
+
+ ctx->pending &= ~(int) wc[i].wr_id;
+ if (scnt < iters && !ctx->pending) {
+ if (pp_post_send(ctx)) {
+ fprintf(stderr, "Couldn't post send\n");
+ return 1;
+ }
+ ctx->pending = PINGPONG_RECV_WRID |
+ PINGPONG_SEND_WRID;
+ }
}
}
}
void *buf;
int size;
int rx_depth;
+ int pending;
};
struct pingpong_dest {
return 1;
}
- if (servername)
+ ctx->pending = PINGPONG_RECV_WRID;
+
+ if (servername) {
if (pp_post_send(ctx, rem_dest->qpn)) {
fprintf(stderr, "Couldn't post send\n");
return 1;
}
+ ctx->pending |= PINGPONG_SEND_WRID;
+ }
if (gettimeofday(&start, NULL)) {
perror("gettimeofday");
}
}
- if (scnt < iters)
- if (pp_post_send(ctx, rem_dest->qpn)) {
- fprintf(stderr, "Couldn't post send\n");
- return 1;
- }
-
++rcnt;
break;
(int) wc[i].wr_id);
return 1;
}
+
+ ctx->pending &= ~(int) wc[i].wr_id;
+ if (scnt < iters && !ctx->pending) {
+ if (pp_post_send(ctx, rem_dest->qpn)) {
+ fprintf(stderr, "Couldn't post send\n");
+ return 1;
+ }
+ ctx->pending = PINGPONG_RECV_WRID |
+ PINGPONG_SEND_WRID;
+ }
}
}
}