]> git.openfabrics.org - ~emulex/tmp/compat-rdma/.git/commitdiff
Added SRP backport for RHEL6.5/6
authorVladimir Sokolovsky <vlad@mellanox.com>
Wed, 7 Jan 2015 15:13:21 +0000 (17:13 +0200)
committerVladimir Sokolovsky <vlad@mellanox.com>
Wed, 7 Jan 2015 15:13:21 +0000 (17:13 +0200)
Signed-off-by: Vladimir Sokolovsky <vlad@mellanox.com>
patches/0023-BACKPORT-srp.patch [new file with mode: 0644]

diff --git a/patches/0023-BACKPORT-srp.patch b/patches/0023-BACKPORT-srp.patch
new file mode 100644 (file)
index 0000000..a69b38b
--- /dev/null
@@ -0,0 +1,263 @@
+From: Vladimir Sokolovsky <vlad@mellanox.com>
+Subject: [PATCH] BACKPORT: srp
+
+Signed-off-by: Vladimir Sokolovsky <vlad@mellanox.com>
+---
+ drivers/infiniband/ulp/srp/ib_srp.c |   86 ++++++++++++++++++++++++++++++++++-
+ drivers/scsi/scsi_transport_srp.c   |   25 ++++++++++
+ 2 files changed, 110 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
+index xxxxxxx..xxxxxxx xxxxxx
+--- a/drivers/infiniband/ulp/srp/ib_srp.c
++++ b/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -30,6 +30,9 @@
+  * SOFTWARE.
+  */
++#ifdef pr_fmt
++#undef pr_fmt
++#endif
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+ #include <linux/module.h>
+@@ -41,7 +44,11 @@
+ #include <linux/random.h>
+ #include <linux/jiffies.h>
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
+ #include <linux/atomic.h>
++#else
++#include <asm/atomic.h>
++#endif
+ #include <scsi/scsi.h>
+ #include <scsi/scsi_device.h>
+@@ -97,30 +104,58 @@ module_param(register_always, bool, 0444);
+ MODULE_PARM_DESC(register_always,
+                "Use memory registration even for contiguous memory regions");
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+ static struct kernel_param_ops srp_tmo_ops;
++#endif
+ static int srp_reconnect_delay = 10;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+ module_param_cb(reconnect_delay, &srp_tmo_ops, &srp_reconnect_delay,
+               S_IRUGO | S_IWUSR);
++#else
++module_param_named(reconnect_delay, srp_reconnect_delay, int,
++                 S_IRUGO | S_IWUSR);
++#endif
++
+ MODULE_PARM_DESC(reconnect_delay, "Time between successive reconnect attempts");
+ static int srp_fast_io_fail_tmo = 15;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+ module_param_cb(fast_io_fail_tmo, &srp_tmo_ops, &srp_fast_io_fail_tmo,
+               S_IRUGO | S_IWUSR);
++#else
++module_param_named(fast_io_fail_tmo, srp_fast_io_fail_tmo, int,
++                 S_IRUGO | S_IWUSR);
++#endif
++
+ MODULE_PARM_DESC(fast_io_fail_tmo,
+                "Number of seconds between the observation of a transport"
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+                " layer error and failing all I/O. \"off\" means that this"
++#else
++               " layer error and failing all I/O. (-1) means that this"
++#endif
+                " functionality is disabled.");
+ static int srp_dev_loss_tmo = 600;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+ module_param_cb(dev_loss_tmo, &srp_tmo_ops, &srp_dev_loss_tmo,
+               S_IRUGO | S_IWUSR);
++#else
++module_param_named(dev_loss_tmo, srp_dev_loss_tmo, int,
++                 S_IRUGO | S_IWUSR);
++#endif
++
+ MODULE_PARM_DESC(dev_loss_tmo,
+                "Maximum number of seconds that the SRP transport should"
+                " insulate transport layer errors. After this time has been"
+                " exceeded the SCSI host is removed. Should be"
+                " between 1 and " __stringify(SCSI_DEVICE_BLOCK_MAX_TIMEOUT)
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+                " if fast_io_fail_tmo has not been set. \"off\" means that"
++#else
++               " if fast_io_fail_tmo has not been set. (-1) means that"
++#endif
+                " this functionality is disabled.");
+ static void srp_add_one(struct ib_device *device);
+@@ -140,6 +175,7 @@ static struct ib_client srp_client = {
+ static struct ib_sa_client srp_sa_client;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+ static int srp_tmo_get(char *buffer, const struct kernel_param *kp)
+ {
+       int tmo = *(int *)kp->arg;
+@@ -181,6 +217,7 @@ static struct kernel_param_ops srp_tmo_ops = {
+       .get = srp_tmo_get,
+       .set = srp_tmo_set,
+ };
++#endif
+ static inline struct srp_target_port *host_to_target(struct Scsi_Host *host)
+ {
+@@ -1085,16 +1122,20 @@ static void srp_finish_req(struct srp_target_port *target,
+ static void srp_terminate_io(struct srp_rport *rport)
+ {
+       struct srp_target_port *target = rport->lld_data;
++#ifdef HAVE_REQUEST_QUEUE_REQUEST_FN_ACTIVE
+       struct Scsi_Host *shost = target->scsi_host;
+       struct scsi_device *sdev;
++#endif
+       int i;
+       /*
+        * Invoking srp_terminate_io() while srp_queuecommand() is running
+        * is not safe. Hence the warning statement below.
+        */
++#ifdef HAVE_REQUEST_QUEUE_REQUEST_FN_ACTIVE
+       shost_for_each_device(sdev, shost)
+               WARN_ON_ONCE(sdev->request_queue->request_fn_active);
++#endif
+       for (i = 0; i < target->req_ring_size; ++i) {
+               struct srp_request *req = &target->req_ring[i];
+@@ -1848,7 +1889,50 @@ static void srp_send_completion(struct ib_cq *cq, void *target_ptr)
+       }
+ }
+-static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd)
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
++/*
++ * Kernel with host lock push-down patch. See also upstream commit
++ * f281233d3eba15fb225d21ae2e228fd4553d824a.
++ */
++#define SRP_QUEUECOMMAND srp_queuecommand
++#elif defined(RHEL_MAJOR) && RHEL_MAJOR -0 == 6 && RHEL_MINOR -0 >= 2
++/*
++ * Kernel with lockless SCSI command dispatching enabled.
++ * See also the RHEL 6.2 release notes (http://access.redhat.com/knowledge/docs/en-US/Red_Hat_Enterprise_Linux/6/html-single/6.2_Release_Notes/index.html).
++ */
++static int srp_queuecommand_wrk(struct Scsi_Host *shost,
++                              struct scsi_cmnd *scmnd);
++static int srp_queuecommand(struct scsi_cmnd *scmnd,
++                          void (*done)(struct scsi_cmnd *))
++{
++      scmnd->scsi_done = done;
++      return srp_queuecommand_wrk(scmnd->device->host, scmnd);
++}
++#define SRP_QUEUECOMMAND srp_queuecommand_wrk
++#else
++/*
++ * Kernel that invokes srp_queuecommand with the SCSI host lock held.
++ */
++static int srp_queuecommand_wrk(struct Scsi_Host *shost,
++                              struct scsi_cmnd *scmnd);
++static int srp_queuecommand(struct scsi_cmnd *scmnd,
++                          void (*done)(struct scsi_cmnd *))
++{
++      struct Scsi_Host *shost = scmnd->device->host;
++      int res;
++
++      spin_unlock_irq(shost->host_lock);
++
++      scmnd->scsi_done = done;
++      res = srp_queuecommand_wrk(shost, scmnd);
++
++      spin_lock_irq(shost->host_lock);
++      return res;
++}
++#define SRP_QUEUECOMMAND srp_queuecommand_wrk
++#endif
++
++static int SRP_QUEUECOMMAND(struct Scsi_Host *shost, struct scsi_cmnd *scmnd)
+ {
+       struct srp_target_port *target = host_to_target(shost);
+       struct srp_rport *rport = target->rport;
+diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c
+index xxxxxxx..xxxxxxx xxxxxx
+--- a/drivers/scsi/scsi_transport_srp.c
++++ b/drivers/scsi/scsi_transport_srp.c
+@@ -405,7 +405,11 @@ static void __rport_fail_io_fast(struct srp_rport *rport)
+       if (srp_rport_set_state(rport, SRP_RPORT_FAIL_FAST))
+               return;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) || defined(CONFIG_COMPAT_SCSI_TARGET_UNBLOCK)
+       scsi_target_unblock(rport->dev.parent, SDEV_TRANSPORT_OFFLINE);
++#else
++      scsi_target_unblock(rport->dev.parent);
++#endif
+       /* Involve the LLD if possible to terminate all I/O on the rport. */
+       i = to_srp_internal(shost->transportt);
+@@ -448,7 +452,11 @@ static void rport_dev_loss_timedout(struct work_struct *work)
+       mutex_lock(&rport->mutex);
+       WARN_ON(srp_rport_set_state(rport, SRP_RPORT_LOST) != 0);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) || defined(CONFIG_COMPAT_SCSI_TARGET_UNBLOCK)
+       scsi_target_unblock(rport->dev.parent, SDEV_TRANSPORT_OFFLINE);
++#else
++      scsi_target_unblock(rport->dev.parent);
++#endif
+       mutex_unlock(&rport->mutex);
+       i->f->rport_delete(rport);
+@@ -509,6 +517,7 @@ EXPORT_SYMBOL(srp_start_tl_fail_timers);
+  */
+ static int scsi_request_fn_active(struct Scsi_Host *shost)
+ {
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+       struct scsi_device *sdev;
+       struct request_queue *q;
+       int request_fn_active = 0;
+@@ -522,6 +531,10 @@ static int scsi_request_fn_active(struct Scsi_Host *shost)
+       }
+       return request_fn_active;
++#else
++      msleep(20);
++      return 0;
++#endif
+ }
+ /**
+@@ -570,7 +583,11 @@ int srp_reconnect_rport(struct srp_rport *rport)
+               rport->failed_reconnects = 0;
+               srp_rport_set_state(rport, SRP_RPORT_RUNNING);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) || defined(CONFIG_COMPAT_SCSI_TARGET_UNBLOCK)
+               scsi_target_unblock(&shost->shost_gendev, SDEV_RUNNING);
++#else
++              scsi_target_unblock(&shost->shost_gendev);
++#endif
+               /*
+                * If the SCSI error handler has offlined one or more devices,
+                * invoking scsi_target_unblock() won't change the state of
+@@ -588,12 +605,20 @@ int srp_reconnect_rport(struct srp_rport *rport)
+                * failure timers if these had not yet been started.
+                */
+               __rport_fail_io_fast(rport);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) || defined(CONFIG_COMPAT_SCSI_TARGET_UNBLOCK)
+               scsi_target_unblock(&shost->shost_gendev,
+                                   SDEV_TRANSPORT_OFFLINE);
++#else
++              scsi_target_unblock(&shost->shost_gendev);
++#endif
+               __srp_start_tl_fail_timers(rport);
+       } else if (rport->state != SRP_RPORT_BLOCKED) {
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) || defined(CONFIG_COMPAT_SCSI_TARGET_UNBLOCK)
+               scsi_target_unblock(&shost->shost_gendev,
+                                   SDEV_TRANSPORT_OFFLINE);
++#else
++              scsi_target_unblock(&shost->shost_gendev);
++#endif
+       }
+       mutex_unlock(&rport->mutex);