IB/core: Fixes to XRC reference counting in uverbs
Added reference counting mechanism for XRC target QPs between ib_uqp_object and its ib_uxrcd_object. This prevents closing an XRC domain that is still attached to a QP. In addition, add missing code in ib_uverbs_destroy_srq() to handle ib_uxrcd_object reference counting correctly when destroying an xsrq. Signed-off-by: Yishai Hadas <yishaih@mellanox.com> Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
This commit is contained in:
parent
73c40c616a
commit
846be90d81
@ -135,6 +135,7 @@ struct ib_usrq_object {
|
|||||||
struct ib_uqp_object {
|
struct ib_uqp_object {
|
||||||
struct ib_uevent_object uevent;
|
struct ib_uevent_object uevent;
|
||||||
struct list_head mcast_list;
|
struct list_head mcast_list;
|
||||||
|
struct ib_uxrcd_object *uxrcd;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ib_ucq_object {
|
struct ib_ucq_object {
|
||||||
|
@ -1526,7 +1526,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
|
|||||||
(unsigned long) cmd.response + sizeof resp,
|
(unsigned long) cmd.response + sizeof resp,
|
||||||
in_len - sizeof cmd, out_len - sizeof resp);
|
in_len - sizeof cmd, out_len - sizeof resp);
|
||||||
|
|
||||||
obj = kmalloc(sizeof *obj, GFP_KERNEL);
|
obj = kzalloc(sizeof *obj, GFP_KERNEL);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -1642,8 +1642,13 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
|
|||||||
goto err_copy;
|
goto err_copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xrcd)
|
if (xrcd) {
|
||||||
|
obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object,
|
||||||
|
uobject);
|
||||||
|
atomic_inc(&obj->uxrcd->refcnt);
|
||||||
put_xrcd_read(xrcd_uobj);
|
put_xrcd_read(xrcd_uobj);
|
||||||
|
}
|
||||||
|
|
||||||
if (pd)
|
if (pd)
|
||||||
put_pd_read(pd);
|
put_pd_read(pd);
|
||||||
if (scq)
|
if (scq)
|
||||||
@ -1753,6 +1758,8 @@ ssize_t ib_uverbs_open_qp(struct ib_uverbs_file *file,
|
|||||||
goto err_remove;
|
goto err_remove;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object, uobject);
|
||||||
|
atomic_inc(&obj->uxrcd->refcnt);
|
||||||
put_xrcd_read(xrcd_uobj);
|
put_xrcd_read(xrcd_uobj);
|
||||||
|
|
||||||
mutex_lock(&file->mutex);
|
mutex_lock(&file->mutex);
|
||||||
@ -2019,6 +2026,9 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if (obj->uxrcd)
|
||||||
|
atomic_dec(&obj->uxrcd->refcnt);
|
||||||
|
|
||||||
idr_remove_uobj(&ib_uverbs_qp_idr, uobj);
|
idr_remove_uobj(&ib_uverbs_qp_idr, uobj);
|
||||||
|
|
||||||
mutex_lock(&file->mutex);
|
mutex_lock(&file->mutex);
|
||||||
@ -2860,6 +2870,8 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
|
|||||||
struct ib_srq *srq;
|
struct ib_srq *srq;
|
||||||
struct ib_uevent_object *obj;
|
struct ib_uevent_object *obj;
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
struct ib_usrq_object *us;
|
||||||
|
enum ib_srq_type srq_type;
|
||||||
|
|
||||||
if (copy_from_user(&cmd, buf, sizeof cmd))
|
if (copy_from_user(&cmd, buf, sizeof cmd))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
@ -2869,6 +2881,7 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
srq = uobj->object;
|
srq = uobj->object;
|
||||||
obj = container_of(uobj, struct ib_uevent_object, uobject);
|
obj = container_of(uobj, struct ib_uevent_object, uobject);
|
||||||
|
srq_type = srq->srq_type;
|
||||||
|
|
||||||
ret = ib_destroy_srq(srq);
|
ret = ib_destroy_srq(srq);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
@ -2879,6 +2892,11 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if (srq_type == IB_SRQT_XRC) {
|
||||||
|
us = container_of(obj, struct ib_usrq_object, uevent);
|
||||||
|
atomic_dec(&us->uxrcd->refcnt);
|
||||||
|
}
|
||||||
|
|
||||||
idr_remove_uobj(&ib_uverbs_srq_idr, uobj);
|
idr_remove_uobj(&ib_uverbs_srq_idr, uobj);
|
||||||
|
|
||||||
mutex_lock(&file->mutex);
|
mutex_lock(&file->mutex);
|
||||||
|
Loading…
Reference in New Issue
Block a user