[openib-general] [PATCH 4/5] [RFC] libmthca changes for resize CQ
Roland Dreier
rolandd at cisco.com
Thu Jan 26 11:23:33 PST 2006
libmthca implementation of resizing CQs. This is the real guts of
it -- there is some slightly tricky code to handle the transition from
the old CQ buffer to the new one.
---
--- libmthca/src/verbs.c (revision 5192)
+++ libmthca/src/verbs.c (working copy)
@@ -41,6 +41,7 @@
#include <stdio.h>
#include <strings.h>
#include <pthread.h>
+#include <errno.h>
#include <netinet/in.h>
#include "mthca.h"
@@ -154,6 +155,16 @@ int mthca_dereg_mr(struct ibv_mr *mr)
return 0;
}
+static int align_cq_size(int cqe)
+{
+ int nent;
+
+ for (nent = 1; nent <= cqe; nent <<= 1)
+ ; /* nothing */
+
+ return nent;
+}
+
struct ibv_cq *mthca_create_cq(struct ibv_context *context, int cqe,
struct ibv_comp_channel *channel,
int comp_vector)
@@ -161,27 +172,24 @@ struct ibv_cq *mthca_create_cq(struct ib
struct mthca_create_cq cmd;
struct mthca_create_cq_resp resp;
struct mthca_cq *cq;
- int nent;
int ret;
cq = malloc(sizeof *cq);
if (!cq)
return NULL;
+ cq->cons_index = 0;
+
if (pthread_spin_init(&cq->lock, PTHREAD_PROCESS_PRIVATE))
goto err;
- for (nent = 1; nent <= cqe; nent <<= 1)
- ; /* nothing */
-
- if (posix_memalign(&cq->buf, to_mdev(context->device)->page_size,
- align(nent * MTHCA_CQ_ENTRY_SIZE, to_mdev(context->device)->page_size)))
+ cqe = align_cq_size(cqe);
+ cq->buf = mthca_alloc_cq_buf(to_mdev(context->device), cqe);
+ if (!cq->buf)
goto err;
- mthca_init_cq_buf(cq, nent);
-
cq->mr = __mthca_reg_mr(to_mctx(context)->pd, cq->buf,
- nent * MTHCA_CQ_ENTRY_SIZE,
+ cqe * MTHCA_CQ_ENTRY_SIZE,
0, IBV_ACCESS_LOCAL_WRITE);
if (!cq->mr)
goto err_buf;
@@ -210,7 +218,7 @@ struct ibv_cq *mthca_create_cq(struct ib
cmd.lkey = cq->mr->lkey;
cmd.pdn = to_mpd(to_mctx(context)->pd)->pdn;
- ret = ibv_cmd_create_cq(context, nent - 1, channel, comp_vector,
+ ret = ibv_cmd_create_cq(context, cqe - 1, channel, comp_vector,
&cq->ibv_cq, &cmd.ibv_cmd, sizeof cmd,
&resp.ibv_resp, sizeof resp);
if (ret)
@@ -247,6 +255,63 @@ err:
return NULL;
}
+int mthca_resize_cq(struct ibv_cq *ibcq, int cqe)
+{
+ struct mthca_cq *cq = to_mcq(ibcq);
+ struct mthca_resize_cq cmd;
+ struct ibv_mr *mr;
+ void *buf;
+ int old_cqe;
+ int ret;
+
+ pthread_spin_lock(&cq->lock);
+
+ cqe = align_cq_size(cqe);
+ if (cqe == ibcq->cqe + 1) {
+ ret = 0;
+ goto out;
+ }
+
+ buf = mthca_alloc_cq_buf(to_mdev(ibcq->context->device), cqe);
+ if (!buf) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ mr = __mthca_reg_mr(to_mctx(ibcq->context)->pd, buf,
+ cqe * MTHCA_CQ_ENTRY_SIZE,
+ 0, IBV_ACCESS_LOCAL_WRITE);
+ if (!mr) {
+ free(buf);
+ ret = ENOMEM;
+ goto out;
+ }
+
+ mr->context = ibcq->context;
+
+ old_cqe = ibcq->cqe;
+
+ cmd.lkey = mr->lkey;
+ ret = ibv_cmd_resize_cq(ibcq, cqe - 1, &cmd.ibv_cmd, sizeof cmd);
+ if (ret) {
+ mthca_dereg_mr(mr);
+ free(buf);
+ goto out;
+ }
+
+ mthca_cq_resize_copy_cqes(cq, buf, old_cqe);
+
+ mthca_dereg_mr(cq->mr);
+ free(cq->buf);
+
+ cq->buf = buf;
+ cq->mr = mr;
+
+out:
+ pthread_spin_unlock(&cq->lock);
+ return ret;
+}
+
int mthca_destroy_cq(struct ibv_cq *cq)
{
int ret;
--- libmthca/src/mthca.h (revision 5192)
+++ libmthca/src/mthca.h (working copy)
@@ -281,6 +281,7 @@ extern int mthca_dereg_mr(struct ibv_mr
struct ibv_cq *mthca_create_cq(struct ibv_context *context, int cqe,
struct ibv_comp_channel *channel,
int comp_vector);
+extern int mthca_resize_cq(struct ibv_cq *cq, int cqe);
extern int mthca_destroy_cq(struct ibv_cq *cq);
extern int mthca_poll_cq(struct ibv_cq *cq, int ne, struct ibv_wc *wc);
extern int mthca_tavor_arm_cq(struct ibv_cq *cq, int solicited);
@@ -288,7 +289,8 @@ extern int mthca_arbel_arm_cq(struct ibv
extern void mthca_arbel_cq_event(struct ibv_cq *cq);
extern void mthca_cq_clean(struct mthca_cq *cq, uint32_t qpn,
struct mthca_srq *srq);
-extern void mthca_init_cq_buf(struct mthca_cq *cq, int nent);
+extern void mthca_cq_resize_copy_cqes(struct mthca_cq *cq, void *buf, int new_cqe);
+extern void *mthca_alloc_cq_buf(struct mthca_device *dev, int cqe);
extern struct ibv_srq *mthca_create_srq(struct ibv_pd *pd,
struct ibv_srq_init_attr *attr);
--- libmthca/src/cq.c (revision 5192)
+++ libmthca/src/cq.c (working copy)
@@ -38,8 +38,9 @@
#endif /* HAVE_CONFIG_H */
#include <stdio.h>
-#include <netinet/in.h>
+#include <stdlib.h>
#include <pthread.h>
+#include <netinet/in.h>
#include <infiniband/opcode.h>
@@ -578,12 +579,38 @@ void mthca_cq_clean(struct mthca_cq *cq,
pthread_spin_unlock(&cq->lock);
}
-void mthca_init_cq_buf(struct mthca_cq *cq, int nent)
+void mthca_cq_resize_copy_cqes(struct mthca_cq *cq, void *buf, int old_cqe)
+{
+ int i;
+
+ /*
+ * In Tavor mode, the hardware keeps the consumer and producer
+ * indices mod the CQ size. Since we might be making the CQ
+ * bigger, we need to deal with the case where the producer
+ * index wrapped around before the CQ was resized.
+ */
+ if (!mthca_is_memfree(cq->ibv_cq.context) && old_cqe < cq->ibv_cq.cqe) {
+ cq->cons_index &= old_cqe;
+ if (cqe_sw(cq, old_cqe))
+ cq->cons_index -= old_cqe + 1;
+ }
+
+ for (i = cq->cons_index; cqe_sw(cq, i & old_cqe); ++i)
+ memcpy(buf + (i & cq->ibv_cq.cqe) * MTHCA_CQ_ENTRY_SIZE,
+ get_cqe(cq, i & old_cqe), MTHCA_CQ_ENTRY_SIZE);
+}
+
+void *mthca_alloc_cq_buf(struct mthca_device *dev, int nent)
{
+ void *buf;
int i;
+ if (posix_memalign(&buf, dev->page_size,
+ align(nent * MTHCA_CQ_ENTRY_SIZE, dev->page_size)))
+ return NULL;
+
for (i = 0; i < nent; ++i)
- set_cqe_hw(get_cqe(cq, i));
+ ((struct mthca_cqe *) buf)[i].owner = MTHCA_CQ_ENTRY_OWNER_HW;
- cq->cons_index = 0;
+ return buf;
}
--- libmthca/src/mthca-abi.h (revision 5192)
+++ libmthca/src/mthca-abi.h (working copy)
@@ -65,6 +65,12 @@ struct mthca_create_cq_resp {
__u32 reserved;
};
+struct mthca_resize_cq {
+ struct ibv_resize_cq ibv_cmd;
+ __u32 lkey;
+ __u32 reserved;
+};
+
struct mthca_create_srq {
struct ibv_create_srq ibv_cmd;
__u32 lkey;
--- libmthca/src/mthca.c (revision 5192)
+++ libmthca/src/mthca.c (working copy)
@@ -105,6 +105,7 @@ static struct ibv_context_ops mthca_ctx_
.dereg_mr = mthca_dereg_mr,
.create_cq = mthca_create_cq,
.poll_cq = mthca_poll_cq,
+ .resize_cq = mthca_resize_cq,
.destroy_cq = mthca_destroy_cq,
.create_srq = mthca_create_srq,
.modify_srq = mthca_modify_srq,
--- libmthca/ChangeLog (revision 5192)
+++ libmthca/ChangeLog (working copy)
@@ -1,3 +1,10 @@
+2006-01-26 Roland Dreier <rdreier at cisco.com>
+
+ * src/mthca.h, src/verbs.c, src/cq.c, src/mthca.c: Add
+ implementation of resize CQ operation.
+
+ * src/mthca-abi.h: Add mthca-specific resize CQ ABI.
+
2006-01-22 Roland Dreier <rdreier at cisco.com>
* Release version 1.0-rc5.
More information about the general
mailing list