Rev 61: ib: fragment sent buf + many bugfixes in http://samba.org/~tridge/psomogyi/

psomogyi at gamax.hu psomogyi at gamax.hu
Thu Feb 8 18:06:14 GMT 2007


------------------------------------------------------------
revno: 61
revision-id: psomogyi at gamax.hu-20070208180614-uudec20k53z5cedf
parent: psomogyi at gamax.hu-20070202175457-t5ebi3foxnxizqpw
committer: Peter Somogyi <psomogyi at gamax.hu>
branch nick: ctdb
timestamp: Thu 2007-02-08 19:06:14 +0100
message:
  ib: fragment sent buf + many bugfixes
  It came to light I have to fragment the send buffer in case destination's to fit receiver's buffers.
  Additionally fixed many bugs.
  Still testing.
  + TODO: clean code.
modified:
  ib/ibwrapper.c                 ibwrapper.c-20061204130028-0125b4f5a72f4b11
  ib/ibwrapper_internal.h        ibwrapper_internal.h-20061204130028-47f0a7e658b16ca2
  tests/ibwrapper_test.c         ibwrapper_test.c-20061214171730-h11a2z5ed6pt66hj-1
=== modified file 'ib/ibwrapper.c'
--- a/ib/ibwrapper.c	2007-02-01 17:46:44 +0000
+++ b/ib/ibwrapper.c	2007-02-08 18:06:14 +0000
@@ -39,6 +39,7 @@
 #include "ibwrapper.h"
 
 #include <rdma/rdma_cma.h>
+#include "infiniband/sa-kern-abi.h"
 
 #include "ibwrapper_internal.h"
 #include "lib/util/dlinklist.h"
@@ -46,11 +47,17 @@
 #define IBW_LASTERR_BUFSIZE 512
 static char ibw_lasterr[IBW_LASTERR_BUFSIZE];
 
+#define IBW_MAX_SEND_WR 256
+#define IBW_MAX_RECV_WR 1024
+#define IBW_RECV_BUFSIZE 256
+#define IBW_RECV_THRESHOLD (1 * 1024 * 1024)
+
 static void ibw_event_handler_verbs(struct event_context *ev,
 	struct fd_event *fde, uint16_t flags, void *private_data);
 static int ibw_fill_cq(struct ibw_conn *conn);
-static inline int ibw_wc_recv(struct ibw_conn *conn, struct ibv_wc *wc);
-static inline int ibw_wc_send(struct ibw_conn *conn, struct ibv_wc *wc);
+static int ibw_wc_recv(struct ibw_conn *conn, struct ibv_wc *wc);
+static int ibw_wc_send(struct ibw_conn *conn, struct ibv_wc *wc);
+static int ibw_send_packet(struct ibw_conn *conn, void *buf, struct ibw_wr *p, uint32_t len);
 
 static void *ibw_alloc_mr(struct ibw_ctx_priv *pctx, struct ibw_conn_priv *pconn,
 	uint32_t n, struct ibv_mr **ppmr)
@@ -97,7 +104,7 @@
 
 	DEBUG(10, ("ibw_init_memory(cmid: %p)\n", pconn->cm_id));
 	pconn->buf_send = ibw_alloc_mr(pctx, pconn,
-		opts->max_send_wr * opts->avg_send_size, &pconn->mr_send);
+		opts->max_send_wr * opts->recv_bufsize, &pconn->mr_send);
 	if (!pconn->buf_send) {
 		sprintf(ibw_lasterr, "couldn't allocate work send buf\n");
 		return -1;
@@ -115,7 +122,7 @@
 
 	for(i=0; i<opts->max_send_wr; i++) {
 		p = pconn->wr_index[i] = talloc_zero(pconn, struct ibw_wr);
-		p->msg = pconn->buf_send + (i * opts->avg_send_size);
+		p->buf = pconn->buf_send + (i * opts->recv_bufsize);
 		p->wr_id = i;
 
 		DLIST_ADD(pconn->wr_list_avail, p);
@@ -228,6 +235,7 @@
 	struct ibw_ctx_priv *pctx = talloc_get_type(conn->ctx->internal, struct ibw_ctx_priv);
 	struct ibw_conn_priv *pconn = talloc_get_type(conn->internal, struct ibw_conn_priv);
 	struct ibv_qp_init_attr init_attr;
+	struct ibv_qp_attr attr;
 	int rc;
 
 	DEBUG(10, ("ibw_setup_cq_qp(cmid: %p)\n", pconn->cm_id));
@@ -286,6 +294,12 @@
 	}
 	/* elase result is in pconn->cm_id->qp */
 
+	rc = ibv_query_qp(pconn->cm_id->qp, &attr, IBV_QP_PATH_MTU, &init_attr);
+	if (rc) {
+		sprintf(ibw_lasterr, "ibv_query_qp failed with %d\n", rc);
+		return rc;
+	}
+
 	return ibw_fill_cq(conn);
 }
 
@@ -295,12 +309,12 @@
 	struct ibw_conn_priv *pconn = talloc_get_type(conn->internal, struct ibw_conn_priv);
 	int	rc;
 	struct ibv_sge list = {
-		.addr 	= (uintptr_t) NULL,
+		.addr 	= (uintptr_t) NULL, /* filled below */
 		.length = pctx->opts.recv_bufsize,
-		.lkey 	= pconn->mr_recv->lkey
+		.lkey 	= pconn->mr_recv->lkey /* always the same */
 	};
 	struct ibv_recv_wr wr = {
-		.wr_id 	    = 0,
+		.wr_id 	    = 0, /* filled below */
 		.sg_list    = &list,
 		.num_sge    = 1,
 	};
@@ -314,7 +328,7 @@
 
 	rc = ibv_post_recv(pconn->cm_id->qp, &wr, &bad_wr);
 	if (rc) {
-		sprintf(ibw_lasterr, "ibv_post_recv failed with %d\n", rc);
+		sprintf(ibw_lasterr, "refill/ibv_post_recv failed with %d\n", rc);
 		DEBUG(0, (ibw_lasterr));
 		return -2;
 	}
@@ -328,12 +342,12 @@
 	struct ibw_conn_priv *pconn = talloc_get_type(conn->internal, struct ibw_conn_priv);
 	int	i, rc;
 	struct ibv_sge list = {
-		.addr 	= (uintptr_t) NULL,
+		.addr 	= (uintptr_t) NULL, /* filled below */
 		.length = pctx->opts.recv_bufsize,
-		.lkey 	= pconn->mr_recv->lkey
+		.lkey 	= pconn->mr_recv->lkey /* always the same */
 	};
 	struct ibv_recv_wr wr = {
-		.wr_id 	    = 0,
+		.wr_id 	    = 0, /* filled below */
 		.sg_list    = &list,
 		.num_sge    = 1,
 	};
@@ -348,7 +362,7 @@
 
 		rc = ibv_post_recv(pconn->cm_id->qp, &wr, &bad_wr);
 		if (rc) {
-			sprintf(ibw_lasterr, "ibv_post_recv failed with %d\n", rc);
+			sprintf(ibw_lasterr, "fill/ibv_post_recv failed with %d\n", rc);
 			DEBUG(0, (ibw_lasterr));
 			return -2;
 		}
@@ -532,8 +546,7 @@
 		goto error;
 	}
 	if (ev_cq != pconn->cq) {
-		sprintf(ibw_lasterr, "ev_cq(%u) != pconn->cq(%u)\n",
-			(unsigned int)ev_cq, (unsigned int)pconn->cq);
+		sprintf(ibw_lasterr, "ev_cq(%p) != pconn->cq(%p)\n", ev_cq, pconn->cq);
 		goto error;
 	}
 	rc = ibv_req_notify_cq(pconn->cq, 0);
@@ -544,8 +557,8 @@
 
 	while((rc=ibv_poll_cq(pconn->cq, 1, &wc))==1) {
 		if (wc.status) {
-			sprintf(ibw_lasterr, "cq completion failed status %d\n",
-				wc.status);
+			sprintf(ibw_lasterr, "cq completion failed status %d rc %d\n",
+				wc.status, rc);
 			goto error;
 		}
 
@@ -587,12 +600,13 @@
 	pctx->connstate_func(NULL, conn);
 }
 
-static inline int ibw_wc_send(struct ibw_conn *conn, struct ibv_wc *wc)
+static int ibw_wc_send(struct ibw_conn *conn, struct ibv_wc *wc)
 {
 	struct ibw_ctx_priv *pctx = talloc_get_type(conn->ctx->internal, struct ibw_ctx_priv);
 	struct ibw_conn_priv *pconn = talloc_get_type(conn->internal, struct ibw_conn_priv);
 	struct ibw_wr	*p;
 	int	send_index;
+	int	rc = 0;
 
 	DEBUG(10, ("ibw_wc_send(cmid: %p, wr_id: %u, bl: %u)\n",
 		pconn->cm_id, (uint32_t)wc->wr_id, (uint32_t)wc->byte_len));
@@ -605,10 +619,19 @@
 	if (send_index < pctx->opts.max_send_wr) {
 		DEBUG(10, ("ibw_wc_send#1 %u\n", (int)wc->wr_id));
 		p = pconn->wr_index[send_index];
-		if (p->msg_large)
-			ibw_free_mr(&p->msg_large, &p->mr_large);
-		DLIST_REMOVE(pconn->wr_list_used, p);
-		DLIST_ADD(pconn->wr_list_avail, p);
+		if (p->buf_large!=NULL) {
+			if (p->ref_cnt) {
+				/* awaiting more of it... */
+				p->ref_cnt--;
+			} else {
+				ibw_free_mr(&p->buf_large, &p->mr_large);
+				DLIST_REMOVE(pconn->wr_list_used, p);
+				DLIST_ADD(pconn->wr_list_avail, p);
+			}
+		} else { /* nasty - but necessary */
+			DLIST_REMOVE(pconn->wr_list_used, p);
+			DLIST_ADD(pconn->wr_list_avail, p);
+		}
 	} else { /* "extra" request - not optimized */
 		DEBUG(10, ("ibw_wc_send#2 %u\n", (int)wc->wr_id));
 		for(p=pconn->extra_sent; p!=NULL; p=p->next)
@@ -618,25 +641,42 @@
 			sprintf(ibw_lasterr, "failed to find wr_id %d\n", (int)wc->wr_id);
 				return -1;
 		}
-		ibw_free_mr(&p->msg_large, &p->mr_large);
-		DLIST_REMOVE(pconn->extra_sent, p);
-		DLIST_ADD(pconn->extra_avail, p);
+		if (p->ref_cnt) {
+			p->ref_cnt--;
+		} else {
+			ibw_free_mr(&p->buf_large, &p->mr_large);
+			DLIST_REMOVE(pconn->extra_sent, p);
+			DLIST_ADD(pconn->extra_avail, p);
+		}
 	}
 
 	if (pconn->queue) {
+		uint32_t	msg_size;
+		
 		DEBUG(10, ("ibw_wc_send#queue %u\n", (int)wc->wr_id));
+		
 		p = pconn->queue;
-		DLIST_REMOVE(pconn->queue, p);
-
+
+		assert(p->queued_ref_cnt>0);
+		p->queued_ref_cnt--;
+
+		msg_size = (p->queued_ref_cnt) ? pctx->opts.recv_bufsize : p->queued_rlen;
+ 
 		assert(p->queued_msg!=NULL);
-		ibw_send(conn, p->queued_msg, p, ntohl(*(uint32_t *)p->queued_msg));
-		p->queued_msg = NULL;
+		assert(msg_size!=0);
+		rc = ibw_send_packet(conn, p->queued_msg, p, msg_size);
+		if (p->queued_ref_cnt) {
+			p->queued_msg += pctx->opts.recv_bufsize;
+		} else {
+			DLIST_REMOVE2(pconn->queue, p, qprev, qnext);
+			p->queued_msg = NULL;
+		}
 	}
 
-	return 0;
+	return rc;
 }
 
