Re: [PATCH v1 10/10] IB/iser: Support the remote invalidation exception

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Nov 24, 2015 at 6:23 PM, Sagi Grimberg <sagig@xxxxxxxxxxxx> wrote:
>
> From: Jenny Derzhavetz <jennyf@xxxxxxxxxxxx>
>
> Declare that we support remote invalidation in case we are:
> 1. using Fastreg method
> 2. always registering memory.

decide if you want or don't want to use periods @ the end of these
cases, but be consistent... I vote not to use periods

>
> Detect the invalidated rkey from the work completion info so we
> won't invalidate it locally. The spec madates that we must not rely
> on the taget remote invalidate our rkey so we must check it upon
> a receive (scsi response) completion.
>

s/madates/mandates/ and run spell check over the change-logs of the
whole series please before posting v2



>
> Signed-off-by: Jenny Derzhavetz <jennyf@xxxxxxxxxxxx>
> Signed-off-by: Sagi Grimberg <sagig@xxxxxxxxxxxx>
> ---
>  drivers/infiniband/ulp/iser/iscsi_iser.h     |  5 ++-
>  drivers/infiniband/ulp/iser/iser_initiator.c | 59 +++++++++++++++++++++++++++-
>  drivers/infiniband/ulp/iser/iser_memory.c    |  4 +-
>  drivers/infiniband/ulp/iser/iser_verbs.c     | 21 +++++++---
>  4 files changed, 80 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
> index c79fdba6f969..e399d9a49df2 100644
> --- a/drivers/infiniband/ulp/iser/iscsi_iser.h
> +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
> @@ -358,6 +358,7 @@ struct iser_reg_ops {
>   *                 cpus and device max completion vectors
>   * @comps:         Dinamically allocated array of completion handlers
>   * @reg_ops:       Registration ops
> + * @remote_inv_sup: Remote invalidate is supported on this device
>   */
>  struct iser_device {
>         struct ib_device             *ib_device;
> @@ -370,6 +371,7 @@ struct iser_device {
>         int                          comps_used;
>         struct iser_comp             *comps;
>         struct iser_reg_ops          *reg_ops;
> +       bool                         remote_inv_sup;
>  };
>
>  #define ISER_CHECK_GUARD       0xc0
> @@ -519,6 +521,7 @@ struct iser_conn {
>         u32                          num_rx_descs;
>         unsigned short               scsi_sg_tablesize;
>         unsigned int                 scsi_max_sectors;
> +       bool                         snd_w_inv;
>  };
>
>  /**
> @@ -602,7 +605,7 @@ int iser_conn_terminate(struct iser_conn *iser_conn);
>  void iser_release_work(struct work_struct *work);
>
>  void iser_rcv_completion(struct iser_rx_desc *desc,
> -                        unsigned long dto_xfer_len,
> +                        struct ib_wc *wc,
>                          struct ib_conn *ib_conn);
>
>  void iser_snd_completion(struct iser_tx_desc *desc,
> diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
> index 6a968e350c14..cd12f89b3365 100644
> --- a/drivers/infiniband/ulp/iser/iser_initiator.c
> +++ b/drivers/infiniband/ulp/iser/iser_initiator.c
> @@ -563,11 +563,61 @@ send_control_error:
>         return err;
>  }
>
> +static inline void
> +iser_inv_desc(struct iser_fr_desc *desc, u32 rkey)
> +{
> +       if (likely(rkey == desc->rsc.mr->rkey))
> +               desc->rsc.mr_valid = 0;
> +       else if (likely(rkey == desc->pi_ctx->sig_mr->rkey))
> +               desc->pi_ctx->sig_mr_valid = 0;
> +}
> +
> +static int
> +iser_check_remote_inv(struct iser_conn *iser_conn,
> +                     struct ib_wc *wc,
> +                     struct iscsi_hdr *hdr)
> +{
> +       if (wc->wc_flags & IB_WC_WITH_INVALIDATE) {
> +               struct iscsi_task *task;
> +               u32 rkey = wc->ex.invalidate_rkey;
> +
> +               iser_dbg("conn %p: remote invalidation for rkey %#x\n",
> +                        iser_conn, rkey);
> +
> +               if (unlikely(!iser_conn->snd_w_inv)) {
> +                       iser_err("conn %p: unexepected remote invalidation, "
> +                                "terminating connection\n", iser_conn);
> +                       return -EPROTO;
> +               }
> +
> +               task = iscsi_itt_to_ctask(iser_conn->iscsi_conn, hdr->itt);
> +               if (likely(task)) {
> +                       struct iscsi_iser_task *iser_task = task->dd_data;
> +                       struct iser_fr_desc *desc;
> +
> +                       if (iser_task->dir[ISER_DIR_IN]) {
> +                               desc = iser_task->rdma_reg[ISER_DIR_IN].mem_h;
> +                               iser_inv_desc(desc, rkey);
> +                       }
> +
> +                       if (iser_task->dir[ISER_DIR_OUT]) {
> +                               desc = iser_task->rdma_reg[ISER_DIR_OUT].mem_h;
> +                               iser_inv_desc(desc, rkey);
> +                       }
> +               } else {
> +                       iser_err("failed to get task for itt=%d\n", hdr->itt);
> +                       return -EINVAL;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
>  /**
>   * iser_rcv_dto_completion - recv DTO completion
>   */
>  void iser_rcv_completion(struct iser_rx_desc *rx_desc,
> -                        unsigned long rx_xfer_len,
> +                        struct ib_wc *wc,
>                          struct ib_conn *ib_conn)
>  {
>         struct iser_conn *iser_conn = container_of(ib_conn, struct iser_conn,
> @@ -575,6 +625,7 @@ void iser_rcv_completion(struct iser_rx_desc *rx_desc,
>         struct iscsi_hdr *hdr;
>         u64 rx_dma;
>         int rx_buflen, outstanding, count, err;
> +       unsigned long rx_xfer_len = wc->byte_len;
>
>         /* differentiate between login to all other PDUs */
>         if ((char *)rx_desc == iser_conn->login_resp_buf) {
> @@ -593,6 +644,12 @@ void iser_rcv_completion(struct iser_rx_desc *rx_desc,
>         iser_dbg("op 0x%x itt 0x%x dlen %d\n", hdr->opcode,
>                         hdr->itt, (int)(rx_xfer_len - ISER_HEADERS_LEN));
>
> +       if (iser_check_remote_inv(iser_conn, wc, hdr)) {
> +               iscsi_conn_failure(iser_conn->iscsi_conn,
> +                                  ISCSI_ERR_CONN_FAILED);
> +               return;
> +       }
> +
>         iscsi_iser_recv(iser_conn->iscsi_conn, hdr, rx_desc->data,
>                         rx_xfer_len - ISER_HEADERS_LEN);
>
> diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
> index c008fc262aee..8a57d4eadda6 100644
> --- a/drivers/infiniband/ulp/iser/iser_memory.c
> +++ b/drivers/infiniband/ulp/iser/iser_memory.c
> @@ -76,10 +76,10 @@ int iser_assign_reg_ops(struct iser_device *device)
>             device->ib_device->map_phys_fmr && device->ib_device->unmap_fmr) {
>                 iser_info("FMR supported, using FMR for registration\n");
>                 device->reg_ops = &fmr_ops;
> -       } else
> -       if (dev_attr->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) {
> +       } else if (dev_attr->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) {
>                 iser_info("FastReg supported, using FastReg for registration\n");
>                 device->reg_ops = &fastreg_ops;
> +               device->remote_inv_sup = iser_always_reg;
>         } else {
>                 iser_err("IB device does not support FMRs nor FastRegs, can't register memory\n");
>                 return -1;
> diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
> index 9ba5214f0e02..8d25c503d32b 100644
> --- a/drivers/infiniband/ulp/iser/iser_verbs.c
> +++ b/drivers/infiniband/ulp/iser/iser_verbs.c
> @@ -847,7 +847,9 @@ static void iser_route_handler(struct rdma_cm_id *cma_id)
>         conn_param.rnr_retry_count     = 6;
>
>         memset(&req_hdr, 0, sizeof(req_hdr));
> -       req_hdr.flags = (ISER_ZBVA_NOT_SUP | ISER_SEND_W_INV_NOT_SUP);
> +       req_hdr.flags = ISER_ZBVA_NOT_SUP;
> +       if (!device->remote_inv_sup)
> +               req_hdr.flags |= ISER_SEND_W_INV_NOT_SUP;
>         conn_param.private_data = (void *)&req_hdr;
>         conn_param.private_data_len = sizeof(struct iser_cm_hdr);
>
> @@ -862,7 +864,8 @@ failure:
>         iser_connect_error(cma_id);
>  }
>
> -static void iser_connected_handler(struct rdma_cm_id *cma_id)
> +static void iser_connected_handler(struct rdma_cm_id *cma_id,
> +                                  const void *private_data)
>  {
>         struct iser_conn *iser_conn;
>         struct ib_qp_attr attr;
> @@ -876,6 +879,15 @@ static void iser_connected_handler(struct rdma_cm_id *cma_id)
>         (void)ib_query_qp(cma_id->qp, &attr, ~0, &init_attr);
>         iser_info("remote qpn:%x my qpn:%x\n", attr.dest_qp_num, cma_id->qp->qp_num);
>
> +       if (private_data) {
> +               u8 flags = *(u8 *)private_data;
> +
> +               iser_conn->snd_w_inv = !(flags & ISER_SEND_W_INV_NOT_SUP);
> +       }
> +
> +       iser_info("conn %p: negotiated %s invalidation\n",
> +                 iser_conn, iser_conn->snd_w_inv ? "remote" : "local");
> +
>         iser_conn->state = ISER_CONN_UP;
>         complete(&iser_conn->up_completion);
>  }
> @@ -927,7 +939,7 @@ static int iser_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *eve
>                 iser_route_handler(cma_id);
>                 break;
>         case RDMA_CM_EVENT_ESTABLISHED:
> -               iser_connected_handler(cma_id);
> +               iser_connected_handler(cma_id, event->param.conn.private_data);
>                 break;
>         case RDMA_CM_EVENT_ADDR_ERROR:
>         case RDMA_CM_EVENT_ROUTE_ERROR:
> @@ -1205,8 +1217,7 @@ static void iser_handle_wc(struct ib_wc *wc)
>         if (likely(wc->status == IB_WC_SUCCESS)) {
>                 if (wc->opcode == IB_WC_RECV) {
>                         rx_desc = (struct iser_rx_desc *)(uintptr_t)wc->wr_id;
> -                       iser_rcv_completion(rx_desc, wc->byte_len,
> -                                           ib_conn);
> +                       iser_rcv_completion(rx_desc, wc, ib_conn);
>                 } else
>                 if (wc->opcode == IB_WC_SEND) {
>                         tx_desc = (struct iser_tx_desc *)(uintptr_t)wc->wr_id;
> --
> 1.8.4.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux