Commit 9a9ebf8c authored by Leon Romanovsky's avatar Leon Romanovsky Committed by Jason Gunthorpe

RDMA: Restore ability to fail on AH destroy

Like any other IB verbs objects, AH are refcounted by ib_core. The release
of those objects are controlled by ib_core with promise that AH destroy
can't fail.

Being SW object for now, this change makes dealloc_ah() to behave like any
other destroy IB flows.

Fixes: d3456914 ("RDMA: Handle AH allocations by IB/core")
Link: https://lore.kernel.org/r/20200907120921.476363-3-leon@kernel.orgSigned-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent 91a7c58f
...@@ -968,18 +968,22 @@ int rdma_destroy_ah_user(struct ib_ah *ah, u32 flags, struct ib_udata *udata) ...@@ -968,18 +968,22 @@ int rdma_destroy_ah_user(struct ib_ah *ah, u32 flags, struct ib_udata *udata)
{ {
const struct ib_gid_attr *sgid_attr = ah->sgid_attr; const struct ib_gid_attr *sgid_attr = ah->sgid_attr;
struct ib_pd *pd; struct ib_pd *pd;
int ret;
might_sleep_if(flags & RDMA_DESTROY_AH_SLEEPABLE); might_sleep_if(flags & RDMA_DESTROY_AH_SLEEPABLE);
pd = ah->pd; pd = ah->pd;
ah->device->ops.destroy_ah(ah, flags); ret = ah->device->ops.destroy_ah(ah, flags);
if (ret)
return ret;
atomic_dec(&pd->usecnt); atomic_dec(&pd->usecnt);
if (sgid_attr) if (sgid_attr)
rdma_put_gid_attr(sgid_attr); rdma_put_gid_attr(sgid_attr);
kfree(ah); kfree(ah);
return 0; return ret;
} }
EXPORT_SYMBOL(rdma_destroy_ah_user); EXPORT_SYMBOL(rdma_destroy_ah_user);
......
...@@ -602,13 +602,14 @@ int bnxt_re_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata) ...@@ -602,13 +602,14 @@ int bnxt_re_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
} }
/* Address Handles */ /* Address Handles */
void bnxt_re_destroy_ah(struct ib_ah *ib_ah, u32 flags) int bnxt_re_destroy_ah(struct ib_ah *ib_ah, u32 flags)
{ {
struct bnxt_re_ah *ah = container_of(ib_ah, struct bnxt_re_ah, ib_ah); struct bnxt_re_ah *ah = container_of(ib_ah, struct bnxt_re_ah, ib_ah);
struct bnxt_re_dev *rdev = ah->rdev; struct bnxt_re_dev *rdev = ah->rdev;
bnxt_qplib_destroy_ah(&rdev->qplib_res, &ah->qplib_ah, bnxt_qplib_destroy_ah(&rdev->qplib_res, &ah->qplib_ah,
!(flags & RDMA_DESTROY_AH_SLEEPABLE)); !(flags & RDMA_DESTROY_AH_SLEEPABLE));
return 0;
} }
static u8 bnxt_re_stack_to_dev_nw_type(enum rdma_network_type ntype) static u8 bnxt_re_stack_to_dev_nw_type(enum rdma_network_type ntype)
......
...@@ -168,7 +168,7 @@ int bnxt_re_create_ah(struct ib_ah *ah, struct rdma_ah_init_attr *init_attr, ...@@ -168,7 +168,7 @@ int bnxt_re_create_ah(struct ib_ah *ah, struct rdma_ah_init_attr *init_attr,
struct ib_udata *udata); struct ib_udata *udata);
int bnxt_re_modify_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr); int bnxt_re_modify_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
int bnxt_re_query_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr); int bnxt_re_query_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
void bnxt_re_destroy_ah(struct ib_ah *ah, u32 flags); int bnxt_re_destroy_ah(struct ib_ah *ah, u32 flags);
int bnxt_re_create_srq(struct ib_srq *srq, int bnxt_re_create_srq(struct ib_srq *srq,
struct ib_srq_init_attr *srq_init_attr, struct ib_srq_init_attr *srq_init_attr,
struct ib_udata *udata); struct ib_udata *udata);
......
...@@ -156,7 +156,7 @@ void efa_mmap_free(struct rdma_user_mmap_entry *rdma_entry); ...@@ -156,7 +156,7 @@ void efa_mmap_free(struct rdma_user_mmap_entry *rdma_entry);
int efa_create_ah(struct ib_ah *ibah, int efa_create_ah(struct ib_ah *ibah,
struct rdma_ah_init_attr *init_attr, struct rdma_ah_init_attr *init_attr,
struct ib_udata *udata); struct ib_udata *udata);
void efa_destroy_ah(struct ib_ah *ibah, u32 flags); int efa_destroy_ah(struct ib_ah *ibah, u32 flags);
int efa_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int efa_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
int qp_attr_mask, struct ib_udata *udata); int qp_attr_mask, struct ib_udata *udata);
enum rdma_link_layer efa_port_link_layer(struct ib_device *ibdev, enum rdma_link_layer efa_port_link_layer(struct ib_device *ibdev,
......
...@@ -1873,7 +1873,7 @@ int efa_create_ah(struct ib_ah *ibah, ...@@ -1873,7 +1873,7 @@ int efa_create_ah(struct ib_ah *ibah,
return err; return err;
} }
void efa_destroy_ah(struct ib_ah *ibah, u32 flags) int efa_destroy_ah(struct ib_ah *ibah, u32 flags)
{ {
struct efa_dev *dev = to_edev(ibah->pd->device); struct efa_dev *dev = to_edev(ibah->pd->device);
struct efa_ah *ah = to_eah(ibah); struct efa_ah *ah = to_eah(ibah);
...@@ -1883,10 +1883,11 @@ void efa_destroy_ah(struct ib_ah *ibah, u32 flags) ...@@ -1883,10 +1883,11 @@ void efa_destroy_ah(struct ib_ah *ibah, u32 flags)
if (!(flags & RDMA_DESTROY_AH_SLEEPABLE)) { if (!(flags & RDMA_DESTROY_AH_SLEEPABLE)) {
ibdev_dbg(&dev->ibdev, ibdev_dbg(&dev->ibdev,
"Destroy address handle is not supported in atomic context\n"); "Destroy address handle is not supported in atomic context\n");
return; return -EOPNOTSUPP;
} }
efa_ah_destroy(dev, ah); efa_ah_destroy(dev, ah);
return 0;
} }
struct rdma_hw_stats *efa_alloc_hw_stats(struct ib_device *ibdev, u8 port_num) struct rdma_hw_stats *efa_alloc_hw_stats(struct ib_device *ibdev, u8 port_num)
......
...@@ -116,8 +116,3 @@ int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr) ...@@ -116,8 +116,3 @@ int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
return 0; return 0;
} }
void hns_roce_destroy_ah(struct ib_ah *ah, u32 flags)
{
return;
}
...@@ -1179,7 +1179,10 @@ void hns_roce_bitmap_free_range(struct hns_roce_bitmap *bitmap, ...@@ -1179,7 +1179,10 @@ void hns_roce_bitmap_free_range(struct hns_roce_bitmap *bitmap,
int hns_roce_create_ah(struct ib_ah *ah, struct rdma_ah_init_attr *init_attr, int hns_roce_create_ah(struct ib_ah *ah, struct rdma_ah_init_attr *init_attr,
struct ib_udata *udata); struct ib_udata *udata);
int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr); int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
void hns_roce_destroy_ah(struct ib_ah *ah, u32 flags); static inline int hns_roce_destroy_ah(struct ib_ah *ah, u32 flags)
{
return 0;
}
int hns_roce_alloc_pd(struct ib_pd *pd, struct ib_udata *udata); int hns_roce_alloc_pd(struct ib_pd *pd, struct ib_udata *udata);
int hns_roce_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata); int hns_roce_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
......
...@@ -232,8 +232,3 @@ int mlx4_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr) ...@@ -232,8 +232,3 @@ int mlx4_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
return 0; return 0;
} }
void mlx4_ib_destroy_ah(struct ib_ah *ah, u32 flags)
{
return;
}
...@@ -753,7 +753,10 @@ int mlx4_ib_create_ah(struct ib_ah *ah, struct rdma_ah_init_attr *init_attr, ...@@ -753,7 +753,10 @@ int mlx4_ib_create_ah(struct ib_ah *ah, struct rdma_ah_init_attr *init_attr,
int mlx4_ib_create_ah_slave(struct ib_ah *ah, struct rdma_ah_attr *ah_attr, int mlx4_ib_create_ah_slave(struct ib_ah *ah, struct rdma_ah_attr *ah_attr,
int slave_sgid_index, u8 *s_mac, u16 vlan_tag); int slave_sgid_index, u8 *s_mac, u16 vlan_tag);
int mlx4_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr); int mlx4_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
void mlx4_ib_destroy_ah(struct ib_ah *ah, u32 flags); static inline int mlx4_ib_destroy_ah(struct ib_ah *ah, u32 flags)
{
return 0;
}
int mlx4_ib_create_srq(struct ib_srq *srq, struct ib_srq_init_attr *init_attr, int mlx4_ib_create_srq(struct ib_srq *srq, struct ib_srq_init_attr *init_attr,
struct ib_udata *udata); struct ib_udata *udata);
......
...@@ -147,8 +147,3 @@ int mlx5_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr) ...@@ -147,8 +147,3 @@ int mlx5_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
return 0; return 0;
} }
void mlx5_ib_destroy_ah(struct ib_ah *ah, u32 flags)
{
return;
}
...@@ -1119,7 +1119,10 @@ void mlx5_ib_free_srq_wqe(struct mlx5_ib_srq *srq, int wqe_index); ...@@ -1119,7 +1119,10 @@ void mlx5_ib_free_srq_wqe(struct mlx5_ib_srq *srq, int wqe_index);
int mlx5_ib_create_ah(struct ib_ah *ah, struct rdma_ah_init_attr *init_attr, int mlx5_ib_create_ah(struct ib_ah *ah, struct rdma_ah_init_attr *init_attr,
struct ib_udata *udata); struct ib_udata *udata);
int mlx5_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr); int mlx5_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
void mlx5_ib_destroy_ah(struct ib_ah *ah, u32 flags); static inline int mlx5_ib_destroy_ah(struct ib_ah *ah, u32 flags)
{
return 0;
}
int mlx5_ib_create_srq(struct ib_srq *srq, struct ib_srq_init_attr *init_attr, int mlx5_ib_create_srq(struct ib_srq *srq, struct ib_srq_init_attr *init_attr,
struct ib_udata *udata); struct ib_udata *udata);
int mlx5_ib_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, int mlx5_ib_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
......
...@@ -390,9 +390,10 @@ static int mthca_ah_create(struct ib_ah *ibah, ...@@ -390,9 +390,10 @@ static int mthca_ah_create(struct ib_ah *ibah,
init_attr->ah_attr, ah); init_attr->ah_attr, ah);
} }
static void mthca_ah_destroy(struct ib_ah *ah, u32 flags) static int mthca_ah_destroy(struct ib_ah *ah, u32 flags)
{ {
mthca_destroy_ah(to_mdev(ah->device), to_mah(ah)); mthca_destroy_ah(to_mdev(ah->device), to_mah(ah));
return 0;
} }
static int mthca_create_srq(struct ib_srq *ibsrq, static int mthca_create_srq(struct ib_srq *ibsrq,
......
...@@ -215,12 +215,13 @@ int ocrdma_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr, ...@@ -215,12 +215,13 @@ int ocrdma_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
return status; return status;
} }
void ocrdma_destroy_ah(struct ib_ah *ibah, u32 flags) int ocrdma_destroy_ah(struct ib_ah *ibah, u32 flags)
{ {
struct ocrdma_ah *ah = get_ocrdma_ah(ibah); struct ocrdma_ah *ah = get_ocrdma_ah(ibah);
struct ocrdma_dev *dev = get_ocrdma_dev(ibah->device); struct ocrdma_dev *dev = get_ocrdma_dev(ibah->device);
ocrdma_free_av(dev, ah); ocrdma_free_av(dev, ah);
return 0;
} }
int ocrdma_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr) int ocrdma_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr)
......
...@@ -53,7 +53,7 @@ enum { ...@@ -53,7 +53,7 @@ enum {
int ocrdma_create_ah(struct ib_ah *ah, struct rdma_ah_init_attr *init_attr, int ocrdma_create_ah(struct ib_ah *ah, struct rdma_ah_init_attr *init_attr,
struct ib_udata *udata); struct ib_udata *udata);
void ocrdma_destroy_ah(struct ib_ah *ah, u32 flags); int ocrdma_destroy_ah(struct ib_ah *ah, u32 flags);
int ocrdma_query_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr); int ocrdma_query_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
int ocrdma_process_mad(struct ib_device *dev, int process_mad_flags, int ocrdma_process_mad(struct ib_device *dev, int process_mad_flags,
......
...@@ -2767,11 +2767,12 @@ int qedr_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr, ...@@ -2767,11 +2767,12 @@ int qedr_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
return 0; return 0;
} }
void qedr_destroy_ah(struct ib_ah *ibah, u32 flags) int qedr_destroy_ah(struct ib_ah *ibah, u32 flags)
{ {
struct qedr_ah *ah = get_qedr_ah(ibah); struct qedr_ah *ah = get_qedr_ah(ibah);
rdma_destroy_ah_attr(&ah->attr); rdma_destroy_ah_attr(&ah->attr);
return 0;
} }
static void free_mr_info(struct qedr_dev *dev, struct mr_info *info) static void free_mr_info(struct qedr_dev *dev, struct mr_info *info)
......
...@@ -72,7 +72,7 @@ int qedr_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr, ...@@ -72,7 +72,7 @@ int qedr_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr,
const struct ib_recv_wr **bad_recv_wr); const struct ib_recv_wr **bad_recv_wr);
int qedr_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr, int qedr_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
struct ib_udata *udata); struct ib_udata *udata);
void qedr_destroy_ah(struct ib_ah *ibah, u32 flags); int qedr_destroy_ah(struct ib_ah *ibah, u32 flags);
int qedr_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata); int qedr_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata);
struct ib_mr *qedr_get_dma_mr(struct ib_pd *, int acc); struct ib_mr *qedr_get_dma_mr(struct ib_pd *, int acc);
......
...@@ -548,9 +548,10 @@ int pvrdma_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr, ...@@ -548,9 +548,10 @@ int pvrdma_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
* @flags: destroy address handle flags (see enum rdma_destroy_ah_flags) * @flags: destroy address handle flags (see enum rdma_destroy_ah_flags)
* *
*/ */
void pvrdma_destroy_ah(struct ib_ah *ah, u32 flags) int pvrdma_destroy_ah(struct ib_ah *ah, u32 flags)
{ {
struct pvrdma_dev *dev = to_vdev(ah->device); struct pvrdma_dev *dev = to_vdev(ah->device);
atomic_dec(&dev->num_ahs); atomic_dec(&dev->num_ahs);
return 0;
} }
...@@ -416,7 +416,7 @@ int pvrdma_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc); ...@@ -416,7 +416,7 @@ int pvrdma_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
int pvrdma_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags); int pvrdma_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags);
int pvrdma_create_ah(struct ib_ah *ah, struct rdma_ah_init_attr *init_attr, int pvrdma_create_ah(struct ib_ah *ah, struct rdma_ah_init_attr *init_attr,
struct ib_udata *udata); struct ib_udata *udata);
void pvrdma_destroy_ah(struct ib_ah *ah, u32 flags); int pvrdma_destroy_ah(struct ib_ah *ah, u32 flags);
int pvrdma_create_srq(struct ib_srq *srq, struct ib_srq_init_attr *init_attr, int pvrdma_create_srq(struct ib_srq *srq, struct ib_srq_init_attr *init_attr,
struct ib_udata *udata); struct ib_udata *udata);
......
...@@ -132,7 +132,7 @@ int rvt_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr, ...@@ -132,7 +132,7 @@ int rvt_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
* *
* Return: 0 on success * Return: 0 on success
*/ */
void rvt_destroy_ah(struct ib_ah *ibah, u32 destroy_flags) int rvt_destroy_ah(struct ib_ah *ibah, u32 destroy_flags)
{ {
struct rvt_dev_info *dev = ib_to_rvt(ibah->device); struct rvt_dev_info *dev = ib_to_rvt(ibah->device);
struct rvt_ah *ah = ibah_to_rvtah(ibah); struct rvt_ah *ah = ibah_to_rvtah(ibah);
...@@ -143,6 +143,7 @@ void rvt_destroy_ah(struct ib_ah *ibah, u32 destroy_flags) ...@@ -143,6 +143,7 @@ void rvt_destroy_ah(struct ib_ah *ibah, u32 destroy_flags)
spin_unlock_irqrestore(&dev->n_ahs_lock, flags); spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
rdma_destroy_ah_attr(&ah->attr); rdma_destroy_ah_attr(&ah->attr);
return 0;
} }
/** /**
......
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
int rvt_create_ah(struct ib_ah *ah, struct rdma_ah_init_attr *init_attr, int rvt_create_ah(struct ib_ah *ah, struct rdma_ah_init_attr *init_attr,
struct ib_udata *udata); struct ib_udata *udata);
void rvt_destroy_ah(struct ib_ah *ibah, u32 destroy_flags); int rvt_destroy_ah(struct ib_ah *ibah, u32 destroy_flags);
int rvt_modify_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr); int rvt_modify_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
int rvt_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr); int rvt_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
......
...@@ -201,11 +201,12 @@ static int rxe_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr) ...@@ -201,11 +201,12 @@ static int rxe_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr)
return 0; return 0;
} }
static void rxe_destroy_ah(struct ib_ah *ibah, u32 flags) static int rxe_destroy_ah(struct ib_ah *ibah, u32 flags)
{ {
struct rxe_ah *ah = to_rah(ibah); struct rxe_ah *ah = to_rah(ibah);
rxe_drop_ref(ah); rxe_drop_ref(ah);
return 0;
} }
static int post_one_recv(struct rxe_rq *rq, const struct ib_recv_wr *ibwr) static int post_one_recv(struct rxe_rq *rq, const struct ib_recv_wr *ibwr)
......
...@@ -2403,7 +2403,7 @@ struct ib_device_ops { ...@@ -2403,7 +2403,7 @@ struct ib_device_ops {
struct ib_udata *udata); struct ib_udata *udata);
int (*modify_ah)(struct ib_ah *ah, struct rdma_ah_attr *ah_attr); int (*modify_ah)(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
int (*query_ah)(struct ib_ah *ah, struct rdma_ah_attr *ah_attr); int (*query_ah)(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
void (*destroy_ah)(struct ib_ah *ah, u32 flags); int (*destroy_ah)(struct ib_ah *ah, u32 flags);
int (*create_srq)(struct ib_srq *srq, int (*create_srq)(struct ib_srq *srq,
struct ib_srq_init_attr *srq_init_attr, struct ib_srq_init_attr *srq_init_attr,
struct ib_udata *udata); struct ib_udata *udata);
...@@ -3596,9 +3596,11 @@ int rdma_destroy_ah_user(struct ib_ah *ah, u32 flags, struct ib_udata *udata); ...@@ -3596,9 +3596,11 @@ int rdma_destroy_ah_user(struct ib_ah *ah, u32 flags, struct ib_udata *udata);
* *
* NOTE: for user ah use rdma_destroy_ah_user with valid udata! * NOTE: for user ah use rdma_destroy_ah_user with valid udata!
*/ */
static inline int rdma_destroy_ah(struct ib_ah *ah, u32 flags) static inline void rdma_destroy_ah(struct ib_ah *ah, u32 flags)
{ {
return rdma_destroy_ah_user(ah, flags, NULL); int ret = rdma_destroy_ah_user(ah, flags, NULL);
WARN_ONCE(ret, "Destroy of kernel AH shouldn't fail");
} }
struct ib_srq *ib_create_srq_user(struct ib_pd *pd, struct ib_srq *ib_create_srq_user(struct ib_pd *pd,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment