[openib-general] [PATCH] SEND_INLINE support in libmthca
Michael S. Tsirkin
mst at mellanox.co.il
Tue Apr 5 00:42:13 PDT 2005
Quoting r. Roland Dreier <roland at topspin.com>:
> Subject: Re: [openib-general] [PATCH] SEND_INLINE support in libmthca
>
> Is the test here correct?
>
> + if (s + sizeof *seg > (1 << qp->sq.wqe_shift)) {
> It seems we need to take into account the size of next segment and any
> RDMA segment that we may be posting as well.
Right. Fixed (below).
> Also does it make sense to put the code for gathering inline data
> segments and writing gather lists into an inline function that can be
> called from both the tavor and arbel post send function? Will gcc
> actually inline this function?
>
> - R.
>
It does get inlined, but the function would have to return
both size and status, so however I rearrange it I get either extra loads/stores
or extra branches.
Inline data support for libmthca (important for latency).
Signed-off-by: Michael S. Tsirkin <mst at mellanox.co.il>
Index: src/qp.c
===================================================================
--- src/qp.c (revision 2096)
+++ 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,39 @@ 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 wqe_size = 1 << qp->sq.wqe_shift;
+ 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 + size * 16 > wqe_size) {
+ 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 +544,39 @@ 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 wqe_size = 1 << qp->sq.wqe_shift;
+ 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 + size * 16 > wqe_size) {
+ 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;
--
MST - Michael S. Tsirkin
More information about the general
mailing list