diff mbox series

[rdma-next,1/4] RDMA: Mark if create address handle is in a sleepable context

Message ID 1544518768-16361-2-git-send-email-galpress@amazon.com (mailing list archive)
State Superseded
Delegated to: Jason Gunthorpe
Headers show
Series Mark create/destroy address handle calls as atomic/sleepable | expand

Commit Message

Gal Pressman Dec. 11, 2018, 8:59 a.m. UTC
Add a 'sleepable' flag to mark 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>
---
 drivers/infiniband/core/cm.c                    |  2 +-
 drivers/infiniband/core/sa_query.c              |  2 +-
 drivers/infiniband/core/verbs.c                 | 15 ++++++++++-----
 drivers/infiniband/hw/bnxt_re/ib_verbs.c        |  1 +
 drivers/infiniband/hw/bnxt_re/ib_verbs.h        |  1 +
 drivers/infiniband/hw/hfi1/mad.c                |  2 +-
 drivers/infiniband/hw/hns/hns_roce_ah.c         |  1 +
 drivers/infiniband/hw/hns/hns_roce_device.h     |  1 +
 drivers/infiniband/hw/mlx4/ah.c                 |  4 ++--
 drivers/infiniband/hw/mlx4/mad.c                |  4 ++--
 drivers/infiniband/hw/mlx4/mlx4_ib.h            |  2 +-
 drivers/infiniband/hw/mlx5/ah.c                 |  2 +-
 drivers/infiniband/hw/mlx5/mlx5_ib.h            |  2 +-
 drivers/infiniband/hw/mthca/mthca_mad.c         |  2 +-
 drivers/infiniband/hw/mthca/mthca_provider.c    |  1 +
 drivers/infiniband/hw/ocrdma/ocrdma_ah.c        |  2 +-
 drivers/infiniband/hw/ocrdma/ocrdma_ah.h        |  2 +-
 drivers/infiniband/hw/qedr/verbs.c              |  2 +-
 drivers/infiniband/hw/qedr/verbs.h              |  2 +-
 drivers/infiniband/hw/qib/qib_verbs.c           |  2 +-
 drivers/infiniband/hw/usnic/usnic_ib_verbs.c    |  1 +
 drivers/infiniband/hw/usnic/usnic_ib_verbs.h    |  1 +
 drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c |  3 ++-
 drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h |  2 +-
 drivers/infiniband/sw/rxe/rxe_verbs.c           |  1 +
 drivers/infiniband/ulp/ipoib/ipoib_ib.c         |  2 +-
 drivers/infiniband/ulp/opa_vnic/opa_vnic_vema.c |  2 +-
 include/rdma/ib_verbs.h                         |  5 ++++-
 28 files changed, 43 insertions(+), 26 deletions(-)

Comments

Jason Gunthorpe Dec. 11, 2018, 4:22 p.m. UTC | #1
On Tue, Dec 11, 2018 at 10:59:25AM +0200, Gal Pressman wrote:

> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
> index 85021451eee0..499d96302262 100644
> +++ b/include/rdma/ib_verbs.h
> @@ -2374,6 +2374,7 @@ struct ib_device {
>  	int                        (*dealloc_pd)(struct ib_pd *pd);
>  	struct ib_ah *             (*create_ah)(struct ib_pd *pd,
>  						struct rdma_ah_attr *ah_attr,
> +						bool sleepable,
>  						struct ib_udata *udata);

I think the Linux style consensus here is that these should be a flag with a
enum name not a bool

> @@ -3180,11 +3181,13 @@ void ib_dealloc_pd(struct ib_pd *pd);
>   * 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.
> + * @sleepable: In a sleepable context.
>   *
>   * 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,
> +			     bool sleepable);

Probably here too

