RDMA: Mark if destroy address handle is in a sleepable context
authorGal Pressman <galpress@amazon.com>
Wed, 12 Dec 2018 09:09:06 +0000 (11:09 +0200)
committerJason Gunthorpe <jgg@mellanox.com>
Wed, 19 Dec 2018 23:28:03 +0000 (16:28 -0700)
Introduce a 'flags' field to destroy address handle callback and add a
flag that marks whether the callback is executed in an atomic context or
not.

This will allow drivers to wait for completion instead of polling for it
when it is allowed.

Signed-off-by: Gal Pressman <galpress@amazon.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
36 files changed:
drivers/infiniband/core/agent.c
drivers/infiniband/core/cm.c
drivers/infiniband/core/mad_rmpp.c
drivers/infiniband/core/sa_query.c
drivers/infiniband/core/user_mad.c
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/uverbs_std_types.c
drivers/infiniband/core/verbs.c
drivers/infiniband/hw/bnxt_re/ib_verbs.c
drivers/infiniband/hw/bnxt_re/ib_verbs.h
drivers/infiniband/hw/hns/hns_roce_ah.c
drivers/infiniband/hw/hns/hns_roce_device.h
drivers/infiniband/hw/mlx4/ah.c
drivers/infiniband/hw/mlx4/mad.c
drivers/infiniband/hw/mlx4/mlx4_ib.h
drivers/infiniband/hw/mlx5/ah.c
drivers/infiniband/hw/mlx5/mlx5_ib.h
drivers/infiniband/hw/mthca/mthca_mad.c
drivers/infiniband/hw/mthca/mthca_provider.c
drivers/infiniband/hw/ocrdma/ocrdma_ah.c
drivers/infiniband/hw/ocrdma/ocrdma_ah.h
drivers/infiniband/hw/qedr/verbs.c
drivers/infiniband/hw/qedr/verbs.h
drivers/infiniband/hw/qib/qib_mad.c
drivers/infiniband/hw/usnic/usnic_ib_verbs.c
drivers/infiniband/hw/usnic/usnic_ib_verbs.h
drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h
drivers/infiniband/sw/rdmavt/ah.c
drivers/infiniband/sw/rdmavt/ah.h
drivers/infiniband/sw/rdmavt/mad.c
drivers/infiniband/sw/rxe/rxe_verbs.c
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/infiniband/ulp/opa_vnic/opa_vnic_vema.c
drivers/infiniband/ulp/srpt/ib_srpt.c
include/rdma/ib_verbs.h

index 324ef85..f82b426 100644 (file)
@@ -137,13 +137,13 @@ void agent_send_response(const struct ib_mad_hdr *mad_hdr, const struct ib_grh *
 err2:
        ib_free_send_mad(send_buf);
 err1:
-       rdma_destroy_ah(ah);
+       rdma_destroy_ah(ah, RDMA_DESTROY_AH_SLEEPABLE);
 }
 
 static void agent_send_handler(struct ib_mad_agent *mad_agent,
                               struct ib_mad_send_wc *mad_send_wc)
 {
-       rdma_destroy_ah(mad_send_wc->send_buf->ah);
+       rdma_destroy_ah(mad_send_wc->send_buf->ah, RDMA_DESTROY_AH_SLEEPABLE);
        ib_free_send_mad(mad_send_wc->send_buf);
 }
 
index cf5b3c4..37980c7 100644 (file)
@@ -355,7 +355,7 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv,
                               GFP_ATOMIC,
                               IB_MGMT_BASE_VERSION);
        if (IS_ERR(m)) {
-               rdma_destroy_ah(ah);
+               rdma_destroy_ah(ah, 0);
                ret = PTR_ERR(m);
                goto out;
        }
@@ -400,7 +400,7 @@ static int cm_create_response_msg_ah(struct cm_port *port,
 static void cm_free_msg(struct ib_mad_send_buf *msg)
 {
        if (msg->ah)
-               rdma_destroy_ah(msg->ah);
+               rdma_destroy_ah(msg->ah, 0);
        if (msg->context[0])
                cm_deref_id(msg->context[0]);
        ib_free_send_mad(msg);
index e5cf09c..5ec57ab 100644 (file)
@@ -81,7 +81,7 @@ static void destroy_rmpp_recv(struct mad_rmpp_recv *rmpp_recv)
 {
        deref_rmpp_recv(rmpp_recv);
        wait_for_completion(&rmpp_recv->comp);
-       rdma_destroy_ah(rmpp_recv->ah);
+       rdma_destroy_ah(rmpp_recv->ah, RDMA_DESTROY_AH_SLEEPABLE);
        kfree(rmpp_recv);
 }
 
@@ -171,7 +171,7 @@ static struct ib_mad_send_buf *alloc_response_msg(struct ib_mad_agent *agent,
                                 hdr_len, 0, GFP_KERNEL,
                                 IB_MGMT_BASE_VERSION);
        if (IS_ERR(msg))
-               rdma_destroy_ah(ah);
+               rdma_destroy_ah(ah, RDMA_DESTROY_AH_SLEEPABLE);
        else {
                msg->ah = ah;
                msg->context[0] = ah;
@@ -201,7 +201,7 @@ static void ack_ds_ack(struct ib_mad_agent_private *agent,
 
        ret = ib_post_send_mad(msg, NULL);
        if (ret) {
-               rdma_destroy_ah(msg->ah);
+               rdma_destroy_ah(msg->ah, RDMA_DESTROY_AH_SLEEPABLE);
                ib_free_send_mad(msg);
        }
 }
@@ -209,7 +209,8 @@ static void ack_ds_ack(struct ib_mad_agent_private *agent,
 void ib_rmpp_send_handler(struct ib_mad_send_wc *mad_send_wc)
 {
        if (mad_send_wc->send_buf->context[0] == mad_send_wc->send_buf->ah)
-               rdma_destroy_ah(mad_send_wc->send_buf->ah);
+               rdma_destroy_ah(mad_send_wc->send_buf->ah,
+                               RDMA_DESTROY_AH_SLEEPABLE);
        ib_free_send_mad(mad_send_wc->send_buf);
 }
 
@@ -237,7 +238,7 @@ static void nack_recv(struct ib_mad_agent_private *agent,
 
        ret = ib_post_send_mad(msg, NULL);
        if (ret) {
-               rdma_destroy_ah(msg->ah);
+               rdma_destroy_ah(msg->ah, RDMA_DESTROY_AH_SLEEPABLE);
                ib_free_send_mad(msg);
        }
 }
index fb96d9d..97e6d7b 100644 (file)
@@ -1147,7 +1147,7 @@ static void free_sm_ah(struct kref *kref)
 {
        struct ib_sa_sm_ah *sm_ah = container_of(kref, struct ib_sa_sm_ah, ref);
 
-       rdma_destroy_ah(sm_ah->ah);
+       rdma_destroy_ah(sm_ah->ah, 0);
        kfree(sm_ah);
 }
 
index f55f48f..ee3b1f7 100644 (file)
@@ -205,7 +205,7 @@ static void send_handler(struct ib_mad_agent *agent,
        struct ib_umad_packet *packet = send_wc->send_buf->context[0];
 
        dequeue_send(file, packet);
-       rdma_destroy_ah(packet->msg->ah);
+       rdma_destroy_ah(packet->msg->ah, RDMA_DESTROY_AH_SLEEPABLE);
        ib_free_send_mad(packet->msg);
 
        if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) {
@@ -621,7 +621,7 @@ err_send:
 err_msg:
        ib_free_send_mad(packet->msg);
 err_ah:
-       rdma_destroy_ah(ah);
+       rdma_destroy_ah(ah, RDMA_DESTROY_AH_SLEEPABLE);
 err_up:
        mutex_unlock(&file->mutex);
 err:
index 17be53d..4dc454d 100644 (file)
@@ -2486,7 +2486,7 @@ static int ib_uverbs_create_ah(struct uverbs_attr_bundle *attrs)
        return uobj_alloc_commit(uobj);
 
 err_copy:
-       rdma_destroy_ah(ah);
+       rdma_destroy_ah(ah, RDMA_DESTROY_AH_SLEEPABLE);
 
 err_put:
        uobj_put_obj_read(pd);
index 8e975f5..cbc7231 100644 (file)
@@ -42,7 +42,8 @@
 static int uverbs_free_ah(struct ib_uobject *uobject,
                          enum rdma_remove_reason why)
 {
-       return rdma_destroy_ah((struct ib_ah *)uobject->object);
+       return rdma_destroy_ah((struct ib_ah *)uobject->object,
+                              RDMA_DESTROY_AH_SLEEPABLE);
 }
 
 static int uverbs_free_flow(struct ib_uobject *uobject,
index 4e2df23..ac01183 100644 (file)
@@ -925,14 +925,16 @@ int rdma_query_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr)
 }
 EXPORT_SYMBOL(rdma_query_ah);
 
-int rdma_destroy_ah(struct ib_ah *ah)
+int rdma_destroy_ah(struct ib_ah *ah, u32 flags)
 {
        const struct ib_gid_attr *sgid_attr = ah->sgid_attr;
        struct ib_pd *pd;
        int ret;
 
+       might_sleep_if(flags & RDMA_DESTROY_AH_SLEEPABLE);
+
        pd = ah->pd;
-       ret = ah->device->ops.destroy_ah(ah);
+       ret = ah->device->ops.destroy_ah(ah, flags);
        if (!ret) {
                atomic_dec(&pd->usecnt);
                if (sgid_attr)
index 4b37bc3..ece45e7 100644 (file)
@@ -647,7 +647,7 @@ fail:
 }
 
 /* Address Handles */
-int bnxt_re_destroy_ah(struct ib_ah *ib_ah)
+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_dev *rdev = ah->rdev;
index 6675db4..c4af726 100644 (file)
@@ -173,7 +173,7 @@ struct ib_ah *bnxt_re_create_ah(struct ib_pd *pd,
                                struct ib_udata *udata);
 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_destroy_ah(struct ib_ah *ah);
+int bnxt_re_destroy_ah(struct ib_ah *ah, u32 flags);
 struct ib_srq *bnxt_re_create_srq(struct ib_pd *pd,
                                  struct ib_srq_init_attr *srq_init_attr,
                                  struct ib_udata *udata);
index dae4c54..b3c8c45 100644 (file)
@@ -111,7 +111,7 @@ int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
        return 0;
 }
 
-int hns_roce_destroy_ah(struct ib_ah *ah)
+int hns_roce_destroy_ah(struct ib_ah *ah, u32 flags)
 {
        kfree(to_hr_ah(ah));
 
index b2c4682..509e467 100644 (file)
@@ -1059,7 +1059,7 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *pd,
                                 u32 flags,
                                 struct ib_udata *udata);
 int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
-int hns_roce_destroy_ah(struct ib_ah *ah);
+int hns_roce_destroy_ah(struct ib_ah *ah, u32 flags);
 
 struct ib_pd *hns_roce_alloc_pd(struct ib_device *ib_dev,
                                struct ib_ucontext *context,
index 6c0e6bc..1672808 100644 (file)
@@ -250,7 +250,7 @@ int mlx4_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
        return 0;
 }
 
-int mlx4_ib_destroy_ah(struct ib_ah *ah)
+int mlx4_ib_destroy_ah(struct ib_ah *ah, u32 flags)
 {
        kfree(to_mah(ah));
        return 0;
index b227f7c..25439da 100644 (file)
@@ -208,7 +208,7 @@ static void update_sm_ah(struct mlx4_ib_dev *dev, u8 port_num, u16 lid, u8 sl)
 
        spin_lock_irqsave(&dev->sm_lock, flags);
        if (dev->sm_ah[port_num - 1])
-               rdma_destroy_ah(dev->sm_ah[port_num - 1]);
+               rdma_destroy_ah(dev->sm_ah[port_num - 1], 0);
        dev->sm_ah[port_num - 1] = new_ah;
        spin_unlock_irqrestore(&dev->sm_lock, flags);
 }
@@ -584,7 +584,7 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port,
 
        tun_mad = (struct mlx4_rcv_tunnel_mad *) (tun_qp->tx_ring[tun_tx_ix].buf.addr);
        if (tun_qp->tx_ring[tun_tx_ix].ah)
-               rdma_destroy_ah(tun_qp->tx_ring[tun_tx_ix].ah);
+               rdma_destroy_ah(tun_qp->tx_ring[tun_tx_ix].ah, 0);
        tun_qp->tx_ring[tun_tx_ix].ah = ah;
        ib_dma_sync_single_for_cpu(&dev->ib_dev,
                                   tun_qp->tx_ring[tun_tx_ix].buf.map,
@@ -657,7 +657,7 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port,
        spin_unlock(&tun_qp->tx_lock);
        tun_qp->tx_ring[tun_tx_ix].ah = NULL;
 end:
-       rdma_destroy_ah(ah);
+       rdma_destroy_ah(ah, 0);
        return ret;
 }
 
@@ -1024,7 +1024,7 @@ static void send_handler(struct ib_mad_agent *agent,
                         struct ib_mad_send_wc *mad_send_wc)
 {
        if (mad_send_wc->send_buf->context[0])
-               rdma_destroy_ah(mad_send_wc->send_buf->context[0]);
+               rdma_destroy_ah(mad_send_wc->send_buf->context[0], 0);
        ib_free_send_mad(mad_send_wc->send_buf);
 }
 
@@ -1079,7 +1079,7 @@ void mlx4_ib_mad_cleanup(struct mlx4_ib_dev *dev)
                }
 
                if (dev->sm_ah[p])
-                       rdma_destroy_ah(dev->sm_ah[p]);
+                       rdma_destroy_ah(dev->sm_ah[p], 0);
        }
 }
 
@@ -1411,7 +1411,7 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port,
 
        sqp_mad = (struct mlx4_mad_snd_buf *) (sqp->tx_ring[wire_tx_ix].buf.addr);
        if (sqp->tx_ring[wire_tx_ix].ah)
-               rdma_destroy_ah(sqp->tx_ring[wire_tx_ix].ah);
+               rdma_destroy_ah(sqp->tx_ring[wire_tx_ix].ah, 0);
        sqp->tx_ring[wire_tx_ix].ah = ah;
        ib_dma_sync_single_for_cpu(&dev->ib_dev,
                                   sqp->tx_ring[wire_tx_ix].buf.map,
@@ -1450,7 +1450,7 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port,
        spin_unlock(&sqp->tx_lock);
        sqp->tx_ring[wire_tx_ix].ah = NULL;
 out:
-       mlx4_ib_destroy_ah(ah);
+       mlx4_ib_destroy_ah(ah, 0);
        return ret;
 }
 
@@ -1716,7 +1716,7 @@ static void mlx4_ib_free_pv_qp_bufs(struct mlx4_ib_demux_pv_ctx *ctx,
                                    tx_buf_size, DMA_TO_DEVICE);
                kfree(tun_qp->tx_ring[i].buf.addr);
                if (tun_qp->tx_ring[i].ah)
-                       rdma_destroy_ah(tun_qp->tx_ring[i].ah);
+                       rdma_destroy_ah(tun_qp->tx_ring[i].ah, 0);
        }
        kfree(tun_qp->tx_ring);
        kfree(tun_qp->ring);
@@ -1749,7 +1749,7 @@ static void mlx4_ib_tunnel_comp_worker(struct work_struct *work)
                                         "wrid=0x%llx, status=0x%x\n",
                                         wc.wr_id, wc.status);
                                rdma_destroy_ah(tun_qp->tx_ring[wc.wr_id &
-                                             (MLX4_NUM_TUNNEL_BUFS - 1)].ah);
+                                             (MLX4_NUM_TUNNEL_BUFS - 1)].ah, 0);
                                tun_qp->tx_ring[wc.wr_id & (MLX4_NUM_TUNNEL_BUFS - 1)].ah
                                        = NULL;
                                spin_lock(&tun_qp->tx_lock);
@@ -1766,7 +1766,7 @@ static void mlx4_ib_tunnel_comp_worker(struct work_struct *work)
                                 ctx->slave, wc.status, wc.wr_id);
                        if (!MLX4_TUN_IS_RECV(wc.wr_id)) {
                                rdma_destroy_ah(tun_qp->tx_ring[wc.wr_id &
-                                             (MLX4_NUM_TUNNEL_BUFS - 1)].ah);
+                                             (MLX4_NUM_TUNNEL_BUFS - 1)].ah, 0);
                                tun_qp->tx_ring[wc.wr_id & (MLX4_NUM_TUNNEL_BUFS - 1)].ah
                                        = NULL;
                                spin_lock(&tun_qp->tx_lock);
@@ -1903,7 +1903,7 @@ static void mlx4_ib_sqp_comp_worker(struct work_struct *work)
                        switch (wc.opcode) {
                        case IB_WC_SEND:
                                rdma_destroy_ah(sqp->tx_ring[wc.wr_id &
-                                             (MLX4_NUM_TUNNEL_BUFS - 1)].ah);
+                                             (MLX4_NUM_TUNNEL_BUFS - 1)].ah, 0);
                                sqp->tx_ring[wc.wr_id & (MLX4_NUM_TUNNEL_BUFS - 1)].ah
                                        = NULL;
                                spin_lock(&sqp->tx_lock);
@@ -1932,7 +1932,7 @@ static void mlx4_ib_sqp_comp_worker(struct work_struct *work)
                                 ctx->slave, wc.status, wc.wr_id);
                        if (!MLX4_TUN_IS_RECV(wc.wr_id)) {
                                rdma_destroy_ah(sqp->tx_ring[wc.wr_id &
-                                             (MLX4_NUM_TUNNEL_BUFS - 1)].ah);
+                                             (MLX4_NUM_TUNNEL_BUFS - 1)].ah, 0);
                                sqp->tx_ring[wc.wr_id & (MLX4_NUM_TUNNEL_BUFS - 1)].ah
                                        = NULL;
                                spin_lock(&sqp->tx_lock);
index 7b827b1..e491f3e 100644 (file)
@@ -760,7 +760,7 @@ struct ib_ah *mlx4_ib_create_ah_slave(struct ib_pd *pd,
                                      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_destroy_ah(struct ib_ah *ah);
+int mlx4_ib_destroy_ah(struct ib_ah *ah, u32 flags);
 
 struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
                                  struct ib_srq_init_attr *init_attr,
index 536c2c0..420ae08 100644 (file)
@@ -131,7 +131,7 @@ int mlx5_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
        return 0;
 }
 
-int mlx5_ib_destroy_ah(struct ib_ah *ah)
+int mlx5_ib_destroy_ah(struct ib_ah *ah, u32 flags)
 {
        kfree(to_mah(ah));
        return 0;
index ebf7002..96e8fa1 100644 (file)
@@ -1044,7 +1044,7 @@ int mlx5_MAD_IFC(struct mlx5_ib_dev *dev, int ignore_mkey, int ignore_bkey,
 struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
                                u32 flags, struct ib_udata *udata);
 int mlx5_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
-int mlx5_ib_destroy_ah(struct ib_ah *ah);
+int mlx5_ib_destroy_ah(struct ib_ah *ah, u32 flags);
 struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
                                  struct ib_srq_init_attr *init_attr,
                                  struct ib_udata *udata);
index 4a5916d..7ad517d 100644 (file)
@@ -95,7 +95,7 @@ static void update_sm_ah(struct mthca_dev *dev,
 
        spin_lock_irqsave(&dev->sm_lock, flags);
        if (dev->sm_ah[port_num - 1])
-               rdma_destroy_ah(dev->sm_ah[port_num - 1]);
+               rdma_destroy_ah(dev->sm_ah[port_num - 1], 0);
        dev->sm_ah[port_num - 1] = new_ah;
        spin_unlock_irqrestore(&dev->sm_lock, flags);
 }
@@ -347,6 +347,7 @@ void mthca_free_agents(struct mthca_dev *dev)
                }
 
                if (dev->sm_ah[p])
-                       rdma_destroy_ah(dev->sm_ah[p]);
+                       rdma_destroy_ah(dev->sm_ah[p],
+                                       RDMA_DESTROY_AH_SLEEPABLE);
        }
 }
index c8a7c37..82cb6b7 100644 (file)
@@ -432,7 +432,7 @@ static struct ib_ah *mthca_ah_create(struct ib_pd *pd,
        return &ah->ibah;
 }
 
-static int mthca_ah_destroy(struct ib_ah *ah)
+static int mthca_ah_destroy(struct ib_ah *ah, u32 flags)
 {
        mthca_destroy_ah(to_mdev(ah->device), to_mah(ah));
        kfree(ah);
index 62c5022..a729532 100644 (file)
@@ -219,7 +219,7 @@ av_err:
        return ERR_PTR(status);
 }
 
-int ocrdma_destroy_ah(struct ib_ah *ibah)
+int ocrdma_destroy_ah(struct ib_ah *ibah, u32 flags)
 {
        struct ocrdma_ah *ah = get_ocrdma_ah(ibah);
        struct ocrdma_dev *dev = get_ocrdma_dev(ibah->device);
index c407022..eb996e1 100644 (file)
@@ -53,7 +53,7 @@ enum {
 
 struct ib_ah *ocrdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
                               u32 flags, struct ib_udata *udata);
-int ocrdma_destroy_ah(struct ib_ah *ah);
+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_process_mad(struct ib_device *,
index bb53c08..b342a70 100644 (file)
@@ -2628,7 +2628,7 @@ struct ib_ah *qedr_create_ah(struct ib_pd *ibpd, struct rdma_ah_attr *attr,
        return &ah->ibah;
 }
 
-int qedr_destroy_ah(struct ib_ah *ibah)
+int qedr_destroy_ah(struct ib_ah *ibah, u32 flags)
 {
        struct qedr_ah *ah = get_qedr_ah(ibah);
 
index 80ac864..1852b70 100644 (file)
@@ -77,7 +77,7 @@ int qedr_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr,
                       const struct ib_recv_wr **bad_recv_wr);
 struct ib_ah *qedr_create_ah(struct ib_pd *ibpd, struct rdma_ah_attr *attr,
                             u32 flags, struct ib_udata *udata);
-int qedr_destroy_ah(struct ib_ah *ibah);
+int qedr_destroy_ah(struct ib_ah *ibah, u32 flags);
 
 int qedr_dereg_mr(struct ib_mr *);
 struct ib_mr *qedr_get_dma_mr(struct ib_pd *, int acc);
index 4845d00..f92faf5 100644 (file)
@@ -2494,5 +2494,6 @@ void qib_notify_free_mad_agent(struct rvt_dev_info *rdi, int port_idx)
                del_timer_sync(&dd->pport[port_idx].cong_stats.timer);
 
        if (dd->pport[port_idx].ibport_data.smi_ah)
-               rdma_destroy_ah(&dd->pport[port_idx].ibport_data.smi_ah->ibah);
+               rdma_destroy_ah(&dd->pport[port_idx].ibport_data.smi_ah->ibah,
+                               RDMA_DESTROY_AH_SLEEPABLE);
 }
index fa47714..1b9f69d 100644 (file)
@@ -768,7 +768,7 @@ struct ib_ah *usnic_ib_create_ah(struct ib_pd *pd,
        return ERR_PTR(-EPERM);
 }
 
-int usnic_ib_destroy_ah(struct ib_ah *ah)
+int usnic_ib_destroy_ah(struct ib_ah *ah, u32 flags)
 {
        usnic_dbg("\n");
        return -EINVAL;
index 066f536..e331442 100644 (file)
@@ -80,7 +80,7 @@ struct ib_ah *usnic_ib_create_ah(struct ib_pd *pd,
                                 u32 flags,
                                 struct ib_udata *udata);
 
-int usnic_ib_destroy_ah(struct ib_ah *ah);
+int usnic_ib_destroy_ah(struct ib_ah *ah, u32 flags);
 int usnic_ib_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr,
                        const struct ib_send_wr **bad_wr);
 int usnic_ib_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *wr,
index 08ea4b9..4d238d0 100644 (file)
@@ -582,10 +582,11 @@ struct ib_ah *pvrdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
 /**
  * pvrdma_destroy_ah - destroy an address handle
  * @ah: the address handle to destroyed
+ * @flags: destroy address handle flags (see enum rdma_destroy_ah_flags)
  *
  * @return: 0 on success.
  */
-int pvrdma_destroy_ah(struct ib_ah *ah)
+int pvrdma_destroy_ah(struct ib_ah *ah, u32 flags)
 {
        struct pvrdma_dev *dev = to_vdev(ah->device);
 
index d872e6a..f7f758d 100644 (file)
@@ -421,7 +421,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);
 struct ib_ah *pvrdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
                               u32 flags, struct ib_udata *udata);
-int pvrdma_destroy_ah(struct ib_ah *ah);
+int pvrdma_destroy_ah(struct ib_ah *ah, u32 flags);
 
 struct ib_srq *pvrdma_create_srq(struct ib_pd *pd,
                                 struct ib_srq_init_attr *init_attr,
index 43e4687..fc10e4e 100644 (file)
@@ -137,10 +137,11 @@ struct ib_ah *rvt_create_ah(struct ib_pd *pd,
 /**
  * rvt_destory_ah - Destory an address handle
  * @ibah: address handle
+ * @destroy_flags: destroy address handle flags (see enum rdma_destroy_ah_flags)
  *
  * Return: 0 on success
  */
-int rvt_destroy_ah(struct ib_ah *ibah)
+int rvt_destroy_ah(struct ib_ah *ibah, u32 destroy_flags)
 {
        struct rvt_dev_info *dev = ib_to_rvt(ibah->device);
        struct rvt_ah *ah = ibah_to_rvtah(ibah);
index 70f8d08..72431a6 100644 (file)
@@ -54,7 +54,7 @@ struct ib_ah *rvt_create_ah(struct ib_pd *pd,
                            struct rdma_ah_attr *ah_attr,
                            u32 create_flags,
                            struct ib_udata *udata);
-int rvt_destroy_ah(struct ib_ah *ibah);
+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_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
 
index d6981dc..108c71e 100644 (file)
@@ -160,7 +160,8 @@ void rvt_free_mad_agents(struct rvt_dev_info *rdi)
                        ib_unregister_mad_agent(agent);
                }
                if (rvp->sm_ah) {
-                       rdma_destroy_ah(&rvp->sm_ah->ibah);
+                       rdma_destroy_ah(&rvp->sm_ah->ibah,
+                                       RDMA_DESTROY_AH_SLEEPABLE);
                        rvp->sm_ah = NULL;
                }
 
index 9c0ae9a..b20e6e0 100644 (file)
@@ -267,7 +267,7 @@ static int rxe_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr)
        return 0;
 }
 
-static int rxe_destroy_ah(struct ib_ah *ibah)
+static int rxe_destroy_ah(struct ib_ah *ibah, u32 flags)
 {
        struct rxe_ah *ah = to_rah(ibah);
 
index 1ecf210..6d35570 100644 (file)
@@ -678,7 +678,7 @@ static void __ipoib_reap_ah(struct net_device *dev)
        list_for_each_entry_safe(ah, tah, &priv->dead_ahs, list)
                if ((int) priv->tx_tail - (int) ah->last_send >= 0) {
                        list_del(&ah->list);
-                       rdma_destroy_ah(ah->ah);
+                       rdma_destroy_ah(ah->ah, 0);
                        kfree(ah);
                }
 
index 2f4f638..560e4f2 100644 (file)
@@ -606,7 +606,7 @@ static void vema_set(struct opa_vnic_vema_port *port,
 static void vema_send(struct ib_mad_agent *mad_agent,
                      struct ib_mad_send_wc *mad_wc)
 {
-       rdma_destroy_ah(mad_wc->send_buf->ah);
+       rdma_destroy_ah(mad_wc->send_buf->ah, RDMA_DESTROY_AH_SLEEPABLE);
        ib_free_send_mad(mad_wc->send_buf);
 }
 
@@ -680,7 +680,7 @@ static void vema_recv(struct ib_mad_agent *mad_agent,
        ib_free_send_mad(rsp);
 
 err_rsp:
-       rdma_destroy_ah(ah);
+       rdma_destroy_ah(ah, RDMA_DESTROY_AH_SLEEPABLE);
 free_recv_mad:
        ib_free_recv_mad(mad_wc);
 }
@@ -848,7 +848,7 @@ void opa_vnic_vema_send_trap(struct opa_vnic_adapter *adapter,
        }
 
 err_sndbuf:
-       rdma_destroy_ah(ah);
+       rdma_destroy_ah(ah, 0);
 err_exit:
        v_err("Aborting trap\n");
 }
index bddd0ad..b2f63a6 100644 (file)
@@ -458,7 +458,7 @@ static void srpt_mgmt_method_get(struct srpt_port *sp, struct ib_mad *rq_mad,
 static void srpt_mad_send_handler(struct ib_mad_agent *mad_agent,
                                  struct ib_mad_send_wc *mad_wc)
 {
-       rdma_destroy_ah(mad_wc->send_buf->ah);
+       rdma_destroy_ah(mad_wc->send_buf->ah, RDMA_DESTROY_AH_SLEEPABLE);
        ib_free_send_mad(mad_wc->send_buf);
 }
 
@@ -525,7 +525,7 @@ static void srpt_mad_recv_handler(struct ib_mad_agent *mad_agent,
        ib_free_send_mad(rsp);
 
 err_rsp:
-       rdma_destroy_ah(ah);
+       rdma_destroy_ah(ah, RDMA_DESTROY_AH_SLEEPABLE);
 err:
        ib_free_recv_mad(mad_wc);
 }
index 86ae878..a3ceed3 100644 (file)
@@ -2381,7 +2381,7 @@ struct ib_device_ops {
                                   struct ib_udata *udata);
        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 (*destroy_ah)(struct ib_ah *ah);
+       int (*destroy_ah)(struct ib_ah *ah, u32 flags);
        struct ib_srq *(*create_srq)(struct ib_pd *pd,
                                     struct ib_srq_init_attr *srq_init_attr,
                                     struct ib_udata *udata);
@@ -3256,11 +3256,17 @@ int rdma_modify_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
  */
 int rdma_query_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
 
+enum rdma_destroy_ah_flags {
+       /* In a sleepable context */
+       RDMA_DESTROY_AH_SLEEPABLE = BIT(0),
+};
+
 /**
  * rdma_destroy_ah - Destroys an address handle.
  * @ah: The address handle to destroy.
+ * @flags: Destroy address handle flags (see enum rdma_destroy_ah_flags).
  */
-int rdma_destroy_ah(struct ib_ah *ah);
+int rdma_destroy_ah(struct ib_ah *ah, u32 flags);
 
 /**
  * ib_create_srq - Creates a SRQ associated with the specified protection