diff options
author | Yishai Hadas <yishaih@mellanox.com> | 2013-08-01 11:49:54 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2013-08-13 14:21:32 -0400 |
commit | 846be90d810c285f6474f53abf1f928e1113830e (patch) | |
tree | 8daa8a2b5ef54239fdfa04c2034f0abe1c80e81b | |
parent | 73c40c616a33fcb7961b3c90a91b550813129b3e (diff) |
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>
-rw-r--r-- | drivers/infiniband/core/uverbs.h | 1 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 22 |
2 files changed, 21 insertions, 2 deletions
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index 0fcd7aa26fa2..b8431d64efeb 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h | |||
@@ -135,6 +135,7 @@ struct ib_usrq_object { | |||
135 | struct ib_uqp_object { | 135 | struct ib_uqp_object { |
136 | struct ib_uevent_object uevent; | 136 | struct ib_uevent_object uevent; |
137 | struct list_head mcast_list; | 137 | struct list_head mcast_list; |
138 | struct ib_uxrcd_object *uxrcd; | ||
138 | }; | 139 | }; |
139 | 140 | ||
140 | struct ib_ucq_object { | 141 | struct ib_ucq_object { |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index b3c07b0c9f26..b1051405d41f 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -1526,7 +1526,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, | |||
1526 | (unsigned long) cmd.response + sizeof resp, | 1526 | (unsigned long) cmd.response + sizeof resp, |
1527 | in_len - sizeof cmd, out_len - sizeof resp); | 1527 | in_len - sizeof cmd, out_len - sizeof resp); |
1528 | 1528 | ||
1529 | obj = kmalloc(sizeof *obj, GFP_KERNEL); | 1529 | obj = kzalloc(sizeof *obj, GFP_KERNEL); |
1530 | if (!obj) | 1530 | if (!obj) |
1531 | return -ENOMEM; | 1531 | return -ENOMEM; |
1532 | 1532 | ||
@@ -1642,8 +1642,13 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, | |||
1642 | goto err_copy; | 1642 | goto err_copy; |
1643 | } | 1643 | } |
1644 | 1644 | ||
1645 | if (xrcd) | 1645 | if (xrcd) { |
1646 | obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object, | ||
1647 | uobject); | ||
1648 | atomic_inc(&obj->uxrcd->refcnt); | ||
1646 | put_xrcd_read(xrcd_uobj); | 1649 | put_xrcd_read(xrcd_uobj); |
1650 | } | ||
1651 | |||
1647 | if (pd) | 1652 | if (pd) |
1648 | put_pd_read(pd); | 1653 | put_pd_read(pd); |
1649 | if (scq) | 1654 | if (scq) |
@@ -1753,6 +1758,8 @@ ssize_t ib_uverbs_open_qp(struct ib_uverbs_file *file, | |||
1753 | goto err_remove; | 1758 | goto err_remove; |
1754 | } | 1759 | } |
1755 | 1760 | ||
1761 | obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object, uobject); | ||
1762 | atomic_inc(&obj->uxrcd->refcnt); | ||
1756 | put_xrcd_read(xrcd_uobj); | 1763 | put_xrcd_read(xrcd_uobj); |
1757 | 1764 | ||
1758 | mutex_lock(&file->mutex); | 1765 | mutex_lock(&file->mutex); |
@@ -2019,6 +2026,9 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, | |||
2019 | if (ret) | 2026 | if (ret) |
2020 | return ret; | 2027 | return ret; |
2021 | 2028 | ||
2029 | if (obj->uxrcd) | ||
2030 | atomic_dec(&obj->uxrcd->refcnt); | ||
2031 | |||
2022 | idr_remove_uobj(&ib_uverbs_qp_idr, uobj); | 2032 | idr_remove_uobj(&ib_uverbs_qp_idr, uobj); |
2023 | 2033 | ||
2024 | mutex_lock(&file->mutex); | 2034 | mutex_lock(&file->mutex); |
@@ -2860,6 +2870,8 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, | |||
2860 | struct ib_srq *srq; | 2870 | struct ib_srq *srq; |
2861 | struct ib_uevent_object *obj; | 2871 | struct ib_uevent_object *obj; |
2862 | int ret = -EINVAL; | 2872 | int ret = -EINVAL; |
2873 | struct ib_usrq_object *us; | ||
2874 | enum ib_srq_type srq_type; | ||
2863 | 2875 | ||
2864 | if (copy_from_user(&cmd, buf, sizeof cmd)) | 2876 | if (copy_from_user(&cmd, buf, sizeof cmd)) |
2865 | return -EFAULT; | 2877 | return -EFAULT; |
@@ -2869,6 +2881,7 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, | |||
2869 | return -EINVAL; | 2881 | return -EINVAL; |
2870 | srq = uobj->object; | 2882 | srq = uobj->object; |
2871 | obj = container_of(uobj, struct ib_uevent_object, uobject); | 2883 | obj = container_of(uobj, struct ib_uevent_object, uobject); |
2884 | srq_type = srq->srq_type; | ||
2872 | 2885 | ||
2873 | ret = ib_destroy_srq(srq); | 2886 | ret = ib_destroy_srq(srq); |
2874 | if (!ret) | 2887 | if (!ret) |
@@ -2879,6 +2892,11 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, | |||
2879 | if (ret) | 2892 | if (ret) |
2880 | return ret; | 2893 | return ret; |
2881 | 2894 | ||
2895 | if (srq_type == IB_SRQT_XRC) { | ||
2896 | us = container_of(obj, struct ib_usrq_object, uevent); | ||
2897 | atomic_dec(&us->uxrcd->refcnt); | ||
2898 | } | ||
2899 | |||
2882 | idr_remove_uobj(&ib_uverbs_srq_idr, uobj); | 2900 | idr_remove_uobj(&ib_uverbs_srq_idr, uobj); |
2883 | 2901 | ||
2884 | mutex_lock(&file->mutex); | 2902 | mutex_lock(&file->mutex); |