IB/core: Use qp->usecnt to track multicast attach/detach
Or Gerlitz [Sun, 29 Apr 2012 14:04:22 +0000 (17:04 +0300)]
Just as we don't allow PDs, CQs, etc. to be destroyed if there are QPs
that are attached to them, don't let a QP be destroyed if there are
multicast group(s) attached to it.  Use the existing usecnt field of
struct ib_qp which was added by commit 0e0ec7e ("RDMA/core: Export
ib_open_qp() to share XRC TGT QPs") to track this.

Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>

drivers/infiniband/core/verbs.c
include/rdma/ib_verbs.h

index 575b780..c5b94d6 100644 (file)
@@ -1183,23 +1183,33 @@ EXPORT_SYMBOL(ib_dealloc_fmr);
 
 int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
 {
+       int ret;
+
        if (!qp->device->attach_mcast)
                return -ENOSYS;
        if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
                return -EINVAL;
 
-       return qp->device->attach_mcast(qp, gid, lid);
+       ret = qp->device->attach_mcast(qp, gid, lid);
+       if (!ret)
+               atomic_inc(&qp->usecnt);
+       return ret;
 }
 EXPORT_SYMBOL(ib_attach_mcast);
 
 int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
 {
+       int ret;
+
        if (!qp->device->detach_mcast)
                return -ENOSYS;
        if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
                return -EINVAL;
 
-       return qp->device->detach_mcast(qp, gid, lid);
+       ret = qp->device->detach_mcast(qp, gid, lid);
+       if (!ret)
+               atomic_dec(&qp->usecnt);
+       return ret;
 }
 EXPORT_SYMBOL(ib_detach_mcast);
 
index c3cca5a..c84d101 100644 (file)
@@ -964,7 +964,7 @@ struct ib_qp {
        struct ib_srq          *srq;
        struct ib_xrcd         *xrcd; /* XRC TGT QPs only */
        struct list_head        xrcd_list;
-       atomic_t                usecnt; /* count times opened */
+       atomic_t                usecnt; /* count times opened, mcast attaches */
        struct list_head        open_list;
        struct ib_qp           *real_qp;
        struct ib_uobject      *uobject;