[openib-general] [PATCH] SEND_INLINE support in libmthca

Michael S. Tsirkin mst at mellanox.co.il
Mon Apr 4 08:02:35 PDT 2005


Adds support for posting SEND_INLINE work requests in libmthca.
With this patch, I get latency as low as 3.35 usec unidirectional
with Arbel Tavor mode. Passed basic testing on Tavor and Arbel mode.

Signed-off-by: Michael S. Tsirkin <mst at mellanox.co.il>

Index: src/qp.c
===================================================================
--- src/qp.c	(revision 2104)
+++ src/qp.c	(working copy)
@@ -57,6 +57,10 @@ enum {
 	MTHCA_NEXT_SOLICIT   = 1 << 1,
 };
 
+enum {
+	MTHCA_INLINE_SEG = 1<<31
+};
+
 struct mthca_next_seg {
 	uint32_t	nda_op;	/* [31:6] next WQE [4:0] next opcode */
 	uint32_t	ee_nds;	/* [31:8] next EE  [7] DBD [6] F [5:0] next WQE size */
@@ -107,6 +111,10 @@ struct mthca_data_seg {
 	uint64_t	addr;
 };
 
+struct mthca_inline_seg {
+	uint32_t	byte_count;
+};
+
 static const uint8_t mthca_opcode[] = {
 	[IBV_WR_SEND]                 = MTHCA_OPCODE_SEND,
 	[IBV_WR_SEND_WITH_IMM]        = MTHCA_OPCODE_SEND_IMM,
@@ -255,15 +263,38 @@ int mthca_tavor_post_send(struct ibv_qp 
 			goto out;
 		}
 
-		for (i = 0; i < wr->num_sge; ++i) {
-			((struct mthca_data_seg *) wqe)->byte_count =
-				htonl(wr->sg_list[i].length);
-			((struct mthca_data_seg *) wqe)->lkey =
-				htonl(wr->sg_list[i].lkey);
-			((struct mthca_data_seg *) wqe)->addr =
-				htonll(wr->sg_list[i].addr);
-			wqe += sizeof (struct mthca_data_seg);
-			size += sizeof (struct mthca_data_seg) / 16;
+		if (wr->send_flags & IBV_SEND_INLINE) {
+			struct mthca_inline_seg *seg = wqe;
+			int s = 0;
+			wqe += sizeof *seg;
+			for (i = 0; i < wr->num_sge; ++i) {
+				struct ibv_sge *sge = &wr->sg_list[i];
+				int l;
+				l = sge->length;
+				s += l;
+
+				if (s + sizeof *seg > (1 << qp->sq.wqe_shift)) {
+					ret = -1;
+					*bad_wr = wr;
+					goto out;
+				}
+
+				memcpy(wqe, (void*)(intptr_t)sge->addr, l);
+				wqe += l;
+			}
+			seg->byte_count = htonl(MTHCA_INLINE_SEG | s);
+
+			size += align(s + sizeof *seg, 16) / 16;
+		} else {
+			struct mthca_data_seg *seg;
+			for (i = 0; i < wr->num_sge; ++i) {
+				seg = wqe;
+				seg->byte_count = htonl(wr->sg_list[i].length);
+				seg->lkey = htonl(wr->sg_list[i].lkey);
+				seg->addr = htonll(wr->sg_list[i].addr);
+				wqe += sizeof *seg;
+			}
+			size += wr->num_sge * sizeof *seg / 16;
 		}
 
 		qp->wrid[ind + qp->rq.max] = wr->wr_id;
@@ -512,15 +543,37 @@ int mthca_arbel_post_send(struct ibv_qp 
 			goto out;
 		}
 
-		for (i = 0; i < wr->num_sge; ++i) {
-			((struct mthca_data_seg *) wqe)->byte_count =
-				htonl(wr->sg_list[i].length);
-			((struct mthca_data_seg *) wqe)->lkey =
-				htonl(wr->sg_list[i].lkey);
-			((struct mthca_data_seg *) wqe)->addr =
-				htonll(wr->sg_list[i].addr);
-			wqe += sizeof (struct mthca_data_seg);
-			size += sizeof (struct mthca_data_seg) / 16;
+		if (wr->send_flags & IBV_SEND_INLINE) {
+			struct mthca_inline_seg *seg = wqe;
+			int s = 0;
+			wqe += sizeof *seg;
+			for (i = 0; i < wr->num_sge; ++i) {
+				int l = wr->sg_list[i].length;
+				s += l;
+
+				if (s + sizeof *seg > (1 << qp->sq.wqe_shift)) {
+					ret = -1;
+					*bad_wr = wr;
+					goto out;
+				}
+
+				memcpy(wqe,
+				       (void*)(intptr_t)wr->sg_list[i].addr, l);
+				wqe += l;
+			}
+			seg->byte_count = htonl(MTHCA_INLINE_SEG | s);
+
+			size += align(s + sizeof *seg, 16) / 16;
+		} else {
+			struct mthca_data_seg *seg;
+			for (i = 0; i < wr->num_sge; ++i) {
+				seg = wqe;
+				seg->byte_count = htonl(wr->sg_list[i].length);
+				seg->lkey = htonl(wr->sg_list[i].lkey);
+				seg->addr = htonll(wr->sg_list[i].addr);
+				wqe += sizeof *seg;
+			}
+			size += wr->num_sge * sizeof *seg / 16;
 		}
 
 		qp->wrid[ind + qp->rq.max] = wr->wr_id;
-- 
MST - Michael S. Tsirkin



More information about the general mailing list