-static inline int ibw_append_to_part(struct ibw_conn_priv *pconn,
+static int ibw_append_to_part(struct ibw_conn_priv *pconn,
 	struct ibw_part *part, char **pp, uint32_t add_len, int info)
 {
 	DEBUG(10, ("ibw_append_to_part: cmid=%p, (bs=%u, len=%u, tr=%u), al=%u, i=%u\n",
@@ -674,7 +714,7 @@
 	return 0;
 }
 
-static inline int ibw_wc_mem_threshold(struct ibw_conn_priv *pconn,
+static int ibw_wc_mem_threshold(struct ibw_conn_priv *pconn,
 	struct ibw_part *part, uint32_t threshold)
 {
 	DEBUG(10, ("ibw_wc_mem_threshold: cmid=%p, (bs=%u, len=%u, tr=%u), thr=%u\n",
@@ -694,7 +734,7 @@
 	return 0;
 }
 
-static inline int ibw_wc_recv(struct ibw_conn *conn, struct ibv_wc *wc)
+static int ibw_wc_recv(struct ibw_conn *conn, struct ibv_wc *wc)
 {
 	struct ibw_ctx_priv *pctx = talloc_get_type(conn->ctx->internal, struct ibw_ctx_priv);
 	struct ibw_conn_priv *pconn = talloc_get_type(conn->internal, struct ibw_conn_priv);
@@ -786,11 +826,10 @@
 
 	DEBUG(10, ("ibw_process_init_attrs: nattr: %d\n", nattr));
 
-	opts->max_send_wr = 256;
-	opts->max_recv_wr = 1024;
-	opts->avg_send_size = 1024;
-	opts->recv_bufsize = 256;
-	opts->recv_threshold = 1 * 1024 * 1024;
+	opts->max_send_wr = IBW_MAX_SEND_WR;
+	opts->max_recv_wr = IBW_MAX_RECV_WR;
+	opts->recv_bufsize = IBW_RECV_BUFSIZE;
+	opts->recv_threshold = IBW_RECV_THRESHOLD;
 
 	for(i=0; i<nattr; i++) {
 		name = attr[i].name;
@@ -801,8 +840,6 @@
 			opts->max_send_wr = atoi(value);
 		else if (strcmp(name, "max_recv_wr")==0)
 			opts->max_recv_wr = atoi(value);
-		else if (strcmp(name, "avg_send_size")==0)
-			opts->avg_send_size = atoi(value);
 		else if (strcmp(name, "recv_bufsize")==0)
 			opts->recv_bufsize = atoi(value);
 		else if (strcmp(name, "recv_threshold")==0)
@@ -1003,7 +1040,7 @@
 
 	rc = rdma_disconnect(pconn->cm_id);
 	if (rc) {
-		sprintf(ibw_lasterr, "ibw_disconnect failed with %d", rc);
+		sprintf(ibw_lasterr, "ibw_disconnect failed with %d\n", rc);
 		DEBUG(0, (ibw_lasterr));
 		return rc;
 	}
@@ -1023,15 +1060,15 @@
 		DLIST_REMOVE(pconn->wr_list_avail, p);
 		DLIST_ADD(pconn->wr_list_used, p);
 
-		if (len <= pctx->opts.avg_send_size) {
-			*buf = (void *)p->msg;
+		if (len <= pctx->opts.recv_bufsize) {
+			*buf = (void *)p->buf;
 		} else {
-			p->msg_large = ibw_alloc_mr(pctx, pconn, len, &p->mr_large);
-			if (!p->msg_large) {
+			p->buf_large = ibw_alloc_mr(pctx, pconn, len, &p->mr_large);
+			if (p->buf_large==NULL) {
 				sprintf(ibw_lasterr, "ibw_alloc_mr#1 failed\n");
 				goto error;
 			}
-			*buf = (void *)p->msg_large;
+			*buf = (void *)p->buf_large;
 		}
 		/* p->wr_id is already filled in ibw_init_memory */
 	} else {
@@ -1041,7 +1078,7 @@
 		if (!p) {
 			p = pconn->extra_avail = talloc_zero(pconn, struct ibw_wr);
 			if (p==NULL) {
-				sprintf(ibw_lasterr, "talloc_zero failed (emax: %u)", pconn->extra_max);
+				sprintf(ibw_lasterr, "talloc_zero failed (emax: %u)\n", pconn->extra_max);
 				goto error;
 			}
 			p->wr_id = pctx->opts.max_send_wr + pconn->extra_max;
@@ -1054,40 +1091,42 @@
 				default: break;
 			}
 		}
+
+		p->buf_large = ibw_alloc_mr(pctx, pconn, len, &p->mr_large);
+		if (p->buf_large==NULL) {
+			sprintf(ibw_lasterr, "ibw_alloc_mr#2 failed\n");
+			goto error;
+		}
+		*buf = (void *)p->buf_large;
+
 		DLIST_REMOVE(pconn->extra_avail, p);
-
-		p->msg_large = ibw_alloc_mr(pctx, pconn, len, &p->mr_large);
-		if (!p->msg_large) {
-			sprintf(ibw_lasterr, "ibw_alloc_mr#2 failed");
-			goto error;
-		}
-		*buf = (void *)p->msg_large;
+		/* we don't have prepared index for this, so that
+		 * we will have to find this by wr_id later on */
+		DLIST_ADD(pconn->extra_sent, p);
 	}
 
 	*key = (void *)p;
 
 	return 0;
 error:
-	DEBUG(0, ("ibw_alloc_send_buf error: %s\n", ibw_lasterr));
+	DEBUG(0, ("ibw_alloc_send_buf error: %s", ibw_lasterr));
 	return -1;
 }
 
 
-int ibw_send(struct ibw_conn *conn, void *buf, void *key, uint32_t len)
+static int ibw_send_packet(struct ibw_conn *conn, void *buf, struct ibw_wr *p, uint32_t len)
 {
 	struct ibw_ctx_priv *pctx = talloc_get_type(conn->ctx->internal, struct ibw_ctx_priv);
 	struct ibw_conn_priv *pconn = talloc_get_type(conn->internal, struct ibw_conn_priv);
-	struct ibw_wr *p = talloc_get_type(key, struct ibw_wr);
 	int	rc;
 
-	*((uint32_t *)buf) = htonl(len);
-
 	/* can we send it right now? */
 	if (pconn->wr_sent<pctx->opts.max_send_wr) {
+		struct ibv_send_wr *bad_wr;
 		struct ibv_sge list = {
-			.addr 	= (uintptr_t) NULL,
+			.addr 	= (uintptr_t)buf,
 			.length = len,
-			.lkey 	= 0
+			.lkey 	= pconn->mr_send->lkey
 		};
 		struct ibv_send_wr wr = {
 			.wr_id 	    = p->wr_id + pctx->opts.max_recv_wr,
@@ -1096,16 +1135,13 @@
 			.opcode     = IBV_WR_SEND,
 			.send_flags = IBV_SEND_SIGNALED,
 		};
-		struct ibv_send_wr *bad_wr;
-
-		DEBUG(10, ("ibw_send#1(cmid: %p, wrid: %u, n: %d)\n",
-			pconn->cm_id, (uint32_t)wr.wr_id, len));
-
-		list.addr = (uintptr_t)buf;
-		if (p->msg_large==NULL) {
-			list.lkey = pconn->mr_send->lkey;
+
+		if (p->buf_large==NULL) {
+			DEBUG(10, ("ibw_send#normal(cmid: %p, wrid: %u, n: %d)\n",
+				pconn->cm_id, (uint32_t)wr.wr_id, len));
 		} else {
-			assert(p->mr_large!=NULL);
+			DEBUG(10, ("ibw_send#large(cmid: %p, wrid: %u, n: %d)\n",
+				pconn->cm_id, (uint32_t)wr.wr_id, len));
 			list.lkey = p->mr_large->lkey;
 		}
 
@@ -1113,26 +1149,72 @@
 		if (rc) {
 			sprintf(ibw_lasterr, "ibv_post_send error %d (%d)\n",
 				rc, pconn->wr_sent);
-			DEBUG(0, (ibw_lasterr));
-		} else {
-			/* good case */
-			if (p->wr_id>=pctx->opts.max_send_wr) {
-				/* we don't have prepared index for this, so that
-				 * we will have to find this later on */
-				DLIST_ADD(pconn->extra_sent, p);
-			}
-			pconn->wr_sent++;
+			goto error;
 		}
+
+		pconn->wr_sent++;
+
 		return rc;
 	} /* else put the request into our own queue: */
 
-	DEBUG(10, ("ibw_send#2(cmid: %p, len: %u)\n", pconn->cm_id, len));
+	DEBUG(10, ("ibw_send#queued(cmid: %p, len: %u)\n", pconn->cm_id, len));
 
 	/* to be sent by ibw_wc_send */
-	DLIST_ADD_END(pconn->queue, p, struct ibw_wr *); /* TODO: optimize */
-	p->queued_msg = buf;
+	/* regardless "normal" or [a part of] "large" packet */
+	if (!p->queued_ref_cnt) {
+		DLIST_ADD_END2(pconn->queue, p, struct ibw_wr *,
+			qprev, qnext); /* TODO: optimize */
+		p->queued_msg = buf;
+	}
+	p->queued_ref_cnt++;
+	p->queued_rlen = len; /* last wins; see ibw_wc_send */
 
 	return 0;
+error:
+	DEBUG(0, (ibw_lasterr));
+	return -1;
+}
+
+int ibw_send(struct ibw_conn *conn, void *buf, void *key, uint32_t len)
+{
+	struct ibw_ctx_priv *pctx = talloc_get_type(conn->ctx->internal, struct ibw_ctx_priv);
+	struct ibw_wr *p = talloc_get_type(key, struct ibw_wr);
+	int	rc;
+
+	assert(len>=sizeof(uint32_t));
+	*((uint32_t *)buf) = htonl(len);
+
+	if (len > pctx->opts.recv_bufsize) {
+		struct ibw_conn_priv *pconn = talloc_get_type(conn->internal, struct ibw_conn_priv);
+		int	rlen = len;
+		char	*packet = (char *)buf;
+		uint32_t	recv_bufsize = pctx->opts.recv_bufsize;
+
+		DEBUG(10, ("ibw_send#frag(cmid: %p, buf: %p, len: %u)\n",
+			pconn->cm_id, buf, len));
+
+		/* single threaded => no race here: */
+		assert(p->ref_cnt==0);
+		while(rlen > recv_bufsize) {
+			rc = ibw_send_packet(conn, packet, p, recv_bufsize);
+			if (rc)
+				return rc;
+			packet += recv_bufsize;
+			rlen -= recv_bufsize;
+			p->ref_cnt++; /* not good to have it in ibw_send_packet */
+		}
+		if (rlen) {
+			rc = ibw_send_packet(conn, packet, p, rlen);
+			p->ref_cnt++; /* not good to have it in ibw_send_packet */
+		}
+		p->ref_cnt--; /* for the same handling */
+	} else {
+		assert(p->ref_cnt==0);
+		assert(p->queued_ref_cnt==0);
+
+		rc = ibw_send_packet(conn, buf, p, len);
+	}
+	return rc;
 }
 
 int ibw_cancel_send_buf(struct ibw_conn *conn, void *buf, void *key)
@@ -1145,8 +1227,8 @@
 	assert(buf!=NULL);
 	assert(conn!=NULL);
 
-	if (p->msg_large)
-		ibw_free_mr(&p->msg_large, &p->mr_large);
+	if (p->buf_large!=NULL)
+		ibw_free_mr(&p->buf_large, &p->mr_large);
 
 	/* parallel case */
 	if (p->wr_id < pctx->opts.max_send_wr) {
@@ -1155,6 +1237,7 @@
 		DLIST_ADD(pconn->wr_list_avail, p);
 	} else { /* "extra" packet */
 		DEBUG(10, ("ibw_cancel_send_buf#2 %u", (int)p->wr_id));
+		DLIST_REMOVE(pconn->extra_sent, p);
 		DLIST_ADD(pconn->extra_avail, p);
 	}
 

=== modified file 'ib/ibwrapper_internal.h'
--- a/ib/ibwrapper_internal.h	2007-01-25 10:01:59 +0000
+++ b/ib/ibwrapper_internal.h	2007-02-08 18:06:14 +0000
@@ -24,21 +24,25 @@
 struct ibw_opts {
 	uint32_t	max_send_wr;
 	uint32_t	max_recv_wr;
-	uint32_t	avg_send_size;
 	uint32_t	recv_bufsize;
 	uint32_t	recv_threshold;
 };
 
 struct ibw_wr {
-	char	*msg; /* initialized in ibw_init_memory once per connection */
+	char	*buf; /* initialized in ibw_init_memory once per connection */
 	int	wr_id; /* position in wr_index list; also used as wr id */
 
-	char	*msg_large; /* allocated specially for "large" message */
+	char	*buf_large; /* allocated specially for "large" message */
 	struct ibv_mr *mr_large;
+	int	ref_cnt; /* reference count for ibw_wc_send to know when to release */
 
 	char	*queued_msg; /* set at ibw_send - can be different than above */
+	int	queued_ref_cnt; /* instead of adding the same to the queue again */
+	uint32_t	queued_rlen; /* last wins when queued_ref_cnt>0; or simple msg size */
 
 	struct ibw_wr *next, *prev; /* in wr_list_avail or wr_list_used */
+				/* or extra_sent or extra_avail */
+	struct ibw_wr *qnext, *qprev; /* in queue */
 };
 
 struct ibw_ctx_priv {
@@ -81,11 +85,12 @@
 	struct ibw_wr **wr_index; /* array[0..(qsize-1)] of (ibw_wr *) */
 	int	wr_sent; /* # of send wrs in the CQ */
 
-	struct ibw_wr *queue;
 	struct ibw_wr *extra_sent;
 	struct ibw_wr *extra_avail;
 	int	extra_max; /* max wr_id in the queue */
 
+	struct ibw_wr *queue;
+
 	/* buf_recv is a ring buffer */
 	char *buf_recv; /* max_recv_wr * avg_recv_size */
 	struct ibv_mr *mr_recv;
@@ -93,3 +98,30 @@
 	struct ibw_part part;
 };
 
+/* remove an element from a list - element doesn't have to be in list. */
+#define DLIST_REMOVE2(list, p, prev, next) \
+do { \
+	if ((p) == (list)) { \
+		(list) = (p)->next; \
+		if (list) (list)->prev = NULL; \
+	} else { \
+		if ((p)->prev) (p)->prev->next = (p)->next; \
+		if ((p)->next) (p)->next->prev = (p)->prev; \
+	} \
+	if ((p) != (list)) (p)->next = (p)->prev = NULL; \
+} while (0)
+
+/* hook into the end of the list - needs a tmp pointer */
+#define DLIST_ADD_END2(list, p, type, prev, next) \
+do { \
+		if (!(list)) { \
+			(list) = (p); \
+			(p)->next = (p)->prev = NULL; \
+		} else { \
+			type tmp; \
+			for (tmp = (list); tmp->next; tmp = tmp->next) ; \
+			tmp->next = (p); \
+			(p)->next = NULL; \
+			(p)->prev = tmp; \
+		} \
+} while (0)

=== modified file 'tests/ibwrapper_test.c'
--- a/tests/ibwrapper_test.c	2007-02-02 17:54:57 +0000
+++ b/tests/ibwrapper_test.c	2007-02-08 18:06:14 +0000
@@ -223,7 +223,7 @@
 	for(i=0; i<tcx->nmsg; i++)
 	{
 		//size = (uint32_t)((float)(tcx->maxsize) * (rand() / (RAND_MAX + 1.0)));
-		size = (uint32_t)((float)(tcx->maxsize) * ((float)i/(float)tcx->nmsg));
+		size = (uint32_t)((float)(tcx->maxsize) * ((float)(i+1)/(float)tcx->nmsg));
 		if (ibwtest_do_varsize_scenario_conn_size(tcx, conn, size))
 			return -1;
 	}



More information about the samba-cvs mailing list