Jason
Gal Pressman Dec. 11, 2018, 4:31 p.m. UTC | #2
On 11-Dec-18 18:22, Jason Gunthorpe wrote:
> On Tue, Dec 11, 2018 at 10:59:25AM +0200, Gal Pressman wrote:
> 
>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>> index 85021451eee0..499d96302262 100644
>> +++ b/include/rdma/ib_verbs.h
>> @@ -2374,6 +2374,7 @@ struct ib_device {
>>  	int                        (*dealloc_pd)(struct ib_pd *pd);
>>  	struct ib_ah *             (*create_ah)(struct ib_pd *pd,
>>  						struct rdma_ah_attr *ah_attr,
>> +						bool sleepable,
>>  						struct ib_udata *udata);
> 
> I think the Linux style consensus here is that these should be a flag with a
> enum name not a bool

Will change.
I'm familiar with the no bool fields in structs
(https://lkml.org/lkml/2017/11/21/384), good to know it applies to function
parameters as well.

> 
>> @@ -3180,11 +3181,13 @@ void ib_dealloc_pd(struct ib_pd *pd);
>>   * 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.
>> + * @sleepable: In a sleepable context.
>>   *
>>   * 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,
>> +			     bool sleepable);
> 
> Probably here too
> 
> Jason
>
Jason Gunthorpe Dec. 11, 2018, 5:03 p.m. UTC | #3
On Tue, Dec 11, 2018 at 06:31:09PM +0200, Gal Pressman wrote:
> On 11-Dec-18 18:22, Jason Gunthorpe wrote:
> > On Tue, Dec 11, 2018 at 10:59:25AM +0200, Gal Pressman wrote:
> > 
> >> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
> >> index 85021451eee0..499d96302262 100644
> >> +++ b/include/rdma/ib_verbs.h
> >> @@ -2374,6 +2374,7 @@ struct ib_device {
> >>  	int                        (*dealloc_pd)(struct ib_pd *pd);
> >>  	struct ib_ah *             (*create_ah)(struct ib_pd *pd,
> >>  						struct rdma_ah_attr *ah_attr,
> >> +						bool sleepable,
> >>  						struct ib_udata *udata);
> > 
> > I think the Linux style consensus here is that these should be a flag with a
> > enum name not a bool
> 
> Will change.
> I'm familiar with the no bool fields in structs
> (https://lkml.org/lkml/2017/11/21/384), good to know it applies to function
> parameters as well.

I think it is under the rational that

foo(true)

tells the user nothing, while

foo(DO_SOMETHING)

Should be more informative

Same argument applies to 'int' pretending to be bool

At least a struct member has a name..

Jason
Gal Pressman Dec. 12, 2018, 7:17 a.m. UTC | #4
On 11-Dec-18 19:03, Jason Gunthorpe wrote:
> On Tue, Dec 11, 2018 at 06:31:09PM +0200, Gal Pressman wrote:
>> On 11-Dec-18 18:22, Jason Gunthorpe wrote:
>>> On Tue, Dec 11, 2018 at 10:59:25AM +0200, Gal Pressman wrote:
>>>
>>>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>>>> index 85021451eee0..499d96302262 100644
>>>> +++ b/include/rdma/ib_verbs.h
>>>> @@ -2374,6 +2374,7 @@ struct ib_device {
>>>>  	int                        (*dealloc_pd)(struct ib_pd *pd);
>>>>  	struct ib_ah *             (*create_ah)(struct ib_pd *pd,
>>>>  						struct rdma_ah_attr *ah_attr,
>>>> +						bool sleepable,
>>>>  						struct ib_udata *udata);
>>>
>>> I think the Linux style consensus here is that these should be a flag with a
>>> enum name not a bool
>>
>> Will change.
>> I'm familiar with the no bool fields in structs
>> (https://lkml.org/lkml/2017/11/21/384), good to know it applies to function
>> parameters as well.
> 
> I think it is under the rational that
> 
> foo(true)
> 
> tells the user nothing, while
> 
> foo(DO_SOMETHING)
> 
> Should be more informative
> 
> Same argument applies to 'int' pretending to be bool
> 
> At least a struct member has a name..
> 
> Jason
> 

That makes sense, thanks for the explanation.
diff mbox series

Patch

diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index edb2cb758be7..3dec43a5d50d 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -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, false);
 	if (IS_ERR(ah)) {
 		ret = PTR_ERR(ah);
 		goto out;
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index be5ba5e15496..6256681c5f9f 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -2276,7 +2276,7 @@  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, true);
 	if (IS_ERR(new_ah->ah)) {
 		pr_warn("Couldn't create new SM AH\n");
 		kfree(new_ah);
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 178899e3ce73..350b3992af64 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -475,14 +475,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,
+				     bool sleepable,
 				     struct ib_udata *udata)
 {
 	struct ib_ah *ah;
 
+	might_sleep_if(sleepable);
+
 	if (!pd->device->create_ah)
 		return ERR_PTR(-EOPNOTSUPP);
 
-	ah = pd->device->create_ah(pd, ah_attr, udata);
+	ah = pd->device->create_ah(pd, ah_attr, sleepable, udata);
 
 	if (!IS_ERR(ah)) {
 		ah->device  = pd->device;
@@ -502,12 +505,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.
+ * @sleepable: In a sleepable context.
  *
  * 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,
+			     bool sleepable)
 {
 	const struct ib_gid_attr *old_sgid_attr;
 	struct ib_ah *ah;
@@ -517,7 +522,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, sleepable, NULL);
 
 	rdma_unfill_sgid_attr(ah_attr, old_sgid_attr);
 	return ah;
@@ -557,7 +562,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, true, udata);
 
 out:
 	rdma_unfill_sgid_attr(ah_attr, old_sgid_attr);
@@ -869,7 +874,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, true);
 
 	rdma_destroy_ah_attr(&ah_attr);
 	return ah;
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 54fdd4cf5288..682525cbb71d 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -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,
+				bool sleepable,
 				struct ib_udata *udata)
 {
 	struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
index aa33e7b82c84..5ae8d1c27a4d 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
@@ -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,
+				bool sleepable,
 				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);
diff --git a/drivers/infiniband/hw/hfi1/mad.c b/drivers/infiniband/hw/hfi1/mad.c
index 88a0cf930136..d9884e2c49c0 100644
--- a/drivers/infiniband/hw/hfi1/mad.c
+++ b/drivers/infiniband/hw/hfi1/mad.c
@@ -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, false);
 	rcu_read_unlock();
 	return ah;
 }
