From c679957f6c339110d1821df1a6285894effa844a Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 22 May 2007 14:13:15 -0700 Subject: [PATCH] Handle freeing doorbell records Actually implement mlx4_free_db() that just naively searches through all doorbell pages. Also add a doorbell type parameter to the function to avoid searching through all CQ doorbell pages when we really want to find an RQ doorbell. Signed-off-by: Roland Dreier --- src/dbrec.c | 47 ++++++++++++++++++++++++++++++++++++++--------- src/mlx4.h | 2 +- src/verbs.c | 12 ++++++------ 3 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/dbrec.c b/src/dbrec.c index 9cff0d8..e59bc9e 100644 --- a/src/dbrec.c +++ b/src/dbrec.c @@ -46,7 +46,7 @@ struct mlx4_db_page { struct mlx4_buf buf; int num_db; int use_cnt; - unsigned free[0]; + unsigned long free[0]; }; static const int db_size[] = { @@ -58,24 +58,24 @@ static struct mlx4_db_page *__add_page(struct mlx4_context *context, enum mlx4_db_type type) { struct mlx4_db_page *page; + int ps = to_mdev(context->ibv_ctx.device)->page_size; int pp; int i; - pp = to_mdev(context->ibv_ctx.device)->page_size / db_size[type]; + pp = ps / db_size[type]; page = malloc(sizeof *page + pp / 8); if (!page) return NULL; - if (mlx4_alloc_buf(&page->buf, to_mdev(context->ibv_ctx.device)->page_size, - to_mdev(context->ibv_ctx.device)->page_size)) { + if (mlx4_alloc_buf(&page->buf, ps, ps)) { free(page); return NULL; } page->num_db = pp; page->use_cnt = 0; - for (i = 0; i < pp / (sizeof (int) * 8); ++i) + for (i = 0; i < pp / (sizeof (long) * 8); ++i) page->free[i] = ~0; page->prev = NULL; @@ -109,9 +109,9 @@ found: for (i = 0; !page->free[i]; ++i) /* nothing */; - j = ffs(page->free[i]); + j = ffsl(page->free[i]); page->free[i] &= ~(1 << (j - 1)); - db = page->buf.buf + (i * 8 * sizeof (int) + (j - 1)) * db_size[type]; + db = page->buf.buf + (i * 8 * sizeof (long) + (j - 1)) * db_size[type]; out: pthread_mutex_unlock(&context->db_list_mutex); @@ -119,7 +119,36 @@ out: return db; } -void mlx4_free_db(struct mlx4_context *context, uint32_t *db) +void mlx4_free_db(struct mlx4_context *context, enum mlx4_db_type type, uint32_t *db) { - /*XXX nothing for now*/ + struct mlx4_db_page *page; + uintptr_t ps = to_mdev(context->ibv_ctx.device)->page_size; + int i; + + pthread_mutex_lock(&context->db_list_mutex); + + for (page = context->db_list[type]; page; page = page->next) + if (((uintptr_t) db & ~(ps - 1)) == (uintptr_t) page->buf.buf) + break; + + if (!page) + goto out; + + i = ((void *) db - page->buf.buf) / db_size[type]; + page->free[i / (8 * sizeof (long))] |= 1 << (i % (8 * sizeof (long))); + + if (!--page->use_cnt) { + if (page->prev) + page->prev->next = page->next; + else + context->db_list[type] = page->next; + if (page->next) + page->next->prev = page->prev; + + mlx4_free_buf(&page->buf); + free(page); + } + +out: + pthread_mutex_unlock(&context->db_list_mutex); } diff --git a/src/mlx4.h b/src/mlx4.h index 7978f9f..3c7b2cf 100644 --- a/src/mlx4.h +++ b/src/mlx4.h @@ -288,7 +288,7 @@ int mlx4_alloc_buf(struct mlx4_buf *buf, size_t size, int page_size); void mlx4_free_buf(struct mlx4_buf *buf); uint32_t *mlx4_alloc_db(struct mlx4_context *context, enum mlx4_db_type type); -void mlx4_free_db(struct mlx4_context *context, uint32_t *db); +void mlx4_free_db(struct mlx4_context *context, enum mlx4_db_type type, uint32_t *db); int mlx4_query_device(struct ibv_context *context, struct ibv_device_attr *attr); diff --git a/src/verbs.c b/src/verbs.c index 41914ac..54c796b 100644 --- a/src/verbs.c +++ b/src/verbs.c @@ -213,7 +213,7 @@ struct ibv_cq *mlx4_create_cq(struct ibv_context *context, int cqe, return &cq->ibv_cq; err_db: - mlx4_free_db(to_mctx(context), cq->set_ci_db); + mlx4_free_db(to_mctx(context), MLX4_DB_TYPE_CQ, cq->set_ci_db); err_buf: mlx4_free_buf(&cq->buf); @@ -238,7 +238,7 @@ int mlx4_destroy_cq(struct ibv_cq *cq) if (ret) return ret; - mlx4_free_db(to_mctx(cq->context), to_mcq(cq)->set_ci_db); + mlx4_free_db(to_mctx(cq->context), MLX4_DB_TYPE_CQ, to_mcq(cq)->set_ci_db); mlx4_free_buf(&to_mcq(cq)->buf); free(to_mcq(cq)); @@ -308,7 +308,7 @@ struct ibv_srq *mlx4_create_srq(struct ibv_pd *pd, return &srq->ibv_srq; err_db: - mlx4_free_db(to_mctx(pd->context), srq->db); + mlx4_free_db(to_mctx(pd->context), MLX4_DB_TYPE_RQ, srq->db); err_free: free(srq->wrid); @@ -345,7 +345,7 @@ int mlx4_destroy_srq(struct ibv_srq *srq) if (ret) return ret; - mlx4_free_db(to_mctx(srq->context), to_msrq(srq)->db); + mlx4_free_db(to_mctx(srq->context), MLX4_DB_TYPE_RQ, to_msrq(srq)->db); mlx4_free_buf(&to_msrq(srq)->buf); free(to_msrq(srq)->wrid); free(to_msrq(srq)); @@ -424,7 +424,7 @@ err_destroy: ibv_cmd_destroy_qp(&qp->ibv_qp); err_rq_db: - mlx4_free_db(to_mctx(pd->context), qp->db); + mlx4_free_db(to_mctx(pd->context), MLX4_DB_TYPE_RQ, qp->db); err_free: free(qp->sq.wrid); @@ -523,7 +523,7 @@ int mlx4_destroy_qp(struct ibv_qp *ibqp) return ret; } - mlx4_free_db(to_mctx(ibqp->context), qp->db); + mlx4_free_db(to_mctx(ibqp->context), MLX4_DB_TYPE_RQ, qp->db); free(qp->sq.wrid); free(qp->rq.wrid); mlx4_free_buf(&qp->buf); -- 2.46.0