Added iSER backport for RHEL7.6
authorVladimir Sokolovsky <vlad@mellanox.com>
Wed, 28 Aug 2019 18:45:51 +0000 (13:45 -0500)
committerVladimir Sokolovsky <vlad@mellanox.com>
Wed, 28 Aug 2019 18:45:51 +0000 (13:45 -0500)
Signed-off-by: Vladimir Sokolovsky <vlad@mellanox.com>
patches/0006-BACKPORT-iser.patch [new file with mode: 0644]

diff --git a/patches/0006-BACKPORT-iser.patch b/patches/0006-BACKPORT-iser.patch
new file mode 100644 (file)
index 0000000..f503414
--- /dev/null
@@ -0,0 +1,220 @@
+From: Vladimir Sokolovsky <vlad@mellanox.com>
+Subject: [PATCH] BACKPORT: iser
+
+Signed-off-by: Vladimir Sokolovsky <vlad@mellanox.com>
+---
+ drivers/infiniband/ulp/iser/iscsi_iser.c  | 39 ++++++++++++++++
+ drivers/infiniband/ulp/iser/iscsi_iser.h  | 10 +++++
+ drivers/infiniband/ulp/iser/iser_memory.c | 54 ++++++++++++++++++++++-
+ 3 files changed, 102 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
+index xxxxxxx..xxxxxxx 100644
+--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
++++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
+@@ -651,8 +651,10 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep,
+                                                  SHOST_DIX_GUARD_CRC);
+               }
++#ifdef HAVE_SCSI_HOST_VIRT_BOUNDARY_MASK
+               if (!(ib_dev->attrs.device_cap_flags & IB_DEVICE_SG_GAPS_REG))
+                       shost->virt_boundary_mask = ~MASK_4K;
++#endif
+               if (iscsi_host_add(shost, ib_dev->dev.parent)) {
+                       mutex_unlock(&iser_conn->state_mutex);
+@@ -960,21 +962,58 @@ static umode_t iser_attr_is_visible(int param_type, int param)
+       return 0;
+ }
++#ifndef HAVE_SCSI_HOST_VIRT_BOUNDARY_MASK
++static int iscsi_iser_slave_alloc(struct scsi_device *sdev)
++{
++      struct iscsi_session *session;
++      struct iser_conn *iser_conn;
++      struct ib_device *ib_dev;
++
++      mutex_lock(&unbind_iser_conn_mutex);
++
++      session = starget_to_session(scsi_target(sdev))->dd_data;
++      iser_conn = session->leadconn->dd_data;
++      if (!iser_conn) {
++              mutex_unlock(&unbind_iser_conn_mutex);
++              return -ENOTCONN;
++      }
++      ib_dev = iser_conn->ib_conn.device->ib_device;
++
++      if (!(ib_dev->attrs.device_cap_flags & IB_DEVICE_SG_GAPS_REG))
++              blk_queue_virt_boundary(sdev->request_queue, ~MASK_4K);
++
++      mutex_unlock(&unbind_iser_conn_mutex);
++
++      return 0;
++}
++#endif
++
+ static struct scsi_host_template iscsi_iser_sht = {
+       .module                 = THIS_MODULE,
+       .name                   = "iSCSI Initiator over iSER",
+       .queuecommand           = iscsi_queuecommand,
++#ifdef HAVE_SCSI_CHANGE_QUEUE_DEPTH
+       .change_queue_depth     = scsi_change_queue_depth,
++#else
++      .change_queue_depth     = iscsi_change_queue_depth,
++#endif
+       .sg_tablesize           = ISCSI_ISER_DEF_SG_TABLESIZE,
+       .cmd_per_lun            = ISER_DEF_CMD_PER_LUN,
++#ifdef HAVE_ISCSI_EH_CMD_TIMED_OUT
+       .eh_timed_out           = iscsi_eh_cmd_timed_out,
++#endif
+       .eh_abort_handler       = iscsi_eh_abort,
+       .eh_device_reset_handler= iscsi_eh_device_reset,
+       .eh_target_reset_handler = iscsi_eh_recover_target,
+       .target_alloc           = iscsi_target_alloc,
++#ifndef HAVE_SCSI_HOST_VIRT_BOUNDARY_MASK
++      .slave_alloc            = iscsi_iser_slave_alloc,
++#endif
+       .proc_name              = "iscsi_iser",
+       .this_id                = -1,
++#ifdef HAVE_SCSI_HOST_TEMPLATE_TRACK_QUEUE_DEPTH
+       .track_queue_depth      = 1,
++#endif
+ };
+ static struct iscsi_transport iscsi_iser_transport = {
+diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
+index xxxxxxx..xxxxxxx 100644
+--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
++++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
+@@ -367,6 +367,16 @@ struct iser_device {
+       bool                         remote_inv_sup;
+ };
++#ifndef ISER_CHECK_GUARD
++#define ISER_CHECK_GUARD      0xc0
++#endif
++#ifndef ISER_CHECK_REFTAG
++#define ISER_CHECK_REFTAG     0x0f
++#endif
++#ifndef ISER_CHECK_APPTAG
++#define ISER_CHECK_APPTAG     0x30
++#endif
++
+ /**
+  * struct iser_reg_resources - Fast registration recources
+  *
+diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
+index xxxxxxx..xxxxxxx 100644
+--- a/drivers/infiniband/ulp/iser/iser_memory.c
++++ b/drivers/infiniband/ulp/iser/iser_memory.c
+@@ -305,8 +305,13 @@ static void
+ iser_set_dif_domain(struct scsi_cmnd *sc, struct ib_sig_domain *domain)
+ {
+       domain->sig_type = IB_SIG_TYPE_T10_DIF;
++#ifdef HAVE_SCSI_CMND_PROT_FLAGS
+       domain->sig.dif.pi_interval = scsi_prot_interval(sc);
+       domain->sig.dif.ref_tag = t10_pi_ref_tag(sc->request);
++#else
++      domain->sig.dif.pi_interval = sc->device->sector_size;
++      domain->sig.dif.ref_tag = scsi_get_lba(sc) & 0xffffffff;
++#endif
+       /*
+        * At the moment we hard code those, but in the future
+        * we will take them from sc.
+@@ -314,9 +319,15 @@ iser_set_dif_domain(struct scsi_cmnd *sc, struct ib_sig_domain *domain)
+       domain->sig.dif.apptag_check_mask = 0xffff;
+       domain->sig.dif.app_escape = true;
+       domain->sig.dif.ref_escape = true;
++#ifdef HAVE_SCSI_CMND_PROT_FLAGS
+       if (sc->prot_flags & SCSI_PROT_REF_INCREMENT)
+               domain->sig.dif.ref_remap = true;
+-};
++#else
++      if (scsi_get_prot_type(sc) == SCSI_PROT_DIF_TYPE1 ||
++              scsi_get_prot_type(sc) == SCSI_PROT_DIF_TYPE2)
++              domain->sig.dif.ref_remap = true;
++#endif
++}
+ static int
+ iser_set_sig_attrs(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs)
+@@ -332,16 +343,26 @@ iser_set_sig_attrs(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs)
+       case SCSI_PROT_WRITE_STRIP:
+               sig_attrs->wire.sig_type = IB_SIG_TYPE_NONE;
+               iser_set_dif_domain(sc, &sig_attrs->mem);
++#ifdef HAVE_SCSI_CMND_PROT_FLAGS
+               sig_attrs->mem.sig.dif.bg_type = sc->prot_flags & SCSI_PROT_IP_CHECKSUM ?
+                                               IB_T10DIF_CSUM : IB_T10DIF_CRC;
++#else
++              sig_attrs->mem.sig.dif.bg_type = iser_pi_guard ? IB_T10DIF_CSUM :
++                                              IB_T10DIF_CRC;
++#endif
+               break;
+       case SCSI_PROT_READ_PASS:
+       case SCSI_PROT_WRITE_PASS:
+               iser_set_dif_domain(sc, &sig_attrs->wire);
+               sig_attrs->wire.sig.dif.bg_type = IB_T10DIF_CRC;
+               iser_set_dif_domain(sc, &sig_attrs->mem);
++#ifdef HAVE_SCSI_CMND_PROT_FLAGS
+               sig_attrs->mem.sig.dif.bg_type = sc->prot_flags & SCSI_PROT_IP_CHECKSUM ?
+                                               IB_T10DIF_CSUM : IB_T10DIF_CRC;
++#else
++              sig_attrs->mem.sig.dif.bg_type = iser_pi_guard ? IB_T10DIF_CSUM :
++                                              IB_T10DIF_CRC;
++#endif
+               break;
+       default:
+               iser_err("Unsupported PI operation %d\n",
+@@ -352,6 +373,7 @@ iser_set_sig_attrs(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs)
+       return 0;
+ }
++#ifdef HAVE_SCSI_CMND_PROT_FLAGS
+ static inline void
+ iser_set_prot_checks(struct scsi_cmnd *sc, u8 *mask)
+ {
+@@ -361,6 +383,30 @@ iser_set_prot_checks(struct scsi_cmnd *sc, u8 *mask)
+       if (sc->prot_flags & SCSI_PROT_GUARD_CHECK)
+               *mask |= IB_SIG_CHECK_GUARD;
+ }
++#else
++static int
++iser_set_prot_checks(struct scsi_cmnd *sc, u8 *mask)
++{
++      switch (scsi_get_prot_type(sc)) {
++      case SCSI_PROT_DIF_TYPE0:
++              *mask = 0x0;
++              break;
++      case SCSI_PROT_DIF_TYPE1:
++      case SCSI_PROT_DIF_TYPE2:
++              *mask = ISER_CHECK_GUARD | ISER_CHECK_REFTAG;
++              break;
++      case SCSI_PROT_DIF_TYPE3:
++              *mask = ISER_CHECK_GUARD;
++              break;
++      default:
++              iser_err("Unsupported protection type %d\n",
++                       scsi_get_prot_type(sc));
++              return -EINVAL;
++      }
++
++      return 0;
++}
++#endif
+ static inline void
+ iser_inv_rkey(struct ib_send_wr *inv_wr,
+@@ -395,7 +441,13 @@ iser_reg_sig_mr(struct iscsi_iser_task *iser_task,
+       if (ret)
+               goto err;
++#ifdef HAVE_SCSI_CMND_PROT_FLAGS
+       iser_set_prot_checks(iser_task->sc, &sig_attrs->check_mask);
++#else
++      ret = iser_set_prot_checks(iser_task->sc, &sig_attrs->check_mask);
++      if (ret)
++              goto err;
++#endif
+       if (rsc->mr_valid)
+               iser_inv_rkey(&tx_desc->inv_wr, mr, cqe, &wr->wr);