diff --git a/drivers/infiniband/hw/hns/hns_roce_ah.c b/drivers/infiniband/hw/hns/hns_roce_ah.c
index 9990dc9eb96a..fe9e8106e098 100644
--- a/drivers/infiniband/hw/hns/hns_roce_ah.c
+++ b/drivers/infiniband/hw/hns/hns_roce_ah.c
@@ -41,6 +41,7 @@ 
 
 struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd,
 				 struct rdma_ah_attr *ah_attr,
+				 bool sleepable,
 				 struct ib_udata *udata)
 {
 	struct hns_roce_dev *hr_dev = to_hr_dev(ibpd->device);
diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h
index 779dd4c409cb..ec8285073c9c 100644
--- a/drivers/infiniband/hw/hns/hns_roce_device.h
+++ b/drivers/infiniband/hw/hns/hns_roce_device.h
@@ -1054,6 +1054,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,
+				 bool sleepable,
 				 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);
diff --git a/drivers/infiniband/hw/mlx4/ah.c b/drivers/infiniband/hw/mlx4/ah.c
index e9e3a6f390db..e54cdcf672cd 100644
--- a/drivers/infiniband/hw/mlx4/ah.c
+++ b/drivers/infiniband/hw/mlx4/ah.c
@@ -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)
+				bool sleepable, 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, false, NULL);
 	if (IS_ERR(ah))
 		return ah;
 
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c
index 8942f5f7f04d..90b420e40b0b 100644
--- a/drivers/infiniband/hw/mlx4/mad.c
+++ b/drivers/infiniband/hw/mlx4/mad.c
@@ -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, false);
 	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, false);
 	if (IS_ERR(ah))
 		return -ENOMEM;
 
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index 5cb52424912e..0cf3df96adbe 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -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);
+				bool sleepable, 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,
diff --git a/drivers/infiniband/hw/mlx5/ah.c b/drivers/infiniband/hw/mlx5/ah.c
index ffd03bf1a71e..5d4f8d9a609b 100644
--- a/drivers/infiniband/hw/mlx5/ah.c
+++ b/drivers/infiniband/hw/mlx5/ah.c
@@ -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)
+				bool sleepable, struct ib_udata *udata)
 
 {
 	struct mlx5_ib_ah *ah;
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index 24cb2f793210..3b01049cae60 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -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);
+				bool sleepable, 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,
diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c
index 2e5dc0a67cfc..e483095e04b9 100644
--- a/drivers/infiniband/hw/mthca/mthca_mad.c
+++ b/drivers/infiniband/hw/mthca/mthca_mad.c
@@ -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, false);
 	if (IS_ERR(new_ah))
 		return;
 
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 691c6f048938..6ab7f5fc2234 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -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,
+				     bool sleepable,
 				     struct ib_udata *udata)
 
 {
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
index 58188fe5aed2..7491eb623f07 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
@@ -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)
+			       bool sleepable, struct ib_udata *udata)
 {
 	u32 *ahid_addr;
 	int status;
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_ah.h b/drivers/infiniband/hw/ocrdma/ocrdma_ah.h
index c0c32c9b80ae..0a961fda2db0 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_ah.h
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_ah.h
@@ -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);
+			       bool sleepable, 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);
 
diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c
index 82ee4b4a7084..7cf77491432d 100644
--- a/drivers/infiniband/hw/qedr/verbs.c
+++ b/drivers/infiniband/hw/qedr/verbs.c
@@ -2626,7 +2626,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)
+			     bool sleepable, struct ib_udata *udata)
 {
 	struct qedr_ah *ah;
 
diff --git a/drivers/infiniband/hw/qedr/verbs.h b/drivers/infiniband/hw/qedr/verbs.h
index 0b7d0124b16c..dac88eb3a249 100644
--- a/drivers/infiniband/hw/qedr/verbs.h
+++ b/drivers/infiniband/hw/qedr/verbs.h
@@ -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);
+			     bool sleepable, struct ib_udata *udata);
 int qedr_destroy_ah(struct ib_ah *ibah);
 
 int qedr_dereg_mr(struct ib_mr *);
diff --git a/drivers/infiniband/hw/qib/qib_verbs.c b/drivers/infiniband/hw/qib/qib_verbs.c
index 8914abdd7584..09744afa0411 100644
--- a/drivers/infiniband/hw/qib/qib_verbs.c
+++ b/drivers/infiniband/hw/qib/qib_verbs.c
@@ -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, false);
 	rcu_read_unlock();
 	return ah;
 }
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
index 0b91ff36768a..a716a6d83594 100644
--- a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
+++ b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
@@ -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,
+				 bool sleepable,
 				 struct ib_udata *udata)
 
 {
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_verbs.h b/drivers/infiniband/hw/usnic/usnic_ib_verbs.h
index 2a2c9beb715f..757816a0fcec 100644
--- a/drivers/infiniband/hw/usnic/usnic_ib_verbs.h
+++ b/drivers/infiniband/hw/usnic/usnic_ib_verbs.h
@@ -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,
+				 bool sleepable,
 				 struct ib_udata *udata);
 
 int usnic_ib_destroy_ah(struct ib_ah *ah);
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
index b65d10b0a875..c97bfc5f5ec7 100644
--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
@@ -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
+ * @sleepable: in a sleepable context
  *
  * @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)
+			       bool sleepable, struct ib_udata *udata)
 {
 	struct pvrdma_dev *dev = to_vdev(pd->device);
 	struct pvrdma_ah *ah;
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h
index b2e3ab50cb08..92fec87dfc4d 100644
--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h
@@ -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);
+			       bool sleepable, struct ib_udata *udata);
 int pvrdma_destroy_ah(struct ib_ah *ah);
 
 struct ib_srq *pvrdma_create_srq(struct ib_pd *pd,
diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
index 30817c79ba96..1d0e2f8f4fa1 100644
--- a/drivers/infiniband/sw/rxe/rxe_verbs.c
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
@@ -239,6 +239,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,
+				   bool sleepable,
 				   struct ib_udata *udata)
 
 {
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 9006a13af1de..0f5475b97db1 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -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, true);
 	if (IS_ERR(vah)) {
 		kfree(ah);
 		ah = (struct ipoib_ah *)vah;
diff --git a/drivers/infiniband/ulp/opa_vnic/opa_vnic_vema.c b/drivers/infiniband/ulp/opa_vnic/opa_vnic_vema.c
index d119d9afa845..fe0bab160c42 100644
--- a/drivers/infiniband/ulp/opa_vnic/opa_vnic_vema.c
+++ b/drivers/infiniband/ulp/opa_vnic/opa_vnic_vema.c
@@ -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, false);
 	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__,
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 85021451eee0..499d96302262 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -2374,6 +2374,7 @@  struct ib_device {
 	int                        (*dealloc_pd)(struct ib_pd *pd);
 	struct ib_ah *             (*create_ah)(struct ib_pd *pd,
 						struct rdma_ah_attr *ah_attr,
+						bool sleepable,
 						struct ib_udata *udata);
 	int                        (*modify_ah)(struct ib_ah *ah,
 						struct rdma_ah_attr *ah_attr);
@@ -3180,11 +3181,13 @@  void ib_dealloc_pd(struct ib_pd *pd);
  * 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.
+ * @sleepable: In a sleepable context.
  *
  * 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,
+			     bool sleepable);
 
 /**
  * rdma_create_user_ah - Creates an address handle for the given address vector.