aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Dreier <rolandd@cisco.com>2006-01-30 22:32:43 +0000
committerRoland Dreier <rolandd@cisco.com>2006-11-09 19:57:05 -0800
commit96852fb5c750e5ca6b063e91586e5485238d2bd1 (patch)
treed8e5bf5624ceb1d87df1141a5da3cff8c9b060cd
parentc8c69760742d85872617e66ee7334a9d1df1b8dc (diff)
downloadlibmthca-96852fb5c750e5ca6b063e91586e5485238d2bd1.tar.gz
libmthca implementation of resizing CQs
Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--ChangeLog7
-rw-r--r--src/cq.c36
-rw-r--r--src/mthca-abi.h7
-rw-r--r--src/mthca.c2
-rw-r--r--src/mthca.h6
-rw-r--r--src/verbs.c87
6 files changed, 128 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 8514a07..ed6a6b5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2006-01-26 Roland Dreier <rdreier@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@cisco.com>
* Release version 1.0-rc5.
diff --git a/src/cq.c b/src/cq.c
index 167b173..cc7722a 100644
--- a/src/cq.c
+++ b/src/cq.c
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Mellanox Technologies Ltd. All rights reserved.
+ * Copyright (c) 2006 Cisco Systems. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -38,8 +39,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 +580,38 @@ void mthca_cq_clean(struct mthca_cq *cq, uint32_t qpn, struct mthca_srq *srq)
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;
}
diff --git a/src/mthca-abi.h b/src/mthca-abi.h
index b760616..e9229c6 100644
--- a/src/mthca-abi.h
+++ b/src/mthca-abi.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
+ * Copyright (c) 2006 Cisco Systems. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -65,6 +66,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;
diff --git a/src/mthca.c b/src/mthca.c
index 31c3941..26c0d85 100644
--- a/src/mthca.c
+++ b/src/mthca.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
+ * Copyright (c) 2006 Cisco Systems. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -105,6 +106,7 @@ static struct ibv_context_ops mthca_ctx_ops = {
.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,
diff --git a/src/mthca.h b/src/mthca.h
index 152c0e7..7eb41d2 100644
--- a/src/mthca.h
+++ b/src/mthca.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
- * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -281,6 +281,7 @@ extern int mthca_dereg_mr(struct ibv_mr *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_cq *cq, int solicited);
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);
diff --git a/src/verbs.c b/src/verbs.c
index 99dbc6b..95f7d6b 100644
--- a/src/verbs.c
+++ b/src/verbs.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2005 Topspin Communications. All rights reserved.
- * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -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 ibv_context *context, int cqe,
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 ibv_context *context, int cqe,
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;