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 edb2cb7..cf5b3c4 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 be5ba5e..fb96d9d 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 bc0b3a1..4e2df23 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 611bacd..4b37bc3 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 aa33e7b..6675db4 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 88a0cf9..4228393 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 9990dc9..dae4c54 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 67609cc..b2c4682 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 e9e3a6f..6c0e6bc 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 8942f5f..b227f7c 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 5cb5242..7b827b1 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 ffd03bf..536c2c0 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 9b4e255..ebf7002 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 2e5dc0a..4a5916d 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 443521c..c8a7c37 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 58188fe..62c5022 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 c0c32c9..c407022 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 8056121..bb53c08 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 0b7d012..80ac864 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 611a6b5..276304f 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 0b91ff3..fa47714 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 2a2c9be..066f536 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 f4cb5cf..08ea4b9 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 b2e3ab5..d872e6a 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 084bb4b..43e4687 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 25271b4..70f8d08 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 8d15b1e..9c0ae9a 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 9006a13..1ecf210 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 d119d9a..2f4f638 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 0ec15d6..86ae878 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.