aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Dreier <rolandd@cisco.com>2007-05-22 14:13:15 -0700
committerRoland Dreier <rolandd@cisco.com>2007-05-22 14:18:12 -0700
commitc679957f6c339110d1821df1a6285894effa844a (patch)
tree75f37b813954682f71453370dc70cfdbb9d8c04c
parent4a0bfc1f592d54724798794fb24e316cdb4b937a (diff)
downloadlibmlx4-c679957f6c339110d1821df1a6285894effa844a.tar.gz
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 <rolandd@cisco.com>
-rw-r--r--src/dbrec.c47
-rw-r--r--src/mlx4.h2
-rw-r--r--src/verbs.c12
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);