From 9c3456e77a1311d7edf8d1345f9c65f23d23c0ad Mon Sep 17 00:00:00 2001 From: Vladimir Sokolovsky Date: Wed, 7 Jan 2015 17:13:21 +0200 Subject: [PATCH] Added SRP backport for RHEL6.5/6 Signed-off-by: Vladimir Sokolovsky --- patches/0023-BACKPORT-srp.patch | 263 ++++++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 patches/0023-BACKPORT-srp.patch diff --git a/patches/0023-BACKPORT-srp.patch b/patches/0023-BACKPORT-srp.patch new file mode 100644 index 0000000..a69b38b --- /dev/null +++ b/patches/0023-BACKPORT-srp.patch @@ -0,0 +1,263 @@ +From: Vladimir Sokolovsky +Subject: [PATCH] BACKPORT: srp + +Signed-off-by: Vladimir Sokolovsky +--- + 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 +@@ -41,7 +44,11 @@ + #include + #include + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) + #include ++#else ++#include ++#endif + + #include + #include +@@ -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); + -- 2.41.0