]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
RDMA: Mark if create address handle is in a sleepable context
authorGal Pressman <galpress@amazon.com>
Wed, 12 Dec 2018 09:09:05 +0000 (11:09 +0200)
committerJason Gunthorpe <jgg@mellanox.com>
Wed, 19 Dec 2018 23:17:19 +0000 (16:17 -0700)
Introduce a 'flags' field to create 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>
30 files changed:
drivers/infiniband/core/cm.c
drivers/infiniband/core/sa_query.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/hfi1/mad.c
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_verbs.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/rxe/rxe_verbs.c
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/infiniband/ulp/opa_vnic/opa_vnic_vema.c
include/rdma/ib_verbs.h

index edb2cb758be729a4f6ac65ca5a211452726f87d6..cf5b3c4314bbe420bac67f1110582357a72c8f73 100644 (file)
@@ -343,7 +343,7 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv,
                ret = -ENODEV;
                goto out;
        }
-       ah = rdma_create_ah(mad_agent->qp->pd, &av->ah_attr);
+       ah = rdma_create_ah(mad_agent->qp->pd, &av->ah_attr, 0);
        if (IS_ERR(ah)) {
                ret = PTR_ERR(ah);
                goto out;
index be5ba5e15496cdd7aa95a5e6f111b4444f5a3dec..fb96d9df1fddc8321648d03bf8451d598d1e4873 100644 (file)
@@ -2276,7 +2276,8 @@ static void update_sm_ah(struct work_struct *work)
                                         cpu_to_be64(IB_SA_WELL_KNOWN_GUID));
        }
 
-       new_ah->ah = rdma_create_ah(port->agent->qp->pd, &ah_attr);
+       new_ah->ah = rdma_create_ah(port->agent->qp->pd, &ah_attr,
+                                   RDMA_CREATE_AH_SLEEPABLE);
        if (IS_ERR(new_ah->ah)) {
                pr_warn("Couldn't create new SM AH\n");
                kfree(new_ah);
index bc0b3a150e3c5d6b5c8b1922e53103bb930cb611..4e2df239447e8acb75a98240e13e85e16e1eb6fd 100644 (file)
@@ -487,14 +487,17 @@ rdma_update_sgid_attr(struct rdma_ah_attr *ah_attr,
 
 static struct ib_ah *_rdma_create_ah(struct ib_pd *pd,
                                     struct rdma_ah_attr *ah_attr,
+                                    u32 flags,
                                     struct ib_udata *udata)
 {
        struct ib_ah *ah;
 
+       might_sleep_if(flags & RDMA_CREATE_AH_SLEEPABLE);
+
        if (!pd->device->ops.create_ah)
                return ERR_PTR(-EOPNOTSUPP);
 
-       ah = pd->device->ops.create_ah(pd, ah_attr, udata);
+       ah = pd->device->ops.create_ah(pd, ah_attr, flags, udata);
 
        if (!IS_ERR(ah)) {
                ah->device  = pd->device;
@@ -514,12 +517,14 @@ static struct ib_ah *_rdma_create_ah(struct ib_pd *pd,
  * given address vector.
  * @pd: The protection domain associated with the address handle.
  * @ah_attr: The attributes of the address vector.
+ * @flags: Create address handle flags (see enum rdma_create_ah_flags).
  *
  * It returns 0 on success and returns appropriate error code on error.
  * The address handle is used to reference a local or global destination
  * in all UD QP post sends.
  */
-struct ib_ah *rdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr)
+struct ib_ah *rdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
+                            u32 flags)
 {
        const struct ib_gid_attr *old_sgid_attr;
        struct ib_ah *ah;
@@ -529,7 +534,7 @@ struct ib_ah *rdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr)
        if (ret)
                return ERR_PTR(ret);
 
-       ah = _rdma_create_ah(pd, ah_attr, NULL);
+       ah = _rdma_create_ah(pd, ah_attr, flags, NULL);
 
        rdma_unfill_sgid_attr(ah_attr, old_sgid_attr);
        return ah;
@@ -569,7 +574,7 @@ struct ib_ah *rdma_create_user_ah(struct ib_pd *pd,
                }
        }
 
-       ah = _rdma_create_ah(pd, ah_attr, udata);
+       ah = _rdma_create_ah(pd, ah_attr, RDMA_CREATE_AH_SLEEPABLE, udata);
 
 out:
        rdma_unfill_sgid_attr(ah_attr, old_sgid_attr);
@@ -881,7 +886,7 @@ struct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, const struct ib_wc *wc,
        if (ret)
                return ERR_PTR(ret);
 
-       ah = rdma_create_ah(pd, &ah_attr);
+       ah = rdma_create_ah(pd, &ah_attr, RDMA_CREATE_AH_SLEEPABLE);
 
        rdma_destroy_ah_attr(&ah_attr);
        return ah;
index 611bacd00b80e9d018f371776ae4ad8f50ac13d9..4b37bc3edc817e2559bf885fc2c7922fe56d8e2a 100644 (file)
@@ -664,6 +664,7 @@ int bnxt_re_destroy_ah(struct ib_ah *ib_ah)
 
 struct ib_ah *bnxt_re_create_ah(struct ib_pd *ib_pd,
                                struct rdma_ah_attr *ah_attr,
+                               u32 flags,
                                struct ib_udata *udata)
 {
        struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
index aa33e7b82c84632972bd6ceeec8199272ef9ffb1..6675db4b4ba403f1c468182d7032540de04d451a 100644 (file)
@@ -169,6 +169,7 @@ struct ib_pd *bnxt_re_alloc_pd(struct ib_device *ibdev,
 int bnxt_re_dealloc_pd(struct ib_pd *pd);
 struct ib_ah *bnxt_re_create_ah(struct ib_pd *pd,
                                struct rdma_ah_attr *ah_attr,
+                               u32 flags,
                                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);
index 88a0cf9301369cc850d2a119fb7fc63cc26c2f72..4228393e6c4cc30ee4e2f08a1d1198f55b010163 100644 (file)
@@ -305,7 +305,7 @@ static struct ib_ah *hfi1_create_qp0_ah(struct hfi1_ibport *ibp, u32 dlid)
        rcu_read_lock();
        qp0 = rcu_dereference(ibp->rvp.qp[0]);
        if (qp0)
-               ah = rdma_create_ah(qp0->ibqp.pd, &attr);
+               ah = rdma_create_ah(qp0->ibqp.pd, &attr, 0);
        rcu_read_unlock();
        return ah;
 }
index 9990dc9eb96a14803be2633115af9b70863e0353..dae4c54f021ddaab4fb2764af55e03ff3725cdf9 100644 (file)
@@ -41,6 +41,7 @@
 
 struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd,
                                 struct rdma_ah_attr *ah_attr,
+                                u32 flags,
                                 struct ib_udata *udata)
 {
        struct hns_roce_dev *hr_dev = to_hr_dev(ibpd->device);
index 67609cc6a45e9233dd1341c5259348df102376ca..b2c46821c283516225c152e3d2ea8b9ce6b2c4b1 100644 (file)
@@ -1056,6 +1056,7 @@ void hns_roce_bitmap_free_range(struct hns_roce_bitmap *bitmap,
 
 struct ib_ah *hns_roce_create_ah(struct ib_pd *pd,
                                 struct rdma_ah_attr *ah_attr,
+                                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);
index e9e3a6f390dba73156b3c9394888516070761ea4..6c0e6bcf1bffc144a09737744565ee7f240f5d25 100644 (file)
@@ -144,7 +144,7 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd,
 }
 
 struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
-                               struct ib_udata *udata)
+                               u32 flags, struct ib_udata *udata)
 
 {
        struct mlx4_ib_ah *ah;
@@ -189,7 +189,7 @@ struct ib_ah *mlx4_ib_create_ah_slave(struct ib_pd *pd,
 
        slave_attr.grh.sgid_attr = NULL;
        slave_attr.grh.sgid_index = slave_sgid_index;
-       ah = mlx4_ib_create_ah(pd, &slave_attr, NULL);
+       ah = mlx4_ib_create_ah(pd, &slave_attr, 0, NULL);
        if (IS_ERR(ah))
                return ah;
 
index 8942f5f7f04dfc137afe97666a3615c04249d779..b227f7c2fca29f2fe3637c5aaf1180628d08e8df 100644 (file)
@@ -202,7 +202,7 @@ static void update_sm_ah(struct mlx4_ib_dev *dev, u8 port_num, u16 lid, u8 sl)
        rdma_ah_set_port_num(&ah_attr, port_num);
 
        new_ah = rdma_create_ah(dev->send_agent[port_num - 1][0]->qp->pd,
-                               &ah_attr);
+                               &ah_attr, 0);
        if (IS_ERR(new_ah))
                return;
 
@@ -567,7 +567,7 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port,
                        return -EINVAL;
                rdma_ah_set_grh(&attr, &dgid, 0, 0, 0, 0);
        }
-       ah = rdma_create_ah(tun_ctx->pd, &attr);
+       ah = rdma_create_ah(tun_ctx->pd, &attr, 0);
        if (IS_ERR(ah))
                return -ENOMEM;
 
index 5cb52424912e2fdcc6171f20d63f6fa65a29f9e7..7b827b185d5fcaaea5401f5fd04fe0e11d968305 100644 (file)
@@ -754,7 +754,7 @@ void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq)
 void mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq);
 
 struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
-                               struct ib_udata *udata);
+                               u32 flags, struct ib_udata *udata);
 struct ib_ah *mlx4_ib_create_ah_slave(struct ib_pd *pd,
                                      struct rdma_ah_attr *ah_attr,
                                      int slave_sgid_index, u8 *s_mac,
index ffd03bf1a71ee91e28bb11b5c40ef9a7efe312a1..536c2c067b94119667c1cd010800fc7206920bf7 100644 (file)
@@ -72,7 +72,7 @@ static struct ib_ah *create_ib_ah(struct mlx5_ib_dev *dev,
 }
 
 struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
-                               struct ib_udata *udata)
+                               u32 flags, struct ib_udata *udata)
 
 {
        struct mlx5_ib_ah *ah;
index 9b4e2554889a256fda9758ae0c935e36d8390b27..ebf700298acbbdb9e7596c00f34aa3f379b8f3ba 100644 (file)
@@ -1042,7 +1042,7 @@ int mlx5_MAD_IFC(struct mlx5_ib_dev *dev, int ignore_mkey, int ignore_bkey,
                 u8 port, const struct ib_wc *in_wc, const struct ib_grh *in_grh,
                 const void *in_mad, void *response_mad);
 struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
-                               struct ib_udata *udata);
+                               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);
 struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
index 2e5dc0a67cfc41a6fe07c4988047e00d30647677..4a5916d8f7da05bcfc0affa83a12272cfc4243fb 100644 (file)
@@ -89,7 +89,7 @@ static void update_sm_ah(struct mthca_dev *dev,
        rdma_ah_set_port_num(&ah_attr, port_num);
 
        new_ah = rdma_create_ah(dev->send_agent[port_num - 1][0]->qp->pd,
-                               &ah_attr);
+                               &ah_attr, 0);
        if (IS_ERR(new_ah))
                return;
 
index 443521cf8107b3474af1a02745d5a876b95dc37b..c8a7c37655583cbc955d331de01d10136a0fdbb7 100644 (file)
@@ -412,6 +412,7 @@ static int mthca_dealloc_pd(struct ib_pd *pd)
 
 static struct ib_ah *mthca_ah_create(struct ib_pd *pd,
                                     struct rdma_ah_attr *ah_attr,
+                                    u32 flags,
                                     struct ib_udata *udata)
 
 {
index 58188fe5aed25d852a18f34a309ef0808d92fe95..62c5022207244d85b3179c0857bcfedc52bfc1f2 100644 (file)
@@ -157,7 +157,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
 }
 
 struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct rdma_ah_attr *attr,
-                              struct ib_udata *udata)
+                              u32 flags, struct ib_udata *udata)
 {
        u32 *ahid_addr;
        int status;
index c0c32c9b80ae8ef9c13cd2edfa1b36892ec0fa8d..c407022d885c46465b2bef3078d7f9a85db91f1d 100644 (file)
@@ -52,7 +52,7 @@ enum {
 };
 
 struct ib_ah *ocrdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
-                              struct ib_udata *udata);
+                              u32 flags, struct ib_udata *udata);
 int ocrdma_destroy_ah(struct ib_ah *ah);
 int ocrdma_query_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
 
index 8056121e9f69d9f67914d30958699740410de37d..bb53c08b86c125f40787f6dfe4e40f6484413e60 100644 (file)
@@ -2615,7 +2615,7 @@ int qedr_destroy_qp(struct ib_qp *ibqp)
 }
 
 struct ib_ah *qedr_create_ah(struct ib_pd *ibpd, struct rdma_ah_attr *attr,
-                            struct ib_udata *udata)
+                            u32 flags, struct ib_udata *udata)
 {
        struct qedr_ah *ah;
 
index 0b7d0124b16cc93228d9e0e287af9de48ef4bcc5..80ac864dbc7874502a078f893dbdc23bac268f9c 100644 (file)
@@ -76,7 +76,7 @@ int qedr_destroy_srq(struct ib_srq *ibsrq);
 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,
-                            struct ib_udata *udata);
+                            u32 flags, struct ib_udata *udata);
 int qedr_destroy_ah(struct ib_ah *ibah);
 
 int qedr_dereg_mr(struct ib_mr *);
index 611a6b5ef83f6ce886b07c3f2a3923c3f44663a4..276304f611abc29c8c5519ab7d0489e305e80399 100644 (file)
@@ -1362,7 +1362,7 @@ struct ib_ah *qib_create_qp0_ah(struct qib_ibport *ibp, u16 dlid)
        rcu_read_lock();
        qp0 = rcu_dereference(ibp->rvp.qp[0]);
        if (qp0)
-               ah = rdma_create_ah(qp0->ibqp.pd, &attr);
+               ah = rdma_create_ah(qp0->ibqp.pd, &attr, 0);
        rcu_read_unlock();
        return ah;
 }
index 0b91ff36768a3fa373d55b7b7f375271ae98a3c5..fa477140f5489d41ae26a61373b81ab9f71e351a 100644 (file)
@@ -760,6 +760,7 @@ int usnic_ib_mmap(struct ib_ucontext *context,
 /* In ib callbacks section -  Start of stub funcs */
 struct ib_ah *usnic_ib_create_ah(struct ib_pd *pd,
                                 struct rdma_ah_attr *ah_attr,
+                                u32 flags,
                                 struct ib_udata *udata)
 
 {
index 2a2c9beb715f0aae8d9dd606f743ea76ce010329..066f53636d0b0154b5e2ac1f846d6e373d14fd6b 100644 (file)
@@ -77,6 +77,7 @@ int usnic_ib_mmap(struct ib_ucontext *context,
                        struct vm_area_struct *vma);
 struct ib_ah *usnic_ib_create_ah(struct ib_pd *pd,
                                 struct rdma_ah_attr *ah_attr,
+                                u32 flags,
                                 struct ib_udata *udata);
 
 int usnic_ib_destroy_ah(struct ib_ah *ah);
index f4cb5cf26006f00316e76299ce60fe452760216b..08ea4b9e4c6c577f211eedf089feb559cca2e837 100644 (file)
@@ -533,11 +533,12 @@ int pvrdma_dealloc_pd(struct ib_pd *pd)
  * @pd: the protection domain
  * @ah_attr: the attributes of the AH
  * @udata: user data blob
+ * @flags: create address handle flags (see enum rdma_create_ah_flags)
  *
  * @return: the ib_ah pointer on success, otherwise errno.
  */
 struct ib_ah *pvrdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
-                              struct ib_udata *udata)
+                              u32 flags, struct ib_udata *udata)
 {
        struct pvrdma_dev *dev = to_vdev(pd->device);
        struct pvrdma_ah *ah;
index b2e3ab50cb08973523218be7f74b0fd03ca00e1a..d872e6aa159c7c26b1e74f3f6fbecc186be29169 100644 (file)
@@ -420,7 +420,7 @@ int pvrdma_destroy_cq(struct ib_cq *cq);
 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,
-                              struct ib_udata *udata);
+                              u32 flags, struct ib_udata *udata);
 int pvrdma_destroy_ah(struct ib_ah *ah);
 
 struct ib_srq *pvrdma_create_srq(struct ib_pd *pd,
index 084bb4baebb50a1fe061bd3fa2be0e2deed2ae89..43e46877d300a52250c8ec6f14ab12a3fccb6298 100644 (file)
@@ -91,6 +91,7 @@ EXPORT_SYMBOL(rvt_check_ah);
  * rvt_create_ah - create an address handle
  * @pd: the protection domain
  * @ah_attr: the attributes of the AH
+ * @create_flags: create address handle flags (see enum rdma_create_ah_flags)
  * @udata: pointer to user's input output buffer information.
  *
  * This may be called from interrupt context.
@@ -99,6 +100,7 @@ EXPORT_SYMBOL(rvt_check_ah);
  */
 struct ib_ah *rvt_create_ah(struct ib_pd *pd,
                            struct rdma_ah_attr *ah_attr,
+                           u32 create_flags,
                            struct ib_udata *udata)
 {
        struct rvt_ah *ah;
index 25271b48a6830c5b6b962095c8fee2b33503036c..70f8d089f740fff9fe502af416995b4ef0af98b5 100644 (file)
@@ -52,6 +52,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_modify_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
index 8d15b1e11a2f14b8d09ab45885fbf89d7a1b9d01..9c0ae9a2631947a1c7dac08e0e4fee44ca1bd2f9 100644 (file)
@@ -219,6 +219,7 @@ static void rxe_init_av(struct rxe_dev *rxe, struct rdma_ah_attr *attr,
 
 static struct ib_ah *rxe_create_ah(struct ib_pd *ibpd,
                                   struct rdma_ah_attr *attr,
+                                  u32 flags,
                                   struct ib_udata *udata)
 
 {
index 9006a13af1de2e5d36fae471cb2946de911be5fe..1ecf21006f72e1dd33a9d2710cfff84cfdf5c335 100644 (file)
@@ -66,7 +66,7 @@ struct ipoib_ah *ipoib_create_ah(struct net_device *dev,
        ah->last_send = 0;
        kref_init(&ah->ref);
 
-       vah = rdma_create_ah(pd, attr);
+       vah = rdma_create_ah(pd, attr, RDMA_CREATE_AH_SLEEPABLE);
        if (IS_ERR(vah)) {
                kfree(ah);
                ah = (struct ipoib_ah *)vah;
index d119d9afa845a745fc637e1c81d8c4c9f2e7a31c..2f4f63847c1093ef905c06790f2fe08b28ed48a4 100644 (file)
@@ -777,7 +777,7 @@ void opa_vnic_vema_send_trap(struct opa_vnic_adapter *adapter,
        }
 
        rdma_ah_set_dlid(&ah_attr, trap_lid);
-       ah = rdma_create_ah(port->mad_agent->qp->pd, &ah_attr);
+       ah = rdma_create_ah(port->mad_agent->qp->pd, &ah_attr, 0);
        if (IS_ERR(ah)) {
                c_err("%s:Couldn't create new AH = %p\n", __func__, ah);
                c_err("%s:dlid = %d, sl = %d, port = %d\n", __func__,
index 0ec15d673d92cb07918145bf6ece3c88adccee0e..86ae878e1de4293fcdcbe2333170607bb9a82b2c 100644 (file)
@@ -2377,7 +2377,7 @@ struct ib_device_ops {
                                  struct ib_udata *udata);
        int (*dealloc_pd)(struct ib_pd *pd);
        struct ib_ah *(*create_ah)(struct ib_pd *pd,
-                                  struct rdma_ah_attr *ah_attr,
+                                  struct rdma_ah_attr *ah_attr, u32 flags,
                                   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);
@@ -3151,15 +3151,22 @@ struct ib_pd *__ib_alloc_pd(struct ib_device *device, unsigned int flags,
        __ib_alloc_pd((device), (flags), KBUILD_MODNAME)
 void ib_dealloc_pd(struct ib_pd *pd);
 
+enum rdma_create_ah_flags {
+       /* In a sleepable context */
+       RDMA_CREATE_AH_SLEEPABLE = BIT(0),
+};
+
 /**
  * rdma_create_ah - Creates an address handle for the given address vector.
  * @pd: The protection domain associated with the address handle.
  * @ah_attr: The attributes of the address vector.
+ * @flags: Create address handle flags (see enum rdma_create_ah_flags).
  *
  * The address handle is used to reference a local or global destination
  * in all UD QP post sends.
  */
-struct ib_ah *rdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr);
+struct ib_ah *rdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
+                            u32 flags);
 
 /**
  * rdma_create_user_ah - Creates an address handle for the given address vector.