Merge branch 'linus/master' into rdma.git for-next
authorJason Gunthorpe <jgg@mellanox.com>
Thu, 16 Aug 2018 20:13:03 +0000 (14:13 -0600)
committerJason Gunthorpe <jgg@mellanox.com>
Thu, 16 Aug 2018 20:21:29 +0000 (14:21 -0600)
rdma.git merge resolution for the 4.19 merge window

Conflicts:
 drivers/infiniband/core/rdma_core.c
   - Use the rdma code and revise with the new spelling for
     atomic_fetch_add_unless
 drivers/nvme/host/rdma.c
   - Replace max_sge with max_send_sge in new blk code
 drivers/nvme/target/rdma.c
   - Use the blk code and revise to use NULL for ib_post_recv when
     appropriate
   - Replace max_sge with max_recv_sge in new blk code
 net/rds/ib_send.c
   - Use the net code and revise to use NULL for ib_post_recv when
     appropriate

Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
23 files changed:
1  2 
.mailmap
MAINTAINERS
drivers/infiniband/core/rdma_core.c
drivers/infiniband/hw/hfi1/pcie.c
drivers/infiniband/hw/hfi1/vnic_main.c
drivers/infiniband/hw/hns/hns_roce_hw_v1.c
drivers/infiniband/ulp/iser/iser_memory.c
drivers/infiniband/ulp/srpt/ib_srpt.c
drivers/net/ethernet/mellanox/mlx5/core/cmd.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
drivers/nvme/host/rdma.c
drivers/nvme/target/rdma.c
include/linux/mlx5/driver.h
include/linux/mlx5/fs.h
include/linux/mlx5/mlx5_ifc.h
net/rds/ib.c
net/rds/ib_frmr.c
net/rds/ib_recv.c
net/rds/ib_send.c
net/smc/smc_core.c
net/smc/smc_ib.c
net/smc/smc_tx.c
net/smc/smc_wr.c

diff --cc .mailmap
Simple merge
diff --cc MAINTAINERS
Simple merge
index 12e7c6c102c136a8bf465845c3648f9d4e7be1f5,475910ffbcb6800f2e729f012b795483cbcc5c15..6eb64c6f08028b6c4a92407435bb2339128fe48b
@@@ -77,201 -120,19 +77,201 @@@ static int uverbs_try_lock_object(struc
         * concurrently, setting the counter to zero is enough for releasing
         * this lock.
         */
 -      if (!exclusive)
 +      switch (mode) {
 +      case UVERBS_LOOKUP_READ:
-               return __atomic_add_unless(&uobj->usecnt, 1, -1) == -1 ?
+               return atomic_fetch_add_unless(&uobj->usecnt, 1, -1) == -1 ?
                        -EBUSY : 0;
 +      case UVERBS_LOOKUP_WRITE:
 +              /* lock is exclusive */
 +              return atomic_cmpxchg(&uobj->usecnt, 0, -1) == 0 ? 0 : -EBUSY;
 +      case UVERBS_LOOKUP_DESTROY:
 +              return 0;
 +      }
 +      return 0;
 +}
 +
 +static void assert_uverbs_usecnt(struct ib_uobject *uobj,
 +                               enum rdma_lookup_mode mode)
 +{
 +#ifdef CONFIG_LOCKDEP
 +      switch (mode) {
 +      case UVERBS_LOOKUP_READ:
 +              WARN_ON(atomic_read(&uobj->usecnt) <= 0);
 +              break;
 +      case UVERBS_LOOKUP_WRITE:
 +              WARN_ON(atomic_read(&uobj->usecnt) != -1);
 +              break;
 +      case UVERBS_LOOKUP_DESTROY:
 +              break;
 +      }
 +#endif
 +}
 +
 +/*
 + * This must be called with the hw_destroy_rwsem locked for read or write,
 + * also the uobject itself must be locked for write.
 + *
 + * Upon return the HW object is guaranteed to be destroyed.
 + *
 + * For RDMA_REMOVE_ABORT, the hw_destroy_rwsem is not required to be held,
 + * however the type's allocat_commit function cannot have been called and the
 + * uobject cannot be on the uobjects_lists
 + *
 + * For RDMA_REMOVE_DESTROY the caller shold be holding a kref (eg via
 + * rdma_lookup_get_uobject) and the object is left in a state where the caller
 + * needs to call rdma_lookup_put_uobject.
 + *
 + * For all other destroy modes this function internally unlocks the uobject
 + * and consumes the kref on the uobj.
 + */
 +static int uverbs_destroy_uobject(struct ib_uobject *uobj,
 +                                enum rdma_remove_reason reason)
 +{
 +      struct ib_uverbs_file *ufile = uobj->ufile;
 +      unsigned long flags;
 +      int ret;
 +
 +      lockdep_assert_held(&ufile->hw_destroy_rwsem);
 +      assert_uverbs_usecnt(uobj, UVERBS_LOOKUP_WRITE);
 +
 +      if (uobj->object) {
 +              ret = uobj->uapi_object->type_class->destroy_hw(uobj, reason);
 +              if (ret) {
 +                      if (ib_is_destroy_retryable(ret, reason, uobj))
 +                              return ret;
 +
 +                      /* Nothing to be done, dangle the memory and move on */
 +                      WARN(true,
 +                           "ib_uverbs: failed to remove uobject id %d, driver err=%d",
 +                           uobj->id, ret);
 +              }
 +
 +              uobj->object = NULL;
 +      }
  
 -      /* lock is either WRITE or DESTROY - should be exclusive */
 -      return atomic_cmpxchg(&uobj->usecnt, 0, -1) == 0 ? 0 : -EBUSY;
 +      if (reason == RDMA_REMOVE_ABORT) {
 +              WARN_ON(!list_empty(&uobj->list));
 +              WARN_ON(!uobj->context);
 +              uobj->uapi_object->type_class->alloc_abort(uobj);
 +      }
 +
 +      uobj->context = NULL;
 +
 +      /*
 +       * For DESTROY the usecnt is held write locked, the caller is expected
 +       * to put it unlock and put the object when done with it. Only DESTROY
 +       * can remove the IDR handle.
 +       */
 +      if (reason != RDMA_REMOVE_DESTROY)
 +              atomic_set(&uobj->usecnt, 0);
 +      else
 +              uobj->uapi_object->type_class->remove_handle(uobj);
 +
 +      if (!list_empty(&uobj->list)) {
 +              spin_lock_irqsave(&ufile->uobjects_lock, flags);
 +              list_del_init(&uobj->list);
 +              spin_unlock_irqrestore(&ufile->uobjects_lock, flags);
 +
 +              /*
 +               * Pairs with the get in rdma_alloc_commit_uobject(), could
 +               * destroy uobj.
 +               */
 +              uverbs_uobject_put(uobj);
 +      }
 +
 +      /*
 +       * When aborting the stack kref remains owned by the core code, and is
 +       * not transferred into the type. Pairs with the get in alloc_uobj
 +       */
 +      if (reason == RDMA_REMOVE_ABORT)
 +              uverbs_uobject_put(uobj);
 +
 +      return 0;
  }
  
 -static struct ib_uobject *alloc_uobj(struct ib_ucontext *context,
 -                                   const struct uverbs_obj_type *type)
 +/*
 + * This calls uverbs_destroy_uobject() using the RDMA_REMOVE_DESTROY
 + * sequence. It should only be used from command callbacks. On success the
 + * caller must pair this with rdma_lookup_put_uobject(LOOKUP_WRITE). This
 + * version requires the caller to have already obtained an
 + * LOOKUP_DESTROY uobject kref.
 + */
 +int uobj_destroy(struct ib_uobject *uobj)
  {
 -      struct ib_uobject *uobj = kzalloc(type->obj_size, GFP_KERNEL);
 +      struct ib_uverbs_file *ufile = uobj->ufile;
 +      int ret;
 +
 +      down_read(&ufile->hw_destroy_rwsem);
 +
 +      ret = uverbs_try_lock_object(uobj, UVERBS_LOOKUP_WRITE);
 +      if (ret)
 +              goto out_unlock;
 +
 +      ret = uverbs_destroy_uobject(uobj, RDMA_REMOVE_DESTROY);
 +      if (ret) {
 +              atomic_set(&uobj->usecnt, 0);
 +              goto out_unlock;
 +      }
  
 +out_unlock:
 +      up_read(&ufile->hw_destroy_rwsem);
 +      return ret;
 +}
 +
 +/*
 + * uobj_get_destroy destroys the HW object and returns a handle to the uobj
 + * with a NULL object pointer. The caller must pair this with
 + * uverbs_put_destroy.
 + */
 +struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj,
 +                                    u32 id, struct ib_uverbs_file *ufile)
 +{
 +      struct ib_uobject *uobj;
 +      int ret;
 +
 +      uobj = rdma_lookup_get_uobject(obj, ufile, id, UVERBS_LOOKUP_DESTROY);
 +      if (IS_ERR(uobj))
 +              return uobj;
 +
 +      ret = uobj_destroy(uobj);
 +      if (ret) {
 +              rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_DESTROY);
 +              return ERR_PTR(ret);
 +      }
 +
 +      return uobj;
 +}
 +
 +/*
 + * Does both uobj_get_destroy() and uobj_put_destroy().  Returns success_res
 + * on success (negative errno on failure). For use by callers that do not need
 + * the uobj.
 + */
 +int __uobj_perform_destroy(const struct uverbs_api_object *obj, u32 id,
 +                         struct ib_uverbs_file *ufile, int success_res)
 +{
 +      struct ib_uobject *uobj;
 +
 +      uobj = __uobj_get_destroy(obj, id, ufile);
 +      if (IS_ERR(uobj))
 +              return PTR_ERR(uobj);
 +
 +      rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_WRITE);
 +      return success_res;
 +}
 +
 +/* alloc_uobj must be undone by uverbs_destroy_uobject() */
 +static struct ib_uobject *alloc_uobj(struct ib_uverbs_file *ufile,
 +                                   const struct uverbs_api_object *obj)
 +{
 +      struct ib_uobject *uobj;
 +      struct ib_ucontext *ucontext;
 +
 +      ucontext = ib_uverbs_get_ucontext(ufile);
 +      if (IS_ERR(ucontext))
 +              return ERR_CAST(ucontext);
 +
 +      uobj = kzalloc(obj->type_attrs->obj_size, GFP_KERNEL);
        if (!uobj)
                return ERR_PTR(-ENOMEM);
        /*
Simple merge
Simple merge
index 72e8e8e7d2d7cd515fc0113b5a8b48057e9cbfa5,0805fa6215eefbbdb15c22cab0bc0e5e101cee17..dc042017c293adc77e0517efb80fd13157b8ac23
@@@ -374,6 -377,8 +377,8 @@@ nvme_rdma_find_get_device(struct rdma_c
                goto out_free_pd;
        }
  
 -                                      ndev->dev->attrs.max_sge - 1);
+       ndev->num_inline_segments = min(NVME_RDMA_MAX_INLINE_SEGMENTS,
++                                      ndev->dev->attrs.max_send_sge - 1);
        list_add(&ndev->entry, &device_list);
  out_unlock:
        mutex_unlock(&device_list_mutex);
index 1a642e214a4ce2272dcef5d05b341cfc8ccb8911,e7f43d1e17797f60f39fc609b5565fcd4799027a..3533e918ea376bbb221489f086047521443c17e8
@@@ -382,13 -435,22 +435,21 @@@ static void nvmet_rdma_free_rsps(struc
  static int nvmet_rdma_post_recv(struct nvmet_rdma_device *ndev,
                struct nvmet_rdma_cmd *cmd)
  {
 -      struct ib_recv_wr *bad_wr;
+       int ret;
        ib_dma_sync_single_for_device(ndev->device,
                cmd->sge[0].addr, cmd->sge[0].length,
                DMA_FROM_DEVICE);
  
        if (ndev->srq)
-               return ib_post_srq_recv(ndev->srq, &cmd->wr, NULL);
-       return ib_post_recv(cmd->queue->cm_id->qp, &cmd->wr, NULL);
 -              ret = ib_post_srq_recv(ndev->srq, &cmd->wr, &bad_wr);
++              ret = ib_post_srq_recv(ndev->srq, &cmd->wr, NULL);
+       else
 -              ret = ib_post_recv(cmd->queue->cm_id->qp, &cmd->wr, &bad_wr);
++              ret = ib_post_recv(cmd->queue->cm_id->qp, &cmd->wr, NULL);
+       if (unlikely(ret))
+               pr_err("post_recv cmd failed\n");
+       return ret;
  }
  
  static void nvmet_rdma_process_wr_wait_list(struct nvmet_rdma_queue *queue)
@@@ -491,7 -553,7 +552,7 @@@ static void nvmet_rdma_queue_response(s
                rsp->send_sge.addr, rsp->send_sge.length,
                DMA_TO_DEVICE);
  
-       if (ib_post_send(cm_id->qp, first_wr, NULL)) {
 -      if (unlikely(ib_post_send(cm_id->qp, first_wr, &bad_wr))) {
++      if (unlikely(ib_post_send(cm_id->qp, first_wr, NULL))) {
                pr_err("sending cmd response failed\n");
                nvmet_rdma_release_rsp(rsp);
        }
@@@ -805,6 -890,18 +889,18 @@@ nvmet_rdma_find_get_device(struct rdma_
        if (!ndev)
                goto out_err;
  
 -                              cm_id->device->attrs.max_sge) - 1;
+       inline_page_count = num_pages(port->inline_data_size);
+       inline_sge_count = max(cm_id->device->attrs.max_sge_rd,
++                              cm_id->device->attrs.max_recv_sge) - 1;
+       if (inline_page_count > inline_sge_count) {
+               pr_warn("inline_data_size %d cannot be supported by device %s. Reducing to %lu.\n",
+                       port->inline_data_size, cm_id->device->name,
+                       inline_sge_count * PAGE_SIZE);
+               port->inline_data_size = inline_sge_count * PAGE_SIZE;
+               inline_page_count = inline_sge_count;
+       }
+       ndev->inline_data_size = port->inline_data_size;
+       ndev->inline_page_count = inline_page_count;
        ndev->device = cm_id->device;
        kref_init(&ndev->ref);
  
Simple merge
Simple merge
Simple merge
diff --cc net/rds/ib.c
Simple merge
Simple merge
index 4c5a937304b274b8258ad25e24336c167ff6c08d,d300186b8dc020ac9da1036b8179e542bb18b14d..2f16146e4ec94e580b26bf6e4e12395a6d882a4b
@@@ -416,10 -415,10 +414,10 @@@ void rds_ib_recv_refill(struct rds_conn
                                &recv->r_frag->f_sg));
  
                /* XXX when can this fail? */
 -              ret = ib_post_recv(ic->i_cm_id->qp, &recv->r_wr, &failed_wr);
 +              ret = ib_post_recv(ic->i_cm_id->qp, &recv->r_wr, NULL);
                if (ret) {
                        rds_ib_conn_error(conn, "recv post on "
-                              "%pI4 returned %d, disconnecting and "
+                              "%pI6c returned %d, disconnecting and "
                               "reconnecting\n", &conn->c_faddr,
                               ret);
                        break;
index 8ac80c1b051e1a8137d0f1e8d0daa0251cc66a51,c8dd3125d398776318a6391de3c8ceb0b62602f4..2dcb555e6350d12197584ba898e6d4dd464d9c61
@@@ -758,8 -758,7 +758,7 @@@ int rds_ib_xmit_atomic(struct rds_conne
  {
        struct rds_ib_connection *ic = conn->c_transport_data;
        struct rds_ib_send_work *send = NULL;
 -      struct ib_send_wr *failed_wr;
 +      const struct ib_send_wr *failed_wr;
-       struct rds_ib_device *rds_ibdev;
        u32 pos;
        u32 work_alloc;
        int ret;
Simple merge
Simple merge
Simple merge
index de1a438cf9773f85413a2ce53c8581cee5078a31,f856b8402b3fe527c0dbf80225d501bcab9336ce..3c458d27985574efc929c21565fd0aaae58f2c20
@@@ -246,14 -239,11 +238,10 @@@ int smc_wr_tx_send(struct smc_link *lin
        ib_req_notify_cq(link->smcibdev->roce_cq_send,
                         IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS);
        pend = container_of(priv, struct smc_wr_tx_pend, priv);
 -      rc = ib_post_send(link->roce_qp, &link->wr_tx_ibs[pend->idx],
 -                        &failed_wr);
 +      rc = ib_post_send(link->roce_qp, &link->wr_tx_ibs[pend->idx], NULL);
        if (rc) {
-               struct smc_link_group *lgr =
-                       container_of(link, struct smc_link_group,
-                                    lnk[SMC_SINGLE_LINK]);
                smc_wr_tx_put_slot(link, priv);
-               smc_lgr_terminate(lgr);
+               smc_lgr_terminate(smc_get_lgr(link));
        }
        return rc;
  }