Good points... I've updated my patch as below:

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..febf32a 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,46 @@ 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);
+       struct ibv_context *context;
+       int ret;
+
+       context = channel->context;
+       pthread_mutex_lock(&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(&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 +289,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 +306,21 @@ default_symver(__ibv_resize_cq, ibv_resize_cq);
 
 int __ibv_destroy_cq(struct ibv_cq *cq)
 {
-       return cq->context->ops.destroy_cq(cq);
+       struct ibv_comp_channel *channel = cq->channel;
+       int ret;
+
+       if (channel)
+               pthread_mutex_lock(&channel->context->mutex);
+
+       ret = cq->context->ops.destroy_cq(cq);
+
+       if (channel) {
+               if (!ret)
+                       --channel->refcnt;
+               pthread_mutex_unlock(&channel->context->mutex);
+       }
+
+       return ret;
 }
 default_symver(__ibv_destroy_cq, ibv_destroy_cq);
 
_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to