diff options
author | Roland Dreier <rolandd@cisco.com> | 2006-01-30 22:32:43 +0000 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2006-11-09 19:57:05 -0800 |
commit | 96852fb5c750e5ca6b063e91586e5485238d2bd1 (patch) | |
tree | d8e5bf5624ceb1d87df1141a5da3cff8c9b060cd | |
parent | c8c69760742d85872617e66ee7334a9d1df1b8dc (diff) | |
download | libmthca-96852fb5c750e5ca6b063e91586e5485238d2bd1.tar.gz |
libmthca implementation of resizing CQs
Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | src/cq.c | 36 | ||||
-rw-r--r-- | src/mthca-abi.h | 7 | ||||
-rw-r--r-- | src/mthca.c | 2 | ||||
-rw-r--r-- | src/mthca.h | 6 | ||||
-rw-r--r-- | src/verbs.c | 87 |
6 files changed, 128 insertions, 17 deletions
@@ -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. @@ -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; |