aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOr Gerlitz <ogerlitz@mellanox.com>2012-04-29 10:04:22 -0400
committerRoland Dreier <roland@purestorage.com>2012-05-08 14:16:54 -0400
commitc3bccbfbb71f5e8a77129c7a069f5c5648cc9cf1 (patch)
treef1802d86a4db8c263e6960c401c4f29be3f68b0a
parentd48b97b403d23f6df0b990cee652bdf9a52337a3 (diff)
IB/core: Use qp->usecnt to track multicast attach/detach
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>
-rw-r--r--drivers/infiniband/core/verbs.c14
-rw-r--r--include/rdma/ib_verbs.h2
2 files changed, 13 insertions, 3 deletions
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 575b78045aaf..c5b94d647e1e 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -1183,23 +1183,33 @@ EXPORT_SYMBOL(ib_dealloc_fmr);
1183 1183
1184int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid) 1184int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
1185{ 1185{
1186 int ret;
1187
1186 if (!qp->device->attach_mcast) 1188 if (!qp->device->attach_mcast)
1187 return -ENOSYS; 1189 return -ENOSYS;
1188 if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD) 1190 if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
1189 return -EINVAL; 1191 return -EINVAL;
1190 1192
1191 return qp->device->attach_mcast(qp, gid, lid); 1193 ret = qp->device->attach_mcast(qp, gid, lid);
1194 if (!ret)
1195 atomic_inc(&qp->usecnt);
1196 return ret;
1192} 1197}
1193EXPORT_SYMBOL(ib_attach_mcast); 1198EXPORT_SYMBOL(ib_attach_mcast);
1194 1199
1195int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid) 1200int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
1196{ 1201{
1202 int ret;
1203
1197 if (!qp->device->detach_mcast) 1204 if (!qp->device->detach_mcast)
1198 return -ENOSYS; 1205 return -ENOSYS;
1199 if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD) 1206 if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
1200 return -EINVAL; 1207 return -EINVAL;
1201 1208
1202 return qp->device->detach_mcast(qp, gid, lid); 1209 ret = qp->device->detach_mcast(qp, gid, lid);
1210 if (!ret)
1211 atomic_dec(&qp->usecnt);
1212 return ret;
1203} 1213}
1204EXPORT_SYMBOL(ib_detach_mcast); 1214EXPORT_SYMBOL(ib_detach_mcast);
1205 1215
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index c3cca5a4dacd..c84d1016618e 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -964,7 +964,7 @@ struct ib_qp {
964 struct ib_srq *srq; 964 struct ib_srq *srq;
965 struct ib_xrcd *xrcd; /* XRC TGT QPs only */ 965 struct ib_xrcd *xrcd; /* XRC TGT QPs only */
966 struct list_head xrcd_list; 966 struct list_head xrcd_list;
967 atomic_t usecnt; /* count times opened */ 967 atomic_t usecnt; /* count times opened, mcast attaches */
968 struct list_head open_list; 968 struct list_head open_list;
969 struct ib_qp *real_qp; 969 struct ib_qp *real_qp;
970 struct ib_uobject *uobject; 970 struct ib_uobject *uobject;