]> git.openfabrics.org - ~shefty/libmlx4.git/commitdiff
Handle freeing doorbell records
authorRoland Dreier <rolandd@cisco.com>
Tue, 22 May 2007 21:13:15 +0000 (14:13 -0700)
committerRoland Dreier <rolandd@cisco.com>
Tue, 22 May 2007 21:18:12 +0000 (14:18 -0700)
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 <rolandd@cisco.com>
src/dbrec.c
src/mlx4.h
src/verbs.c

index 9cff0d8a55cc8ef326acd30ddf0e7bebaa4300d2..e59bc9e6565ee260732ec1c438d20d5e1165af58 100644 (file)
@@ -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);
 }
index 7978f9fcc235ee06c9e8f363d92d7f5050719e08..3c7b2cf73bdb36cd6794359d83ad65e4acf93e99 100644 (file)
@@ -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);
index 41914ac32abe3c15e5cde952fc4a5fafafa38d86..54c796b6b5ab659d49063f63f10089810ce640bc 100644 (file)
@@ -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);