[ofa-general] Re: [PATCH V2 - libibverbs] Added reference count to completion event channels
Roland Dreier
rdreier at cisco.com
Mon Mar 26 15:17:08 PDT 2007
OK, I got bored and tried to implement this using a mutex in the
ibv_context structure. How does this (compile tested only) patch
look?
- R.
diff --git a/include/infiniband/verbs.h b/include/infiniband/verbs.h
index 2ae50ab..acc1b82 100644
--- a/include/infiniband/verbs.h
+++ b/include/infiniband/verbs.h
@@ -573,11 +573,14 @@ struct ibv_qp {
};
struct ibv_comp_channel {
+ struct ibv_context *context;
int fd;
+ int refcnt;
};
struct ibv_cq {
struct ibv_context *context;
+ struct ibv_comp_channel *channel;
void *cq_context;
uint32_t handle;
int cqe;
@@ -680,12 +683,13 @@ struct ibv_context_ops {
};
struct ibv_context {
- struct ibv_device *device;
- struct ibv_context_ops ops;
- int cmd_fd;
- int async_fd;
- int num_comp_vectors;
- void *abi_compat;
+ struct ibv_device *device;
+ struct ibv_context_ops ops;
+ int cmd_fd;
+ int async_fd;
+ int num_comp_vectors;
+ pthread_mutex_t mutex;
+ void *abi_compat;
};
/**
diff --git a/src/cmd.c b/src/cmd.c
index f7d3fde..a0bfaad 100644
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -75,7 +75,9 @@ static int ibv_cmd_get_context_v2(struct ibv_context *context,
context->async_fd = resp->async_fd;
context->num_comp_vectors = 1;
+ t->channel.context = context;
t->channel.fd = cq_fd;
+ t->channel.refcnt = 0;
context->abi_compat = t;
return 0;
diff --git a/src/device.c b/src/device.c
index bca1ce9..3abc1eb 100644
--- a/src/device.c
+++ b/src/device.c
@@ -138,6 +138,7 @@ struct ibv_context *__ibv_open_device(struct ibv_device *device)
context->device = device;
context->cmd_fd = cmd_fd;
+ pthread_mutex_init(&context->mutex, NULL);
return context;
diff --git a/src/verbs.c b/src/verbs.c
index 56513e4..5334af1 100644
--- a/src/verbs.c
+++ b/src/verbs.c
@@ -226,7 +226,9 @@ struct ibv_comp_channel *ibv_create_comp_channel(struct ibv_context *context)
return NULL;
}
- channel->fd = resp.fd;
+ channel->context = context;
+ channel->fd = resp.fd;
+ channel->refcnt = 0;
return channel;
}
@@ -240,23 +242,44 @@ static int ibv_destroy_comp_channel_v2(struct ibv_comp_channel *channel)
int ibv_destroy_comp_channel(struct ibv_comp_channel *channel)
{
- if (abi_ver <= 2)
- return ibv_destroy_comp_channel_v2(channel);
+ int ret;
+
+ pthread_mutex_lock(&channel->context->mutex);
+
+ if (channel->refcnt) {
+ ret = EBUSY;
+ goto out;
+ }
+
+ if (abi_ver <= 2) {
+ ret = ibv_destroy_comp_channel_v2(channel);
+ goto out;
+ }
close(channel->fd);
free(channel);
+ ret = 0;
- return 0;
+out:
+ pthread_mutex_unlock(&channel->context->mutex);
+
+ return ret;
}
struct ibv_cq *__ibv_create_cq(struct ibv_context *context, int cqe, void *cq_context,
struct ibv_comp_channel *channel, int comp_vector)
{
- struct ibv_cq *cq = context->ops.create_cq(context, cqe, channel,
- comp_vector);
+ struct ibv_cq *cq;
+
+ pthread_mutex_lock(&context->mutex);
+
+ cq = context->ops.create_cq(context, cqe, channel, comp_vector);
if (cq) {
cq->context = context;
+ cq->channel = channel;
+ if (channel)
+ ++channel->refcnt;
cq->cq_context = cq_context;
cq->comp_events_completed = 0;
cq->async_events_completed = 0;
@@ -264,6 +287,8 @@ struct ibv_cq *__ibv_create_cq(struct ibv_context *context, int cqe, void *cq_co
pthread_cond_init(&cq->cond, NULL);
}
+ pthread_mutex_unlock(&context->mutex);
+
return cq;
}
default_symver(__ibv_create_cq, ibv_create_cq);
@@ -279,7 +304,17 @@ default_symver(__ibv_resize_cq, ibv_resize_cq);
int __ibv_destroy_cq(struct ibv_cq *cq)
{
- return cq->context->ops.destroy_cq(cq);
+ int ret;
+
+ pthread_mutex_lock(&cq->context->mutex);
+
+ ret = cq->context->ops.destroy_cq(cq);
+ if (cq->channel && !ret)
+ --cq->channel->refcnt;
+
+ pthread_mutex_unlock(&cq->context->mutex);
+
+ return ret;
}
default_symver(__ibv_destroy_cq, ibv_destroy_cq);
More information about the general
mailing list