From 394c595ee8c3256db7200a3dedbf2d1811ca0b40 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 30 Oct 2014 14:46:27 +0100 Subject: IB/srp: Move ib_destroy_cm_id() call into srp_free_ch_ib() The patch that adds multichannel support into the SRP initiator driver introduces an additional call to srp_free_ch_ib(). This patch helps to keep that later patch simple. Signed-off-by: Bart Van Assche Reviewed-by: Sagi Grimberg Signed-off-by: Christoph Hellwig --- drivers/infiniband/ulp/srp/ib_srp.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/infiniband') diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 023a66f5ca1..819ebc9e7c8 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -555,6 +555,11 @@ static void srp_free_target_ib(struct srp_target_port *target) struct srp_device *dev = target->srp_host->srp_dev; int i; + if (target->cm_id) { + ib_destroy_cm_id(target->cm_id); + target->cm_id = NULL; + } + if (dev->use_fast_reg) { if (target->fr_pool) srp_destroy_fr_pool(target->fr_pool); @@ -868,7 +873,6 @@ static void srp_remove_target(struct srp_target_port *target) scsi_remove_host(target->scsi_host); srp_stop_rport_timers(target->rport); srp_disconnect_target(target); - ib_destroy_cm_id(target->cm_id); srp_free_target_ib(target); cancel_work_sync(&target->tl_err_work); srp_rport_put(target->rport); @@ -3021,7 +3025,7 @@ static ssize_t srp_create_target(struct device *dev, if (ret) { shost_printk(KERN_ERR, target->scsi_host, PFX "Connection failed\n"); - goto err_cm_id; + goto err_free_ib; } ret = srp_add_target(host, target); @@ -3045,9 +3049,6 @@ out: err_disconnect: srp_disconnect_target(target); -err_cm_id: - ib_destroy_cm_id(target->cm_id); - err_free_ib: srp_free_target_ib(target); -- cgit v1.2.3-70-g09d2 From 205619f2f82434aebc5eb21c97fe22eb7b393293 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 30 Oct 2014 14:46:55 +0100 Subject: IB/srp: Remove stale connection retry mechanism Attempting to connect three times may be insufficient after an initiator system tries to relogin, especially if the relogin attempt occurs before the SRP target service ID has been registered. Since the srp_daemon retries a failed login attempt anyway, remove the stale connection retry mechanism. Signed-off-by: Bart Van Assche Reviewed-by: Sagi Grimberg Signed-off-by: Christoph Hellwig --- drivers/infiniband/ulp/srp/ib_srp.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'drivers/infiniband') diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 819ebc9e7c8..e07a04a9127 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -904,7 +904,6 @@ static void srp_rport_delete(struct srp_rport *rport) static int srp_connect_target(struct srp_target_port *target) { - int retries = 3; int ret; WARN_ON_ONCE(target->connected); @@ -945,19 +944,10 @@ static int srp_connect_target(struct srp_target_port *target) break; case SRP_STALE_CONN: - /* Our current CM id was stale, and is now in timewait. - * Try to reconnect with a new one. - */ - if (!retries-- || srp_new_cm_id(target)) { - shost_printk(KERN_ERR, target->scsi_host, PFX - "giving up on stale connection\n"); - target->status = -ECONNRESET; - return target->status; - } - shost_printk(KERN_ERR, target->scsi_host, PFX - "retrying stale connection\n"); - break; + "giving up on stale connection\n"); + target->status = -ECONNRESET; + return target->status; default: return target->status; -- cgit v1.2.3-70-g09d2 From 34aa654ecb8eaef729c2bf51f7f97edab12fc3a6 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 30 Oct 2014 14:47:22 +0100 Subject: IB/srp: Avoid that I/O hangs due to a cable pull during LUN scanning If a cable is pulled during LUN scanning it can happen that the SRP rport and the SCSI host have been created but no LUNs have been added to the SCSI host. Since multipathd only sends SCSI commands to a SCSI target if one or more SCSI devices are present and since there is no keepalive mechanism for IB queue pairs this means that after a LUN scan failed and after a reconnect has succeeded no data will be sent over the QP and hence that a subsequent cable pull will not be detected. Avoid this by not creating an rport or SCSI host if a cable is pulled during a SCSI LUN scan. Note: so far the above behavior has only been observed with the kernel module parameter ch_count set to a value >= 2. Signed-off-by: Bart Van Assche Reviewed-by: Sagi Grimberg Signed-off-by: Christoph Hellwig --- drivers/infiniband/ulp/srp/ib_srp.c | 60 +++++++++++++++++++++++++++++++------ drivers/infiniband/ulp/srp/ib_srp.h | 1 + 2 files changed, 52 insertions(+), 9 deletions(-) (limited to 'drivers/infiniband') diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index e07a04a9127..68da24d18bc 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -1111,6 +1111,10 @@ static int srp_rport_reconnect(struct srp_rport *rport) int i, ret; srp_disconnect_target(target); + + if (target->state == SRP_TARGET_SCANNING) + return -ENODEV; + /* * Now get a new local CM ID so that we avoid confusing the target in * case things are really fouled up. Doing so also ensures that all CM @@ -2585,11 +2589,23 @@ static struct scsi_host_template srp_template = { .shost_attrs = srp_host_attrs }; +static int srp_sdev_count(struct Scsi_Host *host) +{ + struct scsi_device *sdev; + int c = 0; + + shost_for_each_device(sdev, host) + c++; + + return c; +} + static int srp_add_target(struct srp_host *host, struct srp_target_port *target) { struct srp_rport_identifiers ids; struct srp_rport *rport; + target->state = SRP_TARGET_SCANNING; sprintf(target->target_name, "SRP.T10:%016llX", (unsigned long long) be64_to_cpu(target->id_ext)); @@ -2612,11 +2628,26 @@ static int srp_add_target(struct srp_host *host, struct srp_target_port *target) list_add_tail(&target->list, &host->target_list); spin_unlock(&host->target_lock); - target->state = SRP_TARGET_LIVE; - scsi_scan_target(&target->scsi_host->shost_gendev, 0, target->scsi_id, SCAN_WILD_CARD, 0); + if (!target->connected || target->qp_in_error) { + shost_printk(KERN_INFO, target->scsi_host, + PFX "SCSI scan failed - removing SCSI host\n"); + srp_queue_remove_work(target); + goto out; + } + + pr_debug(PFX "%s: SCSI scan succeeded - detected %d LUNs\n", + dev_name(&target->scsi_host->shost_gendev), + srp_sdev_count(target->scsi_host)); + + spin_lock_irq(&target->lock); + if (target->state == SRP_TARGET_SCANNING) + target->state = SRP_TARGET_LIVE; + spin_unlock_irq(&target->lock); + +out: return 0; } @@ -2960,6 +2991,12 @@ static ssize_t srp_create_target(struct device *dev, target->tl_retry_count = 7; target->queue_size = SRP_DEFAULT_QUEUE_SIZE; + /* + * Avoid that the SCSI host can be removed by srp_remove_target() + * before this function returns. + */ + scsi_host_get(target->scsi_host); + mutex_lock(&host->add_target_mutex); ret = srp_parse_options(buf, target); @@ -3022,18 +3059,23 @@ static ssize_t srp_create_target(struct device *dev, if (ret) goto err_disconnect; - shost_printk(KERN_DEBUG, target->scsi_host, PFX - "new target: id_ext %016llx ioc_guid %016llx pkey %04x service_id %016llx sgid %pI6 dgid %pI6\n", - be64_to_cpu(target->id_ext), - be64_to_cpu(target->ioc_guid), - be16_to_cpu(target->path.pkey), - be64_to_cpu(target->service_id), - target->path.sgid.raw, target->path.dgid.raw); + if (target->state != SRP_TARGET_REMOVED) { + shost_printk(KERN_DEBUG, target->scsi_host, PFX + "new target: id_ext %016llx ioc_guid %016llx pkey %04x service_id %016llx sgid %pI6 dgid %pI6\n", + be64_to_cpu(target->id_ext), + be64_to_cpu(target->ioc_guid), + be16_to_cpu(target->path.pkey), + be64_to_cpu(target->service_id), + target->path.sgid.raw, target->orig_dgid); + } ret = count; out: mutex_unlock(&host->add_target_mutex); + + scsi_host_put(target->scsi_host); + return ret; err_disconnect: diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index e46ecb15aa0..00c7c480f68 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h @@ -73,6 +73,7 @@ enum { }; enum srp_target_state { + SRP_TARGET_SCANNING, SRP_TARGET_LIVE, SRP_TARGET_REMOVED, }; -- cgit v1.2.3-70-g09d2 From 747fe000ef38eb977945146d08f9050a0e504035 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 30 Oct 2014 14:48:05 +0100 Subject: IB/srp: Introduce two new srp_target_port member variables Introduce the srp_target_port member variables 'sgid' and 'pkey'. Change the type of 'orig_dgid' from __be16[8] into union ib_gid. This patch does not change any functionality but makes the "Separate target and channel variables" patch easier to verify. Signed-off-by: Bart Van Assche Reviewed-by: Sagi Grimberg Signed-off-by: Christoph Hellwig --- drivers/infiniband/ulp/srp/ib_srp.c | 39 ++++++++++++++++++++++--------------- drivers/infiniband/ulp/srp/ib_srp.h | 4 +++- 2 files changed, 26 insertions(+), 17 deletions(-) (limited to 'drivers/infiniband') diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 68da24d18bc..5298e299fbd 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -262,7 +262,7 @@ static int srp_init_qp(struct srp_target_port *target, ret = ib_find_pkey(target->srp_host->srp_dev->dev, target->srp_host->port, - be16_to_cpu(target->path.pkey), + be16_to_cpu(target->pkey), &attr->pkey_index); if (ret) goto out; @@ -295,6 +295,10 @@ static int srp_new_cm_id(struct srp_target_port *target) if (target->cm_id) ib_destroy_cm_id(target->cm_id); target->cm_id = new_cm_id; + target->path.sgid = target->sgid; + target->path.dgid = target->orig_dgid; + target->path.pkey = target->pkey; + target->path.service_id = target->service_id; return 0; } @@ -689,7 +693,7 @@ static int srp_send_req(struct srp_target_port *target) */ if (target->io_class == SRP_REV10_IB_IO_CLASS) { memcpy(req->priv.initiator_port_id, - &target->path.sgid.global.interface_id, 8); + &target->sgid.global.interface_id, 8); memcpy(req->priv.initiator_port_id + 8, &target->initiator_ext, 8); memcpy(req->priv.target_port_id, &target->ioc_guid, 8); @@ -698,7 +702,7 @@ static int srp_send_req(struct srp_target_port *target) memcpy(req->priv.initiator_port_id, &target->initiator_ext, 8); memcpy(req->priv.initiator_port_id + 8, - &target->path.sgid.global.interface_id, 8); + &target->sgid.global.interface_id, 8); memcpy(req->priv.target_port_id, &target->id_ext, 8); memcpy(req->priv.target_port_id + 8, &target->ioc_guid, 8); } @@ -2175,8 +2179,8 @@ static void srp_cm_rej_handler(struct ib_cm_id *cm_id, else shost_printk(KERN_WARNING, shost, PFX "SRP LOGIN from %pI6 to %pI6 REJECTED, reason 0x%08x\n", - target->path.sgid.raw, - target->orig_dgid, reason); + target->sgid.raw, + target->orig_dgid.raw, reason); } else shost_printk(KERN_WARNING, shost, " REJ reason: IB_CM_REJ_CONSUMER_DEFINED," @@ -2442,7 +2446,7 @@ static ssize_t show_pkey(struct device *dev, struct device_attribute *attr, { struct srp_target_port *target = host_to_target(class_to_shost(dev)); - return sprintf(buf, "0x%04x\n", be16_to_cpu(target->path.pkey)); + return sprintf(buf, "0x%04x\n", be16_to_cpu(target->pkey)); } static ssize_t show_sgid(struct device *dev, struct device_attribute *attr, @@ -2450,7 +2454,7 @@ static ssize_t show_sgid(struct device *dev, struct device_attribute *attr, { struct srp_target_port *target = host_to_target(class_to_shost(dev)); - return sprintf(buf, "%pI6\n", target->path.sgid.raw); + return sprintf(buf, "%pI6\n", target->sgid.raw); } static ssize_t show_dgid(struct device *dev, struct device_attribute *attr, @@ -2466,7 +2470,7 @@ static ssize_t show_orig_dgid(struct device *dev, { struct srp_target_port *target = host_to_target(class_to_shost(dev)); - return sprintf(buf, "%pI6\n", target->orig_dgid); + return sprintf(buf, "%pI6\n", target->orig_dgid.raw); } static ssize_t show_req_lim(struct device *dev, @@ -2804,11 +2808,15 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) } for (i = 0; i < 16; ++i) { - strlcpy(dgid, p + i * 2, 3); - target->path.dgid.raw[i] = simple_strtoul(dgid, NULL, 16); + strlcpy(dgid, p + i * 2, sizeof(dgid)); + if (sscanf(dgid, "%hhx", + &target->orig_dgid.raw[i]) < 1) { + ret = -EINVAL; + kfree(p); + goto out; + } } kfree(p); - memcpy(target->orig_dgid, target->path.dgid.raw, 16); break; case SRP_OPT_PKEY: @@ -2816,7 +2824,7 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) pr_warn("bad P_Key parameter '%s'\n", p); goto out; } - target->path.pkey = cpu_to_be16(token); + target->pkey = cpu_to_be16(token); break; case SRP_OPT_SERVICE_ID: @@ -2826,7 +2834,6 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) goto out; } target->service_id = cpu_to_be64(simple_strtoull(p, NULL, 16)); - target->path.service_id = target->service_id; kfree(p); break; @@ -3036,7 +3043,7 @@ static ssize_t srp_create_target(struct device *dev, if (ret) goto err_free_mem; - ret = ib_query_gid(ibdev, host->port, 0, &target->path.sgid); + ret = ib_query_gid(ibdev, host->port, 0, &target->sgid); if (ret) goto err_free_mem; @@ -3064,9 +3071,9 @@ static ssize_t srp_create_target(struct device *dev, "new target: id_ext %016llx ioc_guid %016llx pkey %04x service_id %016llx sgid %pI6 dgid %pI6\n", be64_to_cpu(target->id_ext), be64_to_cpu(target->ioc_guid), - be16_to_cpu(target->path.pkey), + be16_to_cpu(target->pkey), be64_to_cpu(target->service_id), - target->path.sgid.raw, target->orig_dgid); + target->sgid.raw, target->orig_dgid.raw); } ret = count; diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index 00c7c480f68..8635ab67435 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h @@ -157,6 +157,7 @@ struct srp_target_port { * command processing. Try to keep them packed into cachelines. */ + union ib_gid sgid; __be64 id_ext; __be64 ioc_guid; __be64 service_id; @@ -173,8 +174,9 @@ struct srp_target_port { int comp_vector; int tl_retry_count; + union ib_gid orig_dgid; + __be16 pkey; struct ib_sa_path_rec path; - __be16 orig_dgid[8]; struct ib_sa_query *path_query; int path_query_id; -- cgit v1.2.3-70-g09d2 From 509c07bc18500c3ded1a8e6273ace5002136c9d2 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 30 Oct 2014 14:48:30 +0100 Subject: IB/srp: Separate target and channel variables Changes in this patch: - Move channel variables into a new structure (struct srp_rdma_ch). - Add an srp_target_port pointer, 'lock' and 'comp_vector' members in struct srp_rdma_ch. - Add code to initialize these three new member variables. - Many boring "target->" into "ch->" changes. - The cm_id and completion handler context pointers are now of type srp_rdma_ch * instead of srp_target_port *. - Three kzalloc(a * b, f) calls have been changed into kcalloc(a, b, f) to avoid that this patch would trigger a checkpatch warning. - Two casts from u64 into unsigned long long have been left out because these are superfluous. Since considerable time u64 is defined as unsigned long long for all architectures supported by the Linux kernel. Signed-off-by: Bart Van Assche Acked-by: Sagi Grimberg Signed-off-by: Christoph Hellwig --- drivers/infiniband/ulp/srp/ib_srp.c | 674 +++++++++++++++++++----------------- drivers/infiniband/ulp/srp/ib_srp.h | 64 ++-- 2 files changed, 403 insertions(+), 335 deletions(-) (limited to 'drivers/infiniband') diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 5298e299fbd..f07a8a61473 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -125,8 +125,8 @@ MODULE_PARM_DESC(dev_loss_tmo, static void srp_add_one(struct ib_device *device); static void srp_remove_one(struct ib_device *device); -static void srp_recv_completion(struct ib_cq *cq, void *target_ptr); -static void srp_send_completion(struct ib_cq *cq, void *target_ptr); +static void srp_recv_completion(struct ib_cq *cq, void *ch_ptr); +static void srp_send_completion(struct ib_cq *cq, void *ch_ptr); static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event); static struct scsi_transport_template *ib_srp_transport_template; @@ -283,22 +283,23 @@ out: return ret; } -static int srp_new_cm_id(struct srp_target_port *target) +static int srp_new_cm_id(struct srp_rdma_ch *ch) { + struct srp_target_port *target = ch->target; struct ib_cm_id *new_cm_id; new_cm_id = ib_create_cm_id(target->srp_host->srp_dev->dev, - srp_cm_handler, target); + srp_cm_handler, ch); if (IS_ERR(new_cm_id)) return PTR_ERR(new_cm_id); - if (target->cm_id) - ib_destroy_cm_id(target->cm_id); - target->cm_id = new_cm_id; - target->path.sgid = target->sgid; - target->path.dgid = target->orig_dgid; - target->path.pkey = target->pkey; - target->path.service_id = target->service_id; + if (ch->cm_id) + ib_destroy_cm_id(ch->cm_id); + ch->cm_id = new_cm_id; + ch->path.sgid = target->sgid; + ch->path.dgid = target->orig_dgid; + ch->path.pkey = target->pkey; + ch->path.service_id = target->service_id; return 0; } @@ -447,8 +448,9 @@ static struct srp_fr_pool *srp_alloc_fr_pool(struct srp_target_port *target) dev->max_pages_per_mr); } -static int srp_create_target_ib(struct srp_target_port *target) +static int srp_create_ch_ib(struct srp_rdma_ch *ch) { + struct srp_target_port *target = ch->target; struct srp_device *dev = target->srp_host->srp_dev; struct ib_qp_init_attr *init_attr; struct ib_cq *recv_cq, *send_cq; @@ -462,15 +464,15 @@ static int srp_create_target_ib(struct srp_target_port *target) if (!init_attr) return -ENOMEM; - recv_cq = ib_create_cq(dev->dev, srp_recv_completion, NULL, target, - target->queue_size, target->comp_vector); + recv_cq = ib_create_cq(dev->dev, srp_recv_completion, NULL, ch, + target->queue_size, ch->comp_vector); if (IS_ERR(recv_cq)) { ret = PTR_ERR(recv_cq); goto err; } - send_cq = ib_create_cq(dev->dev, srp_send_completion, NULL, target, - m * target->queue_size, target->comp_vector); + send_cq = ib_create_cq(dev->dev, srp_send_completion, NULL, ch, + m * target->queue_size, ch->comp_vector); if (IS_ERR(send_cq)) { ret = PTR_ERR(send_cq); goto err_recv_cq; @@ -506,9 +508,9 @@ static int srp_create_target_ib(struct srp_target_port *target) "FR pool allocation failed (%d)\n", ret); goto err_qp; } - if (target->fr_pool) - srp_destroy_fr_pool(target->fr_pool); - target->fr_pool = fr_pool; + if (ch->fr_pool) + srp_destroy_fr_pool(ch->fr_pool); + ch->fr_pool = fr_pool; } else if (!dev->use_fast_reg && dev->has_fmr) { fmr_pool = srp_alloc_fmr_pool(target); if (IS_ERR(fmr_pool)) { @@ -517,21 +519,21 @@ static int srp_create_target_ib(struct srp_target_port *target) "FMR pool allocation failed (%d)\n", ret); goto err_qp; } - if (target->fmr_pool) - ib_destroy_fmr_pool(target->fmr_pool); - target->fmr_pool = fmr_pool; + if (ch->fmr_pool) + ib_destroy_fmr_pool(ch->fmr_pool); + ch->fmr_pool = fmr_pool; } - if (target->qp) - ib_destroy_qp(target->qp); - if (target->recv_cq) - ib_destroy_cq(target->recv_cq); - if (target->send_cq) - ib_destroy_cq(target->send_cq); + if (ch->qp) + ib_destroy_qp(ch->qp); + if (ch->recv_cq) + ib_destroy_cq(ch->recv_cq); + if (ch->send_cq) + ib_destroy_cq(ch->send_cq); - target->qp = qp; - target->recv_cq = recv_cq; - target->send_cq = send_cq; + ch->qp = qp; + ch->recv_cq = recv_cq; + ch->send_cq = send_cq; kfree(init_attr); return 0; @@ -552,98 +554,102 @@ err: /* * Note: this function may be called without srp_alloc_iu_bufs() having been - * invoked. Hence the target->[rt]x_ring checks. + * invoked. Hence the ch->[rt]x_ring checks. */ -static void srp_free_target_ib(struct srp_target_port *target) +static void srp_free_ch_ib(struct srp_target_port *target, + struct srp_rdma_ch *ch) { struct srp_device *dev = target->srp_host->srp_dev; int i; - if (target->cm_id) { - ib_destroy_cm_id(target->cm_id); - target->cm_id = NULL; + if (ch->cm_id) { + ib_destroy_cm_id(ch->cm_id); + ch->cm_id = NULL; } if (dev->use_fast_reg) { - if (target->fr_pool) - srp_destroy_fr_pool(target->fr_pool); + if (ch->fr_pool) + srp_destroy_fr_pool(ch->fr_pool); } else { - if (target->fmr_pool) - ib_destroy_fmr_pool(target->fmr_pool); + if (ch->fmr_pool) + ib_destroy_fmr_pool(ch->fmr_pool); } - ib_destroy_qp(target->qp); - ib_destroy_cq(target->send_cq); - ib_destroy_cq(target->recv_cq); + ib_destroy_qp(ch->qp); + ib_destroy_cq(ch->send_cq); + ib_destroy_cq(ch->recv_cq); - target->qp = NULL; - target->send_cq = target->recv_cq = NULL; + ch->qp = NULL; + ch->send_cq = ch->recv_cq = NULL; - if (target->rx_ring) { + if (ch->rx_ring) { for (i = 0; i < target->queue_size; ++i) - srp_free_iu(target->srp_host, target->rx_ring[i]); - kfree(target->rx_ring); - target->rx_ring = NULL; + srp_free_iu(target->srp_host, ch->rx_ring[i]); + kfree(ch->rx_ring); + ch->rx_ring = NULL; } - if (target->tx_ring) { + if (ch->tx_ring) { for (i = 0; i < target->queue_size; ++i) - srp_free_iu(target->srp_host, target->tx_ring[i]); - kfree(target->tx_ring); - target->tx_ring = NULL; + srp_free_iu(target->srp_host, ch->tx_ring[i]); + kfree(ch->tx_ring); + ch->tx_ring = NULL; } } static void srp_path_rec_completion(int status, struct ib_sa_path_rec *pathrec, - void *target_ptr) + void *ch_ptr) { - struct srp_target_port *target = target_ptr; + struct srp_rdma_ch *ch = ch_ptr; + struct srp_target_port *target = ch->target; - target->status = status; + ch->status = status; if (status) shost_printk(KERN_ERR, target->scsi_host, PFX "Got failed path rec status %d\n", status); else - target->path = *pathrec; - complete(&target->done); + ch->path = *pathrec; + complete(&ch->done); } -static int srp_lookup_path(struct srp_target_port *target) +static int srp_lookup_path(struct srp_rdma_ch *ch) { + struct srp_target_port *target = ch->target; int ret; - target->path.numb_path = 1; - - init_completion(&target->done); - - target->path_query_id = ib_sa_path_rec_get(&srp_sa_client, - target->srp_host->srp_dev->dev, - target->srp_host->port, - &target->path, - IB_SA_PATH_REC_SERVICE_ID | - IB_SA_PATH_REC_DGID | - IB_SA_PATH_REC_SGID | - IB_SA_PATH_REC_NUMB_PATH | - IB_SA_PATH_REC_PKEY, - SRP_PATH_REC_TIMEOUT_MS, - GFP_KERNEL, - srp_path_rec_completion, - target, &target->path_query); - if (target->path_query_id < 0) - return target->path_query_id; - - ret = wait_for_completion_interruptible(&target->done); + ch->path.numb_path = 1; + + init_completion(&ch->done); + + ch->path_query_id = ib_sa_path_rec_get(&srp_sa_client, + target->srp_host->srp_dev->dev, + target->srp_host->port, + &ch->path, + IB_SA_PATH_REC_SERVICE_ID | + IB_SA_PATH_REC_DGID | + IB_SA_PATH_REC_SGID | + IB_SA_PATH_REC_NUMB_PATH | + IB_SA_PATH_REC_PKEY, + SRP_PATH_REC_TIMEOUT_MS, + GFP_KERNEL, + srp_path_rec_completion, + ch, &ch->path_query); + if (ch->path_query_id < 0) + return ch->path_query_id; + + ret = wait_for_completion_interruptible(&ch->done); if (ret < 0) return ret; - if (target->status < 0) + if (ch->status < 0) shost_printk(KERN_WARNING, target->scsi_host, PFX "Path record query failed\n"); - return target->status; + return ch->status; } -static int srp_send_req(struct srp_target_port *target) +static int srp_send_req(struct srp_rdma_ch *ch) { + struct srp_target_port *target = ch->target; struct { struct ib_cm_req_param param; struct srp_login_req priv; @@ -654,11 +660,11 @@ static int srp_send_req(struct srp_target_port *target) if (!req) return -ENOMEM; - req->param.primary_path = &target->path; + req->param.primary_path = &ch->path; req->param.alternate_path = NULL; req->param.service_id = target->service_id; - req->param.qp_num = target->qp->qp_num; - req->param.qp_type = target->qp->qp_type; + req->param.qp_num = ch->qp->qp_num; + req->param.qp_type = ch->qp->qp_type; req->param.private_data = &req->priv; req->param.private_data_len = sizeof req->priv; req->param.flow_control = 1; @@ -722,7 +728,7 @@ static int srp_send_req(struct srp_target_port *target) &target->srp_host->srp_dev->dev->node_guid, 8); } - status = ib_send_cm_req(target->cm_id, &req->param); + status = ib_send_cm_req(ch->cm_id, &req->param); kfree(req); @@ -763,28 +769,31 @@ static bool srp_change_conn_state(struct srp_target_port *target, static void srp_disconnect_target(struct srp_target_port *target) { + struct srp_rdma_ch *ch = &target->ch; + if (srp_change_conn_state(target, false)) { /* XXX should send SRP_I_LOGOUT request */ - if (ib_send_cm_dreq(target->cm_id, NULL, 0)) { + if (ib_send_cm_dreq(ch->cm_id, NULL, 0)) { shost_printk(KERN_DEBUG, target->scsi_host, PFX "Sending CM DREQ failed\n"); } } } -static void srp_free_req_data(struct srp_target_port *target) +static void srp_free_req_data(struct srp_target_port *target, + struct srp_rdma_ch *ch) { struct srp_device *dev = target->srp_host->srp_dev; struct ib_device *ibdev = dev->dev; struct srp_request *req; int i; - if (!target->req_ring) + if (!ch->req_ring) return; for (i = 0; i < target->req_ring_size; ++i) { - req = &target->req_ring[i]; + req = &ch->req_ring[i]; if (dev->use_fast_reg) kfree(req->fr_list); else @@ -798,12 +807,13 @@ static void srp_free_req_data(struct srp_target_port *target) kfree(req->indirect_desc); } - kfree(target->req_ring); - target->req_ring = NULL; + kfree(ch->req_ring); + ch->req_ring = NULL; } -static int srp_alloc_req_data(struct srp_target_port *target) +static int srp_alloc_req_data(struct srp_rdma_ch *ch) { + struct srp_target_port *target = ch->target; struct srp_device *srp_dev = target->srp_host->srp_dev; struct ib_device *ibdev = srp_dev->dev; struct srp_request *req; @@ -811,15 +821,15 @@ static int srp_alloc_req_data(struct srp_target_port *target) dma_addr_t dma_addr; int i, ret = -ENOMEM; - INIT_LIST_HEAD(&target->free_reqs); + INIT_LIST_HEAD(&ch->free_reqs); - target->req_ring = kzalloc(target->req_ring_size * - sizeof(*target->req_ring), GFP_KERNEL); - if (!target->req_ring) + ch->req_ring = kcalloc(target->req_ring_size, sizeof(*ch->req_ring), + GFP_KERNEL); + if (!ch->req_ring) goto out; for (i = 0; i < target->req_ring_size; ++i) { - req = &target->req_ring[i]; + req = &ch->req_ring[i]; mr_list = kmalloc(target->cmd_sg_cnt * sizeof(void *), GFP_KERNEL); if (!mr_list) @@ -844,7 +854,7 @@ static int srp_alloc_req_data(struct srp_target_port *target) req->indirect_dma_addr = dma_addr; req->index = i; - list_add_tail(&req->list, &target->free_reqs); + list_add_tail(&req->list, &ch->free_reqs); } ret = 0; @@ -869,6 +879,8 @@ static void srp_del_scsi_host_attr(struct Scsi_Host *shost) static void srp_remove_target(struct srp_target_port *target) { + struct srp_rdma_ch *ch = &target->ch; + WARN_ON_ONCE(target->state != SRP_TARGET_REMOVED); srp_del_scsi_host_attr(target->scsi_host); @@ -877,10 +889,10 @@ static void srp_remove_target(struct srp_target_port *target) scsi_remove_host(target->scsi_host); srp_stop_rport_timers(target->rport); srp_disconnect_target(target); - srp_free_target_ib(target); + srp_free_ch_ib(target, ch); cancel_work_sync(&target->tl_err_work); srp_rport_put(target->rport); - srp_free_req_data(target); + srp_free_req_data(target, ch); spin_lock(&target->srp_host->target_lock); list_del(&target->list); @@ -906,24 +918,25 @@ static void srp_rport_delete(struct srp_rport *rport) srp_queue_remove_work(target); } -static int srp_connect_target(struct srp_target_port *target) +static int srp_connect_ch(struct srp_rdma_ch *ch) { + struct srp_target_port *target = ch->target; int ret; WARN_ON_ONCE(target->connected); target->qp_in_error = false; - ret = srp_lookup_path(target); + ret = srp_lookup_path(ch); if (ret) return ret; while (1) { - init_completion(&target->done); - ret = srp_send_req(target); + init_completion(&ch->done); + ret = srp_send_req(ch); if (ret) return ret; - ret = wait_for_completion_interruptible(&target->done); + ret = wait_for_completion_interruptible(&ch->done); if (ret < 0) return ret; @@ -933,13 +946,13 @@ static int srp_connect_target(struct srp_target_port *target) * back, or SRP_DLID_REDIRECT if we get a lid/qp * redirect REJ back. */ - switch (target->status) { + switch (ch->status) { case 0: srp_change_conn_state(target, true); return 0; case SRP_PORT_REDIRECT: - ret = srp_lookup_path(target); + ret = srp_lookup_path(ch); if (ret) return ret; break; @@ -950,16 +963,16 @@ static int srp_connect_target(struct srp_target_port *target) case SRP_STALE_CONN: shost_printk(KERN_ERR, target->scsi_host, PFX "giving up on stale connection\n"); - target->status = -ECONNRESET; - return target->status; + ch->status = -ECONNRESET; + return ch->status; default: - return target->status; + return ch->status; } } } -static int srp_inv_rkey(struct srp_target_port *target, u32 rkey) +static int srp_inv_rkey(struct srp_rdma_ch *ch, u32 rkey) { struct ib_send_wr *bad_wr; struct ib_send_wr wr = { @@ -971,13 +984,14 @@ static int srp_inv_rkey(struct srp_target_port *target, u32 rkey) .ex.invalidate_rkey = rkey, }; - return ib_post_send(target->qp, &wr, &bad_wr); + return ib_post_send(ch->qp, &wr, &bad_wr); } static void srp_unmap_data(struct scsi_cmnd *scmnd, - struct srp_target_port *target, + struct srp_rdma_ch *ch, struct srp_request *req) { + struct srp_target_port *target = ch->target; struct srp_device *dev = target->srp_host->srp_dev; struct ib_device *ibdev = dev->dev; int i, res; @@ -991,7 +1005,7 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd, struct srp_fr_desc **pfr; for (i = req->nmdesc, pfr = req->fr_list; i > 0; i--, pfr++) { - res = srp_inv_rkey(target, (*pfr)->mr->rkey); + res = srp_inv_rkey(ch, (*pfr)->mr->rkey); if (res < 0) { shost_printk(KERN_ERR, target->scsi_host, PFX "Queueing INV WR for rkey %#x failed (%d)\n", @@ -1001,7 +1015,7 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd, } } if (req->nmdesc) - srp_fr_pool_put(target->fr_pool, req->fr_list, + srp_fr_pool_put(ch->fr_pool, req->fr_list, req->nmdesc); } else { struct ib_pool_fmr **pfmr; @@ -1016,7 +1030,7 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd, /** * srp_claim_req - Take ownership of the scmnd associated with a request. - * @target: SRP target port. + * @ch: SRP RDMA channel. * @req: SRP request. * @sdev: If not NULL, only take ownership for this SCSI device. * @scmnd: If NULL, take ownership of @req->scmnd. If not NULL, only take @@ -1025,14 +1039,14 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd, * Return value: * Either NULL or a pointer to the SCSI command the caller became owner of. */ -static struct scsi_cmnd *srp_claim_req(struct srp_target_port *target, +static struct scsi_cmnd *srp_claim_req(struct srp_rdma_ch *ch, struct srp_request *req, struct scsi_device *sdev, struct scsi_cmnd *scmnd) { unsigned long flags; - spin_lock_irqsave(&target->lock, flags); + spin_lock_irqsave(&ch->lock, flags); if (req->scmnd && (!sdev || req->scmnd->device == sdev) && (!scmnd || req->scmnd == scmnd)) { @@ -1041,40 +1055,38 @@ static struct scsi_cmnd *srp_claim_req(struct srp_target_port *target, } else { scmnd = NULL; } - spin_unlock_irqrestore(&target->lock, flags); + spin_unlock_irqrestore(&ch->lock, flags); return scmnd; } /** * srp_free_req() - Unmap data and add request to the free request list. - * @target: SRP target port. + * @ch: SRP RDMA channel. * @req: Request to be freed. * @scmnd: SCSI command associated with @req. * @req_lim_delta: Amount to be added to @target->req_lim. */ -static void srp_free_req(struct srp_target_port *target, - struct srp_request *req, struct scsi_cmnd *scmnd, - s32 req_lim_delta) +static void srp_free_req(struct srp_rdma_ch *ch, struct srp_request *req, + struct scsi_cmnd *scmnd, s32 req_lim_delta) { unsigned long flags; - srp_unmap_data(scmnd, target, req); + srp_unmap_data(scmnd, ch, req); - spin_lock_irqsave(&target->lock, flags); - target->req_lim += req_lim_delta; - list_add_tail(&req->list, &target->free_reqs); - spin_unlock_irqrestore(&target->lock, flags); + spin_lock_irqsave(&ch->lock, flags); + ch->req_lim += req_lim_delta; + list_add_tail(&req->list, &ch->free_reqs); + spin_unlock_irqrestore(&ch->lock, flags); } -static void srp_finish_req(struct srp_target_port *target, - struct srp_request *req, struct scsi_device *sdev, - int result) +static void srp_finish_req(struct srp_rdma_ch *ch, struct srp_request *req, + struct scsi_device *sdev, int result) { - struct scsi_cmnd *scmnd = srp_claim_req(target, req, sdev, NULL); + struct scsi_cmnd *scmnd = srp_claim_req(ch, req, sdev, NULL); if (scmnd) { - srp_free_req(target, req, scmnd, 0); + srp_free_req(ch, req, scmnd, 0); scmnd->result = result; scmnd->scsi_done(scmnd); } @@ -1083,6 +1095,7 @@ 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; + struct srp_rdma_ch *ch = &target->ch; struct Scsi_Host *shost = target->scsi_host; struct scsi_device *sdev; int i; @@ -1095,8 +1108,9 @@ static void srp_terminate_io(struct srp_rport *rport) WARN_ON_ONCE(sdev->request_queue->request_fn_active); for (i = 0; i < target->req_ring_size; ++i) { - struct srp_request *req = &target->req_ring[i]; - srp_finish_req(target, req, NULL, DID_TRANSPORT_FAILFAST << 16); + struct srp_request *req = &ch->req_ring[i]; + + srp_finish_req(ch, req, NULL, DID_TRANSPORT_FAILFAST << 16); } } @@ -1112,6 +1126,7 @@ static void srp_terminate_io(struct srp_rport *rport) static int srp_rport_reconnect(struct srp_rport *rport) { struct srp_target_port *target = rport->lld_data; + struct srp_rdma_ch *ch = &target->ch; int i, ret; srp_disconnect_target(target); @@ -1124,11 +1139,12 @@ static int srp_rport_reconnect(struct srp_rport *rport) * case things are really fouled up. Doing so also ensures that all CM * callbacks will have finished before a new QP is allocated. */ - ret = srp_new_cm_id(target); + ret = srp_new_cm_id(ch); for (i = 0; i < target->req_ring_size; ++i) { - struct srp_request *req = &target->req_ring[i]; - srp_finish_req(target, req, NULL, DID_RESET << 16); + struct srp_request *req = &ch->req_ring[i]; + + srp_finish_req(ch, req, NULL, DID_RESET << 16); } /* @@ -1136,14 +1152,14 @@ static int srp_rport_reconnect(struct srp_rport *rport) * QP. This guarantees that all callback functions for the old QP have * finished before any send requests are posted on the new QP. */ - ret += srp_create_target_ib(target); + ret += srp_create_ch_ib(ch); - INIT_LIST_HEAD(&target->free_tx); + INIT_LIST_HEAD(&ch->free_tx); for (i = 0; i < target->queue_size; ++i) - list_add(&target->tx_ring[i]->list, &target->free_tx); + list_add(&ch->tx_ring[i]->list, &ch->free_tx); if (ret == 0) - ret = srp_connect_target(target); + ret = srp_connect_ch(ch); if (ret == 0) shost_printk(KERN_INFO, target->scsi_host, @@ -1167,12 +1183,12 @@ static void srp_map_desc(struct srp_map_state *state, dma_addr_t dma_addr, } static int srp_map_finish_fmr(struct srp_map_state *state, - struct srp_target_port *target) + struct srp_rdma_ch *ch) { struct ib_pool_fmr *fmr; u64 io_addr = 0; - fmr = ib_fmr_pool_map_phys(target->fmr_pool, state->pages, + fmr = ib_fmr_pool_map_phys(ch->fmr_pool, state->pages, state->npages, io_addr); if (IS_ERR(fmr)) return PTR_ERR(fmr); @@ -1186,15 +1202,16 @@ static int srp_map_finish_fmr(struct srp_map_state *state, } static int srp_map_finish_fr(struct srp_map_state *state, - struct srp_target_port *target) + struct srp_rdma_ch *ch) { + struct srp_target_port *target = ch->target; struct srp_device *dev = target->srp_host->srp_dev; struct ib_send_wr *bad_wr; struct ib_send_wr wr; struct srp_fr_desc *desc; u32 rkey; - desc = srp_fr_pool_get(target->fr_pool); + desc = srp_fr_pool_get(ch->fr_pool); if (!desc) return -ENOMEM; @@ -1223,12 +1240,13 @@ static int srp_map_finish_fr(struct srp_map_state *state, srp_map_desc(state, state->base_dma_addr, state->dma_len, desc->mr->rkey); - return ib_post_send(target->qp, &wr, &bad_wr); + return ib_post_send(ch->qp, &wr, &bad_wr); } static int srp_finish_mapping(struct srp_map_state *state, - struct srp_target_port *target) + struct srp_rdma_ch *ch) { + struct srp_target_port *target = ch->target; int ret = 0; if (state->npages == 0) @@ -1239,8 +1257,8 @@ static int srp_finish_mapping(struct srp_map_state *state, target->rkey); else ret = target->srp_host->srp_dev->use_fast_reg ? - srp_map_finish_fr(state, target) : - srp_map_finish_fmr(state, target); + srp_map_finish_fr(state, ch) : + srp_map_finish_fmr(state, ch); if (ret == 0) { state->npages = 0; @@ -1260,10 +1278,11 @@ static void srp_map_update_start(struct srp_map_state *state, } static int srp_map_sg_entry(struct srp_map_state *state, - struct srp_target_port *target, + struct srp_rdma_ch *ch, struct scatterlist *sg, int sg_index, bool use_mr) { + struct srp_target_port *target = ch->target; struct srp_device *dev = target->srp_host->srp_dev; struct ib_device *ibdev = dev->dev; dma_addr_t dma_addr = ib_sg_dma_address(ibdev, sg); @@ -1292,7 +1311,7 @@ static int srp_map_sg_entry(struct srp_map_state *state, */ if ((!dev->use_fast_reg && dma_addr & ~dev->mr_page_mask) || dma_len > dev->mr_max_size) { - ret = srp_finish_mapping(state, target); + ret = srp_finish_mapping(state, ch); if (ret) return ret; @@ -1313,7 +1332,7 @@ static int srp_map_sg_entry(struct srp_map_state *state, while (dma_len) { unsigned offset = dma_addr & ~dev->mr_page_mask; if (state->npages == dev->max_pages_per_mr || offset != 0) { - ret = srp_finish_mapping(state, target); + ret = srp_finish_mapping(state, ch); if (ret) return ret; @@ -1337,17 +1356,18 @@ static int srp_map_sg_entry(struct srp_map_state *state, */ ret = 0; if (len != dev->mr_page_size) { - ret = srp_finish_mapping(state, target); + ret = srp_finish_mapping(state, ch); if (!ret) srp_map_update_start(state, NULL, 0, 0); } return ret; } -static int srp_map_sg(struct srp_map_state *state, - struct srp_target_port *target, struct srp_request *req, - struct scatterlist *scat, int count) +static int srp_map_sg(struct srp_map_state *state, struct srp_rdma_ch *ch, + struct srp_request *req, struct scatterlist *scat, + int count) { + struct srp_target_port *target = ch->target; struct srp_device *dev = target->srp_host->srp_dev; struct ib_device *ibdev = dev->dev; struct scatterlist *sg; @@ -1358,14 +1378,14 @@ static int srp_map_sg(struct srp_map_state *state, state->pages = req->map_page; if (dev->use_fast_reg) { state->next_fr = req->fr_list; - use_mr = !!target->fr_pool; + use_mr = !!ch->fr_pool; } else { state->next_fmr = req->fmr_list; - use_mr = !!target->fmr_pool; + use_mr = !!ch->fmr_pool; } for_each_sg(scat, sg, count, i) { - if (srp_map_sg_entry(state, target, sg, i, use_mr)) { + if (srp_map_sg_entry(state, ch, sg, i, use_mr)) { /* * Memory registration failed, so backtrack to the * first unmapped entry and continue on without using @@ -1387,7 +1407,7 @@ backtrack: } } - if (use_mr && srp_finish_mapping(state, target)) + if (use_mr && srp_finish_mapping(state, ch)) goto backtrack; req->nmdesc = state->nmdesc; @@ -1395,9 +1415,10 @@ backtrack: return 0; } -static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target, +static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_rdma_ch *ch, struct srp_request *req) { + struct srp_target_port *target = ch->target; struct scatterlist *scat; struct srp_cmd *cmd = req->cmd->buf; int len, nents, count; @@ -1459,7 +1480,7 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target, target->indirect_size, DMA_TO_DEVICE); memset(&state, 0, sizeof(state)); - srp_map_sg(&state, target, req, scat, count); + srp_map_sg(&state, ch, req, scat, count); /* We've mapped the request, now pull as much of the indirect * descriptor table as we can into the command buffer. If this @@ -1520,20 +1541,20 @@ map_complete: /* * Return an IU and possible credit to the free pool */ -static void srp_put_tx_iu(struct srp_target_port *target, struct srp_iu *iu, +static void srp_put_tx_iu(struct srp_rdma_ch *ch, struct srp_iu *iu, enum srp_iu_type iu_type) { unsigned long flags; - spin_lock_irqsave(&target->lock, flags); - list_add(&iu->list, &target->free_tx); + spin_lock_irqsave(&ch->lock, flags); + list_add(&iu->list, &ch->free_tx); if (iu_type != SRP_IU_RSP) - ++target->req_lim; - spin_unlock_irqrestore(&target->lock, flags); + ++ch->req_lim; + spin_unlock_irqrestore(&ch->lock, flags); } /* - * Must be called with target->lock held to protect req_lim and free_tx. + * Must be called with ch->lock held to protect req_lim and free_tx. * If IU is not sent, it must be returned using srp_put_tx_iu(). * * Note: @@ -1545,35 +1566,36 @@ static void srp_put_tx_iu(struct srp_target_port *target, struct srp_iu *iu, * - SRP_IU_RSP: 1, since a conforming SRP target never sends more than * one unanswered SRP request to an initiator. */ -static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target, +static struct srp_iu *__srp_get_tx_iu(struct srp_rdma_ch *ch, enum srp_iu_type iu_type) { + struct srp_target_port *target = ch->target; s32 rsv = (iu_type == SRP_IU_TSK_MGMT) ? 0 : SRP_TSK_MGMT_SQ_SIZE; struct srp_iu *iu; - srp_send_completion(target->send_cq, target); + srp_send_completion(ch->send_cq, ch); - if (list_empty(&target->free_tx)) + if (list_empty(&ch->free_tx)) return NULL; /* Initiator responses to target requests do not consume credits */ if (iu_type != SRP_IU_RSP) { - if (target->req_lim <= rsv) { + if (ch->req_lim <= rsv) { ++target->zero_req_lim; return NULL; } - --target->req_lim; + --ch->req_lim; } - iu = list_first_entry(&target->free_tx, struct srp_iu, list); + iu = list_first_entry(&ch->free_tx, struct srp_iu, list); list_del(&iu->list); return iu; } -static int srp_post_send(struct srp_target_port *target, - struct srp_iu *iu, int len) +static int srp_post_send(struct srp_rdma_ch *ch, struct srp_iu *iu, int len) { + struct srp_target_port *target = ch->target; struct ib_sge list; struct ib_send_wr wr, *bad_wr; @@ -1588,11 +1610,12 @@ static int srp_post_send(struct srp_target_port *target, wr.opcode = IB_WR_SEND; wr.send_flags = IB_SEND_SIGNALED; - return ib_post_send(target->qp, &wr, &bad_wr); + return ib_post_send(ch->qp, &wr, &bad_wr); } -static int srp_post_recv(struct srp_target_port *target, struct srp_iu *iu) +static int srp_post_recv(struct srp_rdma_ch *ch, struct srp_iu *iu) { + struct srp_target_port *target = ch->target; struct ib_recv_wr wr, *bad_wr; struct ib_sge list; @@ -1605,35 +1628,36 @@ static int srp_post_recv(struct srp_target_port *target, struct srp_iu *iu) wr.sg_list = &list; wr.num_sge = 1; - return ib_post_recv(target->qp, &wr, &bad_wr); + return ib_post_recv(ch->qp, &wr, &bad_wr); } -static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) +static void srp_process_rsp(struct srp_rdma_ch *ch, struct srp_rsp *rsp) { + struct srp_target_port *target = ch->target; struct srp_request *req; struct scsi_cmnd *scmnd; unsigned long flags; if (unlikely(rsp->tag & SRP_TAG_TSK_MGMT)) { - spin_lock_irqsave(&target->lock, flags); - target->req_lim += be32_to_cpu(rsp->req_lim_delta); - spin_unlock_irqrestore(&target->lock, flags); + spin_lock_irqsave(&ch->lock, flags); + ch->req_lim += be32_to_cpu(rsp->req_lim_delta); + spin_unlock_irqrestore(&ch->lock, flags); - target->tsk_mgmt_status = -1; + ch->tsk_mgmt_status = -1; if (be32_to_cpu(rsp->resp_data_len) >= 4) - target->tsk_mgmt_status = rsp->data[3]; - complete(&target->tsk_mgmt_done); + ch->tsk_mgmt_status = rsp->data[3]; + complete(&ch->tsk_mgmt_done); } else { - req = &target->req_ring[rsp->tag]; - scmnd = srp_claim_req(target, req, NULL, NULL); + req = &ch->req_ring[rsp->tag]; + scmnd = srp_claim_req(ch, req, NULL, NULL); if (!scmnd) { shost_printk(KERN_ERR, target->scsi_host, "Null scmnd for RSP w/tag %016llx\n", (unsigned long long) rsp->tag); - spin_lock_irqsave(&target->lock, flags); - target->req_lim += be32_to_cpu(rsp->req_lim_delta); - spin_unlock_irqrestore(&target->lock, flags); + spin_lock_irqsave(&ch->lock, flags); + ch->req_lim += be32_to_cpu(rsp->req_lim_delta); + spin_unlock_irqrestore(&ch->lock, flags); return; } @@ -1655,7 +1679,7 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) else if (unlikely(rsp->flags & SRP_RSP_FLAG_DOOVER)) scsi_set_resid(scmnd, -be32_to_cpu(rsp->data_out_res_cnt)); - srp_free_req(target, req, scmnd, + srp_free_req(ch, req, scmnd, be32_to_cpu(rsp->req_lim_delta)); scmnd->host_scribble = NULL; @@ -1663,18 +1687,19 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) } } -static int srp_response_common(struct srp_target_port *target, s32 req_delta, +static int srp_response_common(struct srp_rdma_ch *ch, s32 req_delta, void *rsp, int len) { + struct srp_target_port *target = ch->target; struct ib_device *dev = target->srp_host->srp_dev->dev; unsigned long flags; struct srp_iu *iu; int err; - spin_lock_irqsave(&target->lock, flags); - target->req_lim += req_delta; - iu = __srp_get_tx_iu(target, SRP_IU_RSP); - spin_unlock_irqrestore(&target->lock, flags); + spin_lock_irqsave(&ch->lock, flags); + ch->req_lim += req_delta; + iu = __srp_get_tx_iu(ch, SRP_IU_RSP); + spin_unlock_irqrestore(&ch->lock, flags); if (!iu) { shost_printk(KERN_ERR, target->scsi_host, PFX @@ -1686,17 +1711,17 @@ static int srp_response_common(struct srp_target_port *target, s32 req_delta, memcpy(iu->buf, rsp, len); ib_dma_sync_single_for_device(dev, iu->dma, len, DMA_TO_DEVICE); - err = srp_post_send(target, iu, len); + err = srp_post_send(ch, iu, len); if (err) { shost_printk(KERN_ERR, target->scsi_host, PFX "unable to post response: %d\n", err); - srp_put_tx_iu(target, iu, SRP_IU_RSP); + srp_put_tx_iu(ch, iu, SRP_IU_RSP); } return err; } -static void srp_process_cred_req(struct srp_target_port *target, +static void srp_process_cred_req(struct srp_rdma_ch *ch, struct srp_cred_req *req) { struct srp_cred_rsp rsp = { @@ -1705,14 +1730,15 @@ static void srp_process_cred_req(struct srp_target_port *target, }; s32 delta = be32_to_cpu(req->req_lim_delta); - if (srp_response_common(target, delta, &rsp, sizeof rsp)) - shost_printk(KERN_ERR, target->scsi_host, PFX + if (srp_response_common(ch, delta, &rsp, sizeof(rsp))) + shost_printk(KERN_ERR, ch->target->scsi_host, PFX "problems processing SRP_CRED_REQ\n"); } -static void srp_process_aer_req(struct srp_target_port *target, +static void srp_process_aer_req(struct srp_rdma_ch *ch, struct srp_aer_req *req) { + struct srp_target_port *target = ch->target; struct srp_aer_rsp rsp = { .opcode = SRP_AER_RSP, .tag = req->tag, @@ -1722,19 +1748,20 @@ static void srp_process_aer_req(struct srp_target_port *target, shost_printk(KERN_ERR, target->scsi_host, PFX "ignoring AER for LUN %llu\n", be64_to_cpu(req->lun)); - if (srp_response_common(target, delta, &rsp, sizeof rsp)) + if (srp_response_common(ch, delta, &rsp, sizeof(rsp))) shost_printk(KERN_ERR, target->scsi_host, PFX "problems processing SRP_AER_REQ\n"); } -static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) +static void srp_handle_recv(struct srp_rdma_ch *ch, struct ib_wc *wc) { + struct srp_target_port *target = ch->target; struct ib_device *dev = target->srp_host->srp_dev->dev; struct srp_iu *iu = (struct srp_iu *) (uintptr_t) wc->wr_id; int res; u8 opcode; - ib_dma_sync_single_for_cpu(dev, iu->dma, target->max_ti_iu_len, + ib_dma_sync_single_for_cpu(dev, iu->dma, ch->max_ti_iu_len, DMA_FROM_DEVICE); opcode = *(u8 *) iu->buf; @@ -1748,15 +1775,15 @@ static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) switch (opcode) { case SRP_RSP: - srp_process_rsp(target, iu->buf); + srp_process_rsp(ch, iu->buf); break; case SRP_CRED_REQ: - srp_process_cred_req(target, iu->buf); + srp_process_cred_req(ch, iu->buf); break; case SRP_AER_REQ: - srp_process_aer_req(target, iu->buf); + srp_process_aer_req(ch, iu->buf); break; case SRP_T_LOGOUT: @@ -1771,10 +1798,10 @@ static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) break; } - ib_dma_sync_single_for_device(dev, iu->dma, target->max_ti_iu_len, + ib_dma_sync_single_for_device(dev, iu->dma, ch->max_ti_iu_len, DMA_FROM_DEVICE); - res = srp_post_recv(target, iu); + res = srp_post_recv(ch, iu); if (res != 0) shost_printk(KERN_ERR, target->scsi_host, PFX "Recv failed with error code %d\n", res); @@ -1819,33 +1846,35 @@ static void srp_handle_qp_err(u64 wr_id, enum ib_wc_status wc_status, target->qp_in_error = true; } -static void srp_recv_completion(struct ib_cq *cq, void *target_ptr) +static void srp_recv_completion(struct ib_cq *cq, void *ch_ptr) { - struct srp_target_port *target = target_ptr; + struct srp_rdma_ch *ch = ch_ptr; struct ib_wc wc; ib_req_notify_cq(cq, IB_CQ_NEXT_COMP); while (ib_poll_cq(cq, 1, &wc) > 0) { if (likely(wc.status == IB_WC_SUCCESS)) { - srp_handle_recv(target, &wc); + srp_handle_recv(ch, &wc); } else { - srp_handle_qp_err(wc.wr_id, wc.status, false, target); + srp_handle_qp_err(wc.wr_id, wc.status, false, + ch->target); } } } -static void srp_send_completion(struct ib_cq *cq, void *target_ptr) +static void srp_send_completion(struct ib_cq *cq, void *ch_ptr) { - struct srp_target_port *target = target_ptr; + struct srp_rdma_ch *ch = ch_ptr; struct ib_wc wc; struct srp_iu *iu; while (ib_poll_cq(cq, 1, &wc) > 0) { if (likely(wc.status == IB_WC_SUCCESS)) { iu = (struct srp_iu *) (uintptr_t) wc.wr_id; - list_add(&iu->list, &target->free_tx); + list_add(&iu->list, &ch->free_tx); } else { - srp_handle_qp_err(wc.wr_id, wc.status, true, target); + srp_handle_qp_err(wc.wr_id, wc.status, true, + ch->target); } } } @@ -1854,6 +1883,7 @@ 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; + struct srp_rdma_ch *ch; struct srp_request *req; struct srp_iu *iu; struct srp_cmd *cmd; @@ -1875,14 +1905,16 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd) if (unlikely(scmnd->result)) goto err; - spin_lock_irqsave(&target->lock, flags); - iu = __srp_get_tx_iu(target, SRP_IU_CMD); + ch = &target->ch; + + spin_lock_irqsave(&ch->lock, flags); + iu = __srp_get_tx_iu(ch, SRP_IU_CMD); if (!iu) goto err_unlock; - req = list_first_entry(&target->free_reqs, struct srp_request, list); + req = list_first_entry(&ch->free_reqs, struct srp_request, list); list_del(&req->list); - spin_unlock_irqrestore(&target->lock, flags); + spin_unlock_irqrestore(&ch->lock, flags); dev = target->srp_host->srp_dev->dev; ib_dma_sync_single_for_cpu(dev, iu->dma, target->max_iu_len, @@ -1901,7 +1933,7 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd) req->scmnd = scmnd; req->cmd = iu; - len = srp_map_data(scmnd, target, req); + len = srp_map_data(scmnd, ch, req); if (len < 0) { shost_printk(KERN_ERR, target->scsi_host, PFX "Failed to map data (%d)\n", len); @@ -1919,7 +1951,7 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd) ib_dma_sync_single_for_device(dev, iu->dma, target->max_iu_len, DMA_TO_DEVICE); - if (srp_post_send(target, iu, len)) { + if (srp_post_send(ch, iu, len)) { shost_printk(KERN_ERR, target->scsi_host, PFX "Send failed\n"); goto err_unmap; } @@ -1933,10 +1965,10 @@ unlock_rport: return ret; err_unmap: - srp_unmap_data(scmnd, target, req); + srp_unmap_data(scmnd, ch, req); err_iu: - srp_put_tx_iu(target, iu, SRP_IU_CMD); + srp_put_tx_iu(ch, iu, SRP_IU_CMD); /* * Avoid that the loops that iterate over the request ring can @@ -1944,11 +1976,11 @@ err_iu: */ req->scmnd = NULL; - spin_lock_irqsave(&target->lock, flags); - list_add(&req->list, &target->free_reqs); + spin_lock_irqsave(&ch->lock, flags); + list_add(&req->list, &ch->free_reqs); err_unlock: - spin_unlock_irqrestore(&target->lock, flags); + spin_unlock_irqrestore(&ch->lock, flags); err: if (scmnd->result) { @@ -1963,53 +1995,54 @@ err: /* * Note: the resources allocated in this function are freed in - * srp_free_target_ib(). + * srp_free_ch_ib(). */ -static int srp_alloc_iu_bufs(struct srp_target_port *target) +static int srp_alloc_iu_bufs(struct srp_rdma_ch *ch) { + struct srp_target_port *target = ch->target; int i; - target->rx_ring = kzalloc(target->queue_size * sizeof(*target->rx_ring), - GFP_KERNEL); - if (!target->rx_ring) + ch->rx_ring = kcalloc(target->queue_size, sizeof(*ch->rx_ring), + GFP_KERNEL); + if (!ch->rx_ring) goto err_no_ring; - target->tx_ring = kzalloc(target->queue_size * sizeof(*target->tx_ring), - GFP_KERNEL); - if (!target->tx_ring) + ch->tx_ring = kcalloc(target->queue_size, sizeof(*ch->tx_ring), + GFP_KERNEL); + if (!ch->tx_ring) goto err_no_ring; for (i = 0; i < target->queue_size; ++i) { - target->rx_ring[i] = srp_alloc_iu(target->srp_host, - target->max_ti_iu_len, - GFP_KERNEL, DMA_FROM_DEVICE); - if (!target->rx_ring[i]) + ch->rx_ring[i] = srp_alloc_iu(target->srp_host, + ch->max_ti_iu_len, + GFP_KERNEL, DMA_FROM_DEVICE); + if (!ch->rx_ring[i]) goto err; } for (i = 0; i < target->queue_size; ++i) { - target->tx_ring[i] = srp_alloc_iu(target->srp_host, - target->max_iu_len, - GFP_KERNEL, DMA_TO_DEVICE); - if (!target->tx_ring[i]) + ch->tx_ring[i] = srp_alloc_iu(target->srp_host, + target->max_iu_len, + GFP_KERNEL, DMA_TO_DEVICE); + if (!ch->tx_ring[i]) goto err; - list_add(&target->tx_ring[i]->list, &target->free_tx); + list_add(&ch->tx_ring[i]->list, &ch->free_tx); } return 0; err: for (i = 0; i < target->queue_size; ++i) { - srp_free_iu(target->srp_host, target->rx_ring[i]); - srp_free_iu(target->srp_host, target->tx_ring[i]); + srp_free_iu(target->srp_host, ch->rx_ring[i]); + srp_free_iu(target->srp_host, ch->tx_ring[i]); } err_no_ring: - kfree(target->tx_ring); - target->tx_ring = NULL; - kfree(target->rx_ring); - target->rx_ring = NULL; + kfree(ch->tx_ring); + ch->tx_ring = NULL; + kfree(ch->rx_ring); + ch->rx_ring = NULL; return -ENOMEM; } @@ -2043,23 +2076,24 @@ static uint32_t srp_compute_rq_tmo(struct ib_qp_attr *qp_attr, int attr_mask) static void srp_cm_rep_handler(struct ib_cm_id *cm_id, struct srp_login_rsp *lrsp, - struct srp_target_port *target) + struct srp_rdma_ch *ch) { + struct srp_target_port *target = ch->target; struct ib_qp_attr *qp_attr = NULL; int attr_mask = 0; int ret; int i; if (lrsp->opcode == SRP_LOGIN_RSP) { - target->max_ti_iu_len = be32_to_cpu(lrsp->max_ti_iu_len); - target->req_lim = be32_to_cpu(lrsp->req_lim_delta); + ch->max_ti_iu_len = be32_to_cpu(lrsp->max_ti_iu_len); + ch->req_lim = be32_to_cpu(lrsp->req_lim_delta); /* * Reserve credits for task management so we don't * bounce requests back to the SCSI mid-layer. */ target->scsi_host->can_queue - = min(target->req_lim - SRP_TSK_MGMT_SQ_SIZE, + = min(ch->req_lim - SRP_TSK_MGMT_SQ_SIZE, target->scsi_host->can_queue); target->scsi_host->cmd_per_lun = min_t(int, target->scsi_host->can_queue, @@ -2071,8 +2105,8 @@ static void srp_cm_rep_handler(struct ib_cm_id *cm_id, goto error; } - if (!target->rx_ring) { - ret = srp_alloc_iu_bufs(target); + if (!ch->rx_ring) { + ret = srp_alloc_iu_bufs(ch); if (ret) goto error; } @@ -2087,13 +2121,14 @@ static void srp_cm_rep_handler(struct ib_cm_id *cm_id, if (ret) goto error_free; - ret = ib_modify_qp(target->qp, qp_attr, attr_mask); + ret = ib_modify_qp(ch->qp, qp_attr, attr_mask); if (ret) goto error_free; for (i = 0; i < target->queue_size; i++) { - struct srp_iu *iu = target->rx_ring[i]; - ret = srp_post_recv(target, iu); + struct srp_iu *iu = ch->rx_ring[i]; + + ret = srp_post_recv(ch, iu); if (ret) goto error_free; } @@ -2105,7 +2140,7 @@ static void srp_cm_rep_handler(struct ib_cm_id *cm_id, target->rq_tmo_jiffies = srp_compute_rq_tmo(qp_attr, attr_mask); - ret = ib_modify_qp(target->qp, qp_attr, attr_mask); + ret = ib_modify_qp(ch->qp, qp_attr, attr_mask); if (ret) goto error_free; @@ -2115,13 +2150,14 @@ error_free: kfree(qp_attr); error: - target->status = ret; + ch->status = ret; } static void srp_cm_rej_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event, - struct srp_target_port *target) + struct srp_rdma_ch *ch) { + struct srp_target_port *target = ch->target; struct Scsi_Host *shost = target->scsi_host; struct ib_class_port_info *cpi; int opcode; @@ -2129,12 +2165,12 @@ static void srp_cm_rej_handler(struct ib_cm_id *cm_id, switch (event->param.rej_rcvd.reason) { case IB_CM_REJ_PORT_CM_REDIRECT: cpi = event->param.rej_rcvd.ari; - target->path.dlid = cpi->redirect_lid; - target->path.pkey = cpi->redirect_pkey; + ch->path.dlid = cpi->redirect_lid; + ch->path.pkey = cpi->redirect_pkey; cm_id->remote_cm_qpn = be32_to_cpu(cpi->redirect_qp) & 0x00ffffff; - memcpy(target->path.dgid.raw, cpi->redirect_gid, 16); + memcpy(ch->path.dgid.raw, cpi->redirect_gid, 16); - target->status = target->path.dlid ? + ch->status = ch->path.dlid ? SRP_DLID_REDIRECT : SRP_PORT_REDIRECT; break; @@ -2145,26 +2181,26 @@ static void srp_cm_rej_handler(struct ib_cm_id *cm_id, * reject reason code 25 when they mean 24 * (port redirect). */ - memcpy(target->path.dgid.raw, + memcpy(ch->path.dgid.raw, event->param.rej_rcvd.ari, 16); shost_printk(KERN_DEBUG, shost, PFX "Topspin/Cisco redirect to target port GID %016llx%016llx\n", - (unsigned long long) be64_to_cpu(target->path.dgid.global.subnet_prefix), - (unsigned long long) be64_to_cpu(target->path.dgid.global.interface_id)); + be64_to_cpu(ch->path.dgid.global.subnet_prefix), + be64_to_cpu(ch->path.dgid.global.interface_id)); - target->status = SRP_PORT_REDIRECT; + ch->status = SRP_PORT_REDIRECT; } else { shost_printk(KERN_WARNING, shost, " REJ reason: IB_CM_REJ_PORT_REDIRECT\n"); - target->status = -ECONNRESET; + ch->status = -ECONNRESET; } break; case IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID: shost_printk(KERN_WARNING, shost, " REJ reason: IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID\n"); - target->status = -ECONNRESET; + ch->status = -ECONNRESET; break; case IB_CM_REJ_CONSUMER_DEFINED: @@ -2185,24 +2221,25 @@ static void srp_cm_rej_handler(struct ib_cm_id *cm_id, shost_printk(KERN_WARNING, shost, " REJ reason: IB_CM_REJ_CONSUMER_DEFINED," " opcode 0x%02x\n", opcode); - target->status = -ECONNRESET; + ch->status = -ECONNRESET; break; case IB_CM_REJ_STALE_CONN: shost_printk(KERN_WARNING, shost, " REJ reason: stale connection\n"); - target->status = SRP_STALE_CONN; + ch->status = SRP_STALE_CONN; break; default: shost_printk(KERN_WARNING, shost, " REJ reason 0x%x\n", event->param.rej_rcvd.reason); - target->status = -ECONNRESET; + ch->status = -ECONNRESET; } } static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) { - struct srp_target_port *target = cm_id->context; + struct srp_rdma_ch *ch = cm_id->context; + struct srp_target_port *target = ch->target; int comp = 0; switch (event->event) { @@ -2210,19 +2247,19 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) shost_printk(KERN_DEBUG, target->scsi_host, PFX "Sending CM REQ failed\n"); comp = 1; - target->status = -ECONNRESET; + ch->status = -ECONNRESET; break; case IB_CM_REP_RECEIVED: comp = 1; - srp_cm_rep_handler(cm_id, event->private_data, target); + srp_cm_rep_handler(cm_id, event->private_data, ch); break; case IB_CM_REJ_RECEIVED: shost_printk(KERN_DEBUG, target->scsi_host, PFX "REJ received\n"); comp = 1; - srp_cm_rej_handler(cm_id, event, target); + srp_cm_rej_handler(cm_id, event, ch); break; case IB_CM_DREQ_RECEIVED: @@ -2240,7 +2277,7 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) PFX "connection closed\n"); comp = 1; - target->status = 0; + ch->status = 0; break; case IB_CM_MRA_RECEIVED: @@ -2255,7 +2292,7 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) } if (comp) - complete(&target->done); + complete(&ch->done); return 0; } @@ -2289,9 +2326,10 @@ srp_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) return sdev->queue_depth; } -static int srp_send_tsk_mgmt(struct srp_target_port *target, - u64 req_tag, unsigned int lun, u8 func) +static int srp_send_tsk_mgmt(struct srp_rdma_ch *ch, u64 req_tag, + unsigned int lun, u8 func) { + struct srp_target_port *target = ch->target; struct srp_rport *rport = target->rport; struct ib_device *dev = target->srp_host->srp_dev->dev; struct srp_iu *iu; @@ -2300,16 +2338,16 @@ static int srp_send_tsk_mgmt(struct srp_target_port *target, if (!target->connected || target->qp_in_error) return -1; - init_completion(&target->tsk_mgmt_done); + init_completion(&ch->tsk_mgmt_done); /* - * Lock the rport mutex to avoid that srp_create_target_ib() is + * Lock the rport mutex to avoid that srp_create_ch_ib() is * invoked while a task management function is being sent. */ mutex_lock(&rport->mutex); - spin_lock_irq(&target->lock); - iu = __srp_get_tx_iu(target, SRP_IU_TSK_MGMT); - spin_unlock_irq(&target->lock); + spin_lock_irq(&ch->lock); + iu = __srp_get_tx_iu(ch, SRP_IU_TSK_MGMT); + spin_unlock_irq(&ch->lock); if (!iu) { mutex_unlock(&rport->mutex); @@ -2330,15 +2368,15 @@ static int srp_send_tsk_mgmt(struct srp_target_port *target, ib_dma_sync_single_for_device(dev, iu->dma, sizeof *tsk_mgmt, DMA_TO_DEVICE); - if (srp_post_send(target, iu, sizeof *tsk_mgmt)) { - srp_put_tx_iu(target, iu, SRP_IU_TSK_MGMT); + if (srp_post_send(ch, iu, sizeof(*tsk_mgmt))) { + srp_put_tx_iu(ch, iu, SRP_IU_TSK_MGMT); mutex_unlock(&rport->mutex); return -1; } mutex_unlock(&rport->mutex); - if (!wait_for_completion_timeout(&target->tsk_mgmt_done, + if (!wait_for_completion_timeout(&ch->tsk_mgmt_done, msecs_to_jiffies(SRP_ABORT_TIMEOUT_MS))) return -1; @@ -2349,20 +2387,22 @@ static int srp_abort(struct scsi_cmnd *scmnd) { struct srp_target_port *target = host_to_target(scmnd->device->host); struct srp_request *req = (struct srp_request *) scmnd->host_scribble; + struct srp_rdma_ch *ch; int ret; shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); - if (!req || !srp_claim_req(target, req, NULL, scmnd)) + ch = &target->ch; + if (!req || !srp_claim_req(ch, req, NULL, scmnd)) return SUCCESS; - if (srp_send_tsk_mgmt(target, req->index, scmnd->device->lun, + if (srp_send_tsk_mgmt(ch, req->index, scmnd->device->lun, SRP_TSK_ABORT_TASK) == 0) ret = SUCCESS; else if (target->rport->state == SRP_RPORT_LOST) ret = FAST_IO_FAIL; else ret = FAILED; - srp_free_req(target, req, scmnd, 0); + srp_free_req(ch, req, scmnd, 0); scmnd->result = DID_ABORT << 16; scmnd->scsi_done(scmnd); @@ -2372,19 +2412,21 @@ static int srp_abort(struct scsi_cmnd *scmnd) static int srp_reset_device(struct scsi_cmnd *scmnd) { struct srp_target_port *target = host_to_target(scmnd->device->host); + struct srp_rdma_ch *ch = &target->ch; int i; shost_printk(KERN_ERR, target->scsi_host, "SRP reset_device called\n"); - if (srp_send_tsk_mgmt(target, SRP_TAG_NO_REQ, scmnd->device->lun, + if (srp_send_tsk_mgmt(ch, SRP_TAG_NO_REQ, scmnd->device->lun, SRP_TSK_LUN_RESET)) return FAILED; - if (target->tsk_mgmt_status) + if (ch->tsk_mgmt_status) return FAILED; for (i = 0; i < target->req_ring_size; ++i) { - struct srp_request *req = &target->req_ring[i]; - srp_finish_req(target, req, scmnd->device, DID_RESET << 16); + struct srp_request *req = &ch->req_ring[i]; + + srp_finish_req(ch, req, scmnd->device, DID_RESET << 16); } return SUCCESS; @@ -2461,8 +2503,9 @@ static ssize_t show_dgid(struct device *dev, struct device_attribute *attr, char *buf) { struct srp_target_port *target = host_to_target(class_to_shost(dev)); + struct srp_rdma_ch *ch = &target->ch; - return sprintf(buf, "%pI6\n", target->path.dgid.raw); + return sprintf(buf, "%pI6\n", ch->path.dgid.raw); } static ssize_t show_orig_dgid(struct device *dev, @@ -2478,7 +2521,7 @@ static ssize_t show_req_lim(struct device *dev, { struct srp_target_port *target = host_to_target(class_to_shost(dev)); - return sprintf(buf, "%d\n", target->req_lim); + return sprintf(buf, "%d\n", target->ch.req_lim); } static ssize_t show_zero_req_lim(struct device *dev, @@ -2970,6 +3013,7 @@ static ssize_t srp_create_target(struct device *dev, container_of(dev, struct srp_host, dev); struct Scsi_Host *target_host; struct srp_target_port *target; + struct srp_rdma_ch *ch; struct srp_device *srp_dev = host->srp_dev; struct ib_device *ibdev = srp_dev->dev; int ret; @@ -3038,8 +3082,12 @@ static ssize_t srp_create_target(struct device *dev, INIT_WORK(&target->tl_err_work, srp_tl_err_work); INIT_WORK(&target->remove_work, srp_remove_work); spin_lock_init(&target->lock); - INIT_LIST_HEAD(&target->free_tx); - ret = srp_alloc_req_data(target); + ch = &target->ch; + ch->target = target; + ch->comp_vector = target->comp_vector; + spin_lock_init(&ch->lock); + INIT_LIST_HEAD(&ch->free_tx); + ret = srp_alloc_req_data(ch); if (ret) goto err_free_mem; @@ -3047,15 +3095,15 @@ static ssize_t srp_create_target(struct device *dev, if (ret) goto err_free_mem; - ret = srp_create_target_ib(target); + ret = srp_create_ch_ib(ch); if (ret) goto err_free_mem; - ret = srp_new_cm_id(target); + ret = srp_new_cm_id(ch); if (ret) goto err_free_ib; - ret = srp_connect_target(target); + ret = srp_connect_ch(ch); if (ret) { shost_printk(KERN_ERR, target->scsi_host, PFX "Connection failed\n"); @@ -3089,10 +3137,10 @@ err_disconnect: srp_disconnect_target(target); err_free_ib: - srp_free_target_ib(target); + srp_free_ch_ib(target, ch); err_free_mem: - srp_free_req_data(target); + srp_free_req_data(target, ch); err: scsi_host_put(target_host); diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index 8635ab67435..74530d9e639 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h @@ -130,7 +130,11 @@ struct srp_request { short index; }; -struct srp_target_port { +/** + * struct srp_rdma_ch + * @comp_vector: Completion vector used by this RDMA channel. + */ +struct srp_rdma_ch { /* These are RW in the hot path, and commonly used together */ struct list_head free_tx; struct list_head free_reqs; @@ -138,13 +142,48 @@ struct srp_target_port { s32 req_lim; /* These are read-only in the hot path */ - struct ib_cq *send_cq ____cacheline_aligned_in_smp; + struct srp_target_port *target ____cacheline_aligned_in_smp; + struct ib_cq *send_cq; struct ib_cq *recv_cq; struct ib_qp *qp; union { struct ib_fmr_pool *fmr_pool; struct srp_fr_pool *fr_pool; }; + + /* Everything above this point is used in the hot path of + * command processing. Try to keep them packed into cachelines. + */ + + struct completion done; + int status; + + struct ib_sa_path_rec path; + struct ib_sa_query *path_query; + int path_query_id; + + struct ib_cm_id *cm_id; + struct srp_iu **tx_ring; + struct srp_iu **rx_ring; + struct srp_request *req_ring; + int max_ti_iu_len; + int comp_vector; + + struct completion tsk_mgmt_done; + u8 tsk_mgmt_status; +}; + +/** + * struct srp_target_port + * @comp_vector: Completion vector used by the first RDMA channel created for + * this target port. + */ +struct srp_target_port { + /* read and written in the hot path */ + spinlock_t lock; + + struct srp_rdma_ch ch; + /* read only in the hot path */ u32 lkey; u32 rkey; enum srp_target_state state; @@ -153,10 +192,7 @@ struct srp_target_port { unsigned int indirect_size; bool allow_ext_sg; - /* Everything above this point is used in the hot path of - * command processing. Try to keep them packed into cachelines. - */ - + /* other member variables */ union ib_gid sgid; __be64 id_ext; __be64 ioc_guid; @@ -176,33 +212,17 @@ struct srp_target_port { union ib_gid orig_dgid; __be16 pkey; - struct ib_sa_path_rec path; - struct ib_sa_query *path_query; - int path_query_id; u32 rq_tmo_jiffies; bool connected; - struct ib_cm_id *cm_id; - - int max_ti_iu_len; - int zero_req_lim; - struct srp_iu **tx_ring; - struct srp_iu **rx_ring; - struct srp_request *req_ring; - struct work_struct tl_err_work; struct work_struct remove_work; struct list_head list; - struct completion done; - int status; bool qp_in_error; - - struct completion tsk_mgmt_done; - u8 tsk_mgmt_status; }; struct srp_iu { -- cgit v1.2.3-70-g09d2 From 77f2c1a40e6fed202d08c8ec0bdca36a76dab368 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 2 Oct 2014 15:29:25 +0200 Subject: IB/srp: Use block layer tags Since the block layer already contains functionality to assign a tag to each request, use that functionality instead of reimplementing that functionality in the SRP initiator driver. This change makes the free_reqs list superfluous. Hence remove that list. [hch: updated to use .use_blk_tags instead scsi_activate_tcq] Signed-off-by: Bart Van Assche Reviewed-by: Sagi Grimberg Signed-off-by: Christoph Hellwig --- drivers/infiniband/ulp/srp/ib_srp.c | 48 +++++++++++++++++++++---------------- drivers/infiniband/ulp/srp/ib_srp.h | 3 --- 2 files changed, 27 insertions(+), 24 deletions(-) (limited to 'drivers/infiniband') diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index f07a8a61473..42af59f3c8c 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -821,8 +821,6 @@ static int srp_alloc_req_data(struct srp_rdma_ch *ch) dma_addr_t dma_addr; int i, ret = -ENOMEM; - INIT_LIST_HEAD(&ch->free_reqs); - ch->req_ring = kcalloc(target->req_ring_size, sizeof(*ch->req_ring), GFP_KERNEL); if (!ch->req_ring) @@ -853,8 +851,6 @@ static int srp_alloc_req_data(struct srp_rdma_ch *ch) goto out; req->indirect_dma_addr = dma_addr; - req->index = i; - list_add_tail(&req->list, &ch->free_reqs); } ret = 0; @@ -1076,7 +1072,6 @@ static void srp_free_req(struct srp_rdma_ch *ch, struct srp_request *req, spin_lock_irqsave(&ch->lock, flags); ch->req_lim += req_lim_delta; - list_add_tail(&req->list, &ch->free_reqs); spin_unlock_irqrestore(&ch->lock, flags); } @@ -1648,8 +1643,11 @@ static void srp_process_rsp(struct srp_rdma_ch *ch, struct srp_rsp *rsp) ch->tsk_mgmt_status = rsp->data[3]; complete(&ch->tsk_mgmt_done); } else { - req = &ch->req_ring[rsp->tag]; - scmnd = srp_claim_req(ch, req, NULL, NULL); + scmnd = scsi_host_find_tag(target->scsi_host, rsp->tag); + if (scmnd) { + req = (void *)scmnd->host_scribble; + scmnd = srp_claim_req(ch, req, NULL, scmnd); + } if (!scmnd) { shost_printk(KERN_ERR, target->scsi_host, "Null scmnd for RSP w/tag %016llx\n", @@ -1889,6 +1887,8 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd) struct srp_cmd *cmd; struct ib_device *dev; unsigned long flags; + u32 tag; + u16 idx; int len, ret; const bool in_scsi_eh = !in_interrupt() && current == shost->ehandler; @@ -1905,17 +1905,22 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd) if (unlikely(scmnd->result)) goto err; + WARN_ON_ONCE(scmnd->request->tag < 0); + tag = blk_mq_unique_tag(scmnd->request); ch = &target->ch; + idx = blk_mq_unique_tag_to_tag(tag); + WARN_ONCE(idx >= target->req_ring_size, "%s: tag %#x: idx %d >= %d\n", + dev_name(&shost->shost_gendev), tag, idx, + target->req_ring_size); spin_lock_irqsave(&ch->lock, flags); iu = __srp_get_tx_iu(ch, SRP_IU_CMD); - if (!iu) - goto err_unlock; - - req = list_first_entry(&ch->free_reqs, struct srp_request, list); - list_del(&req->list); spin_unlock_irqrestore(&ch->lock, flags); + if (!iu) + goto err; + + req = &ch->req_ring[idx]; dev = target->srp_host->srp_dev->dev; ib_dma_sync_single_for_cpu(dev, iu->dma, target->max_iu_len, DMA_TO_DEVICE); @@ -1927,7 +1932,7 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd) cmd->opcode = SRP_CMD; cmd->lun = cpu_to_be64((u64) scmnd->device->lun << 48); - cmd->tag = req->index; + cmd->tag = tag; memcpy(cmd->cdb, scmnd->cmnd, scmnd->cmd_len); req->scmnd = scmnd; @@ -1976,12 +1981,6 @@ err_iu: */ req->scmnd = NULL; - spin_lock_irqsave(&ch->lock, flags); - list_add(&req->list, &ch->free_reqs); - -err_unlock: - spin_unlock_irqrestore(&ch->lock, flags); - err: if (scmnd->result) { scmnd->scsi_done(scmnd); @@ -2387,6 +2386,7 @@ static int srp_abort(struct scsi_cmnd *scmnd) { struct srp_target_port *target = host_to_target(scmnd->device->host); struct srp_request *req = (struct srp_request *) scmnd->host_scribble; + u32 tag; struct srp_rdma_ch *ch; int ret; @@ -2395,7 +2395,8 @@ static int srp_abort(struct scsi_cmnd *scmnd) ch = &target->ch; if (!req || !srp_claim_req(ch, req, NULL, scmnd)) return SUCCESS; - if (srp_send_tsk_mgmt(ch, req->index, scmnd->device->lun, + tag = blk_mq_unique_tag(scmnd->request); + if (srp_send_tsk_mgmt(ch, tag, scmnd->device->lun, SRP_TSK_ABORT_TASK) == 0) ret = SUCCESS; else if (target->rport->state == SRP_RPORT_LOST) @@ -2633,7 +2634,8 @@ static struct scsi_host_template srp_template = { .this_id = -1, .cmd_per_lun = SRP_DEFAULT_CMD_SQ_SIZE, .use_clustering = ENABLE_CLUSTERING, - .shost_attrs = srp_host_attrs + .shost_attrs = srp_host_attrs, + .use_blk_tags = 1, }; static int srp_sdev_count(struct Scsi_Host *host) @@ -3054,6 +3056,10 @@ static ssize_t srp_create_target(struct device *dev, if (ret) goto err; + ret = scsi_init_shared_tag_map(target_host, target_host->can_queue); + if (ret) + goto err; + target->req_ring_size = target->queue_size - SRP_TSK_MGMT_SQ_SIZE; if (!srp_conn_unique(target->srp_host, target)) { diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index 74530d9e639..37aa9f49947 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h @@ -116,7 +116,6 @@ struct srp_host { }; struct srp_request { - struct list_head list; struct scsi_cmnd *scmnd; struct srp_iu *cmd; union { @@ -127,7 +126,6 @@ struct srp_request { struct srp_direct_buf *indirect_desc; dma_addr_t indirect_dma_addr; short nmdesc; - short index; }; /** @@ -137,7 +135,6 @@ struct srp_request { struct srp_rdma_ch { /* These are RW in the hot path, and commonly used together */ struct list_head free_tx; - struct list_head free_reqs; spinlock_t lock; s32 req_lim; -- cgit v1.2.3-70-g09d2 From d92c0da71a35dfddccca7bfa932829504311359e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 6 Oct 2014 17:14:36 +0200 Subject: IB/srp: Add multichannel support Improve performance by using multiple RDMA/RC channels per SCSI host for communication with an SRP target. About the implementation: - Introduce a loop over all channels in the code that uses target->ch. - Set the SRP_MULTICHAN_MULTI flag during login for the creation of the second and subsequent channels. - RDMA completion vectors are chosen such that RDMA completion interrupts are handled by the CPU socket that submitted the I/O request. As one can see in this patch it has been assumed if a system contains n CPU sockets and m RDMA completion vectors have been assigned to an RDMA HCA that IRQ affinity has been configured such that completion vectors [i*m/n..(i+1)*m/n) are bound to CPU socket i with 0 <= i < n. - Modify srp_free_ch_ib() and srp_free_req_data() such that it becomes safe to invoke these functions after the corresponding allocation function failed. - Add a ch_count sysfs attribute per target port. Signed-off-by: Bart Van Assche Reviewed-by: Sagi Grimberg Signed-off-by: Christoph Hellwig --- Documentation/ABI/stable/sysfs-driver-ib_srp | 25 ++- drivers/infiniband/ulp/srp/ib_srp.c | 288 ++++++++++++++++++++------- drivers/infiniband/ulp/srp/ib_srp.h | 3 +- 3 files changed, 235 insertions(+), 81 deletions(-) (limited to 'drivers/infiniband') diff --git a/Documentation/ABI/stable/sysfs-driver-ib_srp b/Documentation/ABI/stable/sysfs-driver-ib_srp index b9688de8455..7049a2b5035 100644 --- a/Documentation/ABI/stable/sysfs-driver-ib_srp +++ b/Documentation/ABI/stable/sysfs-driver-ib_srp @@ -55,12 +55,12 @@ Description: Interface for making ib_srp connect to a new target. only safe with partial memory descriptor list support enabled (allow_ext_sg=1). * comp_vector, a number in the range 0..n-1 specifying the - MSI-X completion vector. Some HCA's allocate multiple (n) - MSI-X vectors per HCA port. If the IRQ affinity masks of - these interrupts have been configured such that each MSI-X - interrupt is handled by a different CPU then the comp_vector - parameter can be used to spread the SRP completion workload - over multiple CPU's. + MSI-X completion vector of the first RDMA channel. Some + HCA's allocate multiple (n) MSI-X vectors per HCA port. If + the IRQ affinity masks of these interrupts have been + configured such that each MSI-X interrupt is handled by a + different CPU then the comp_vector parameter can be used to + spread the SRP completion workload over multiple CPU's. * tl_retry_count, a number in the range 2..7 specifying the IB RC retry count. * queue_size, the maximum number of commands that the @@ -88,6 +88,13 @@ Description: Whether ib_srp is allowed to include a partial memory descriptor list in an SRP_CMD when communicating with an SRP target. +What: /sys/class/scsi_host/host/ch_count +Date: April 1, 2015 +KernelVersion: 3.19 +Contact: linux-rdma@vger.kernel.org +Description: Number of RDMA channels used for communication with the SRP + target. + What: /sys/class/scsi_host/host/cmd_sg_entries Date: May 19, 2011 KernelVersion: 2.6.39 @@ -95,6 +102,12 @@ Contact: linux-rdma@vger.kernel.org Description: Maximum number of data buffer descriptors that may be sent to the target in a single SRP_CMD request. +What: /sys/class/scsi_host/host/comp_vector +Date: September 2, 2013 +KernelVersion: 3.11 +Contact: linux-rdma@vger.kernel.org +Description: Completion vector used for the first RDMA channel. + What: /sys/class/scsi_host/host/dgid Date: June 17, 2006 KernelVersion: 2.6.17 diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 42af59f3c8c..aac844a6eef 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -123,6 +123,11 @@ MODULE_PARM_DESC(dev_loss_tmo, " if fast_io_fail_tmo has not been set. \"off\" means that" " this functionality is disabled."); +static unsigned ch_count; +module_param(ch_count, uint, 0444); +MODULE_PARM_DESC(ch_count, + "Number of RDMA channels to use for communication with an SRP target. Using more than one channel improves performance if the HCA supports multiple completion vectors. The default value is the minimum of four times the number of online CPU sockets and the number of completion vectors supported by the HCA."); + static void srp_add_one(struct ib_device *device); static void srp_remove_one(struct ib_device *device); static void srp_recv_completion(struct ib_cq *cq, void *ch_ptr); @@ -562,11 +567,18 @@ static void srp_free_ch_ib(struct srp_target_port *target, struct srp_device *dev = target->srp_host->srp_dev; int i; + if (!ch->target) + return; + if (ch->cm_id) { ib_destroy_cm_id(ch->cm_id); ch->cm_id = NULL; } + /* If srp_new_cm_id() succeeded but srp_create_ch_ib() not, return. */ + if (!ch->qp) + return; + if (dev->use_fast_reg) { if (ch->fr_pool) srp_destroy_fr_pool(ch->fr_pool); @@ -578,6 +590,14 @@ static void srp_free_ch_ib(struct srp_target_port *target, ib_destroy_cq(ch->send_cq); ib_destroy_cq(ch->recv_cq); + /* + * Avoid that the SCSI error handler tries to use this channel after + * it has been freed. The SCSI error handler can namely continue + * trying to perform recovery actions after scsi_remove_host() + * returned. + */ + ch->target = NULL; + ch->qp = NULL; ch->send_cq = ch->recv_cq = NULL; @@ -647,7 +667,7 @@ static int srp_lookup_path(struct srp_rdma_ch *ch) return ch->status; } -static int srp_send_req(struct srp_rdma_ch *ch) +static int srp_send_req(struct srp_rdma_ch *ch, bool multich) { struct srp_target_port *target = ch->target; struct { @@ -688,6 +708,8 @@ static int srp_send_req(struct srp_rdma_ch *ch) req->priv.req_it_iu_len = cpu_to_be32(target->max_iu_len); req->priv.req_buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT); + req->priv.req_flags = (multich ? SRP_MULTICHAN_MULTI : + SRP_MULTICHAN_SINGLE); /* * In the published SRP specification (draft rev. 16a), the * port identifier format is 8 bytes of ID extension followed @@ -769,14 +791,18 @@ static bool srp_change_conn_state(struct srp_target_port *target, static void srp_disconnect_target(struct srp_target_port *target) { - struct srp_rdma_ch *ch = &target->ch; + struct srp_rdma_ch *ch; + int i; if (srp_change_conn_state(target, false)) { /* XXX should send SRP_I_LOGOUT request */ - if (ib_send_cm_dreq(ch->cm_id, NULL, 0)) { - shost_printk(KERN_DEBUG, target->scsi_host, - PFX "Sending CM DREQ failed\n"); + for (i = 0; i < target->ch_count; i++) { + ch = &target->ch[i]; + if (ch->cm_id && ib_send_cm_dreq(ch->cm_id, NULL, 0)) { + shost_printk(KERN_DEBUG, target->scsi_host, + PFX "Sending CM DREQ failed\n"); + } } } } @@ -789,7 +815,7 @@ static void srp_free_req_data(struct srp_target_port *target, struct srp_request *req; int i; - if (!ch->req_ring) + if (!ch->target || !ch->req_ring) return; for (i = 0; i < target->req_ring_size; ++i) { @@ -875,7 +901,8 @@ static void srp_del_scsi_host_attr(struct Scsi_Host *shost) static void srp_remove_target(struct srp_target_port *target) { - struct srp_rdma_ch *ch = &target->ch; + struct srp_rdma_ch *ch; + int i; WARN_ON_ONCE(target->state != SRP_TARGET_REMOVED); @@ -885,10 +912,18 @@ static void srp_remove_target(struct srp_target_port *target) scsi_remove_host(target->scsi_host); srp_stop_rport_timers(target->rport); srp_disconnect_target(target); - srp_free_ch_ib(target, ch); + for (i = 0; i < target->ch_count; i++) { + ch = &target->ch[i]; + srp_free_ch_ib(target, ch); + } cancel_work_sync(&target->tl_err_work); srp_rport_put(target->rport); - srp_free_req_data(target, ch); + for (i = 0; i < target->ch_count; i++) { + ch = &target->ch[i]; + srp_free_req_data(target, ch); + } + kfree(target->ch); + target->ch = NULL; spin_lock(&target->srp_host->target_lock); list_del(&target->list); @@ -914,12 +949,12 @@ static void srp_rport_delete(struct srp_rport *rport) srp_queue_remove_work(target); } -static int srp_connect_ch(struct srp_rdma_ch *ch) +static int srp_connect_ch(struct srp_rdma_ch *ch, bool multich) { struct srp_target_port *target = ch->target; int ret; - WARN_ON_ONCE(target->connected); + WARN_ON_ONCE(!multich && target->connected); target->qp_in_error = false; @@ -929,7 +964,7 @@ static int srp_connect_ch(struct srp_rdma_ch *ch) while (1) { init_completion(&ch->done); - ret = srp_send_req(ch); + ret = srp_send_req(ch, multich); if (ret) return ret; ret = wait_for_completion_interruptible(&ch->done); @@ -1090,10 +1125,10 @@ static void srp_finish_req(struct srp_rdma_ch *ch, struct srp_request *req, static void srp_terminate_io(struct srp_rport *rport) { struct srp_target_port *target = rport->lld_data; - struct srp_rdma_ch *ch = &target->ch; + struct srp_rdma_ch *ch; struct Scsi_Host *shost = target->scsi_host; struct scsi_device *sdev; - int i; + int i, j; /* * Invoking srp_terminate_io() while srp_queuecommand() is running @@ -1102,10 +1137,15 @@ static void srp_terminate_io(struct srp_rport *rport) shost_for_each_device(sdev, shost) WARN_ON_ONCE(sdev->request_queue->request_fn_active); - for (i = 0; i < target->req_ring_size; ++i) { - struct srp_request *req = &ch->req_ring[i]; + for (i = 0; i < target->ch_count; i++) { + ch = &target->ch[i]; - srp_finish_req(ch, req, NULL, DID_TRANSPORT_FAILFAST << 16); + for (j = 0; j < target->req_ring_size; ++j) { + struct srp_request *req = &ch->req_ring[j]; + + srp_finish_req(ch, req, NULL, + DID_TRANSPORT_FAILFAST << 16); + } } } @@ -1121,8 +1161,9 @@ static void srp_terminate_io(struct srp_rport *rport) static int srp_rport_reconnect(struct srp_rport *rport) { struct srp_target_port *target = rport->lld_data; - struct srp_rdma_ch *ch = &target->ch; - int i, ret; + struct srp_rdma_ch *ch; + int i, j, ret = 0; + bool multich = false; srp_disconnect_target(target); @@ -1134,27 +1175,47 @@ static int srp_rport_reconnect(struct srp_rport *rport) * case things are really fouled up. Doing so also ensures that all CM * callbacks will have finished before a new QP is allocated. */ - ret = srp_new_cm_id(ch); - - for (i = 0; i < target->req_ring_size; ++i) { - struct srp_request *req = &ch->req_ring[i]; - - srp_finish_req(ch, req, NULL, DID_RESET << 16); + for (i = 0; i < target->ch_count; i++) { + ch = &target->ch[i]; + if (!ch->target) + break; + ret += srp_new_cm_id(ch); } + for (i = 0; i < target->ch_count; i++) { + ch = &target->ch[i]; + if (!ch->target) + break; + for (j = 0; j < target->req_ring_size; ++j) { + struct srp_request *req = &ch->req_ring[j]; - /* - * Whether or not creating a new CM ID succeeded, create a new - * QP. This guarantees that all callback functions for the old QP have - * finished before any send requests are posted on the new QP. - */ - ret += srp_create_ch_ib(ch); - - INIT_LIST_HEAD(&ch->free_tx); - for (i = 0; i < target->queue_size; ++i) - list_add(&ch->tx_ring[i]->list, &ch->free_tx); + srp_finish_req(ch, req, NULL, DID_RESET << 16); + } + } + for (i = 0; i < target->ch_count; i++) { + ch = &target->ch[i]; + if (!ch->target) + break; + /* + * Whether or not creating a new CM ID succeeded, create a new + * QP. This guarantees that all completion callback function + * invocations have finished before request resetting starts. + */ + ret += srp_create_ch_ib(ch); - if (ret == 0) - ret = srp_connect_ch(ch); + INIT_LIST_HEAD(&ch->free_tx); + for (j = 0; j < target->queue_size; ++j) + list_add(&ch->tx_ring[j]->list, &ch->free_tx); + } + for (i = 0; i < target->ch_count; i++) { + ch = &target->ch[i]; + if (ret || !ch->target) { + if (i > 1) + ret = 0; + break; + } + ret = srp_connect_ch(ch, multich); + multich = true; + } if (ret == 0) shost_printk(KERN_INFO, target->scsi_host, @@ -1650,8 +1711,8 @@ static void srp_process_rsp(struct srp_rdma_ch *ch, struct srp_rsp *rsp) } if (!scmnd) { shost_printk(KERN_ERR, target->scsi_host, - "Null scmnd for RSP w/tag %016llx\n", - (unsigned long long) rsp->tag); + "Null scmnd for RSP w/tag %#016llx received on ch %td / QP %#x\n", + rsp->tag, ch - target->ch, ch->qp->qp_num); spin_lock_irqsave(&ch->lock, flags); ch->req_lim += be32_to_cpu(rsp->req_lim_delta); @@ -1907,7 +1968,7 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd) WARN_ON_ONCE(scmnd->request->tag < 0); tag = blk_mq_unique_tag(scmnd->request); - ch = &target->ch; + ch = &target->ch[blk_mq_unique_tag_to_hwq(tag)]; idx = blk_mq_unique_tag_to_tag(tag); WARN_ONCE(idx >= target->req_ring_size, "%s: tag %#x: idx %d >= %d\n", dev_name(&shost->shost_gendev), tag, idx, @@ -2387,15 +2448,23 @@ static int srp_abort(struct scsi_cmnd *scmnd) struct srp_target_port *target = host_to_target(scmnd->device->host); struct srp_request *req = (struct srp_request *) scmnd->host_scribble; u32 tag; + u16 ch_idx; struct srp_rdma_ch *ch; int ret; shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); - ch = &target->ch; - if (!req || !srp_claim_req(ch, req, NULL, scmnd)) + if (!req) return SUCCESS; tag = blk_mq_unique_tag(scmnd->request); + ch_idx = blk_mq_unique_tag_to_hwq(tag); + if (WARN_ON_ONCE(ch_idx >= target->ch_count)) + return SUCCESS; + ch = &target->ch[ch_idx]; + if (!srp_claim_req(ch, req, NULL, scmnd)) + return SUCCESS; + shost_printk(KERN_ERR, target->scsi_host, + "Sending SRP abort for tag %#x\n", tag); if (srp_send_tsk_mgmt(ch, tag, scmnd->device->lun, SRP_TSK_ABORT_TASK) == 0) ret = SUCCESS; @@ -2413,21 +2482,25 @@ static int srp_abort(struct scsi_cmnd *scmnd) static int srp_reset_device(struct scsi_cmnd *scmnd) { struct srp_target_port *target = host_to_target(scmnd->device->host); - struct srp_rdma_ch *ch = &target->ch; + struct srp_rdma_ch *ch; int i; shost_printk(KERN_ERR, target->scsi_host, "SRP reset_device called\n"); + ch = &target->ch[0]; if (srp_send_tsk_mgmt(ch, SRP_TAG_NO_REQ, scmnd->device->lun, SRP_TSK_LUN_RESET)) return FAILED; if (ch->tsk_mgmt_status) return FAILED; - for (i = 0; i < target->req_ring_size; ++i) { - struct srp_request *req = &ch->req_ring[i]; + for (i = 0; i < target->ch_count; i++) { + ch = &target->ch[i]; + for (i = 0; i < target->req_ring_size; ++i) { + struct srp_request *req = &ch->req_ring[i]; - srp_finish_req(ch, req, scmnd->device, DID_RESET << 16); + srp_finish_req(ch, req, scmnd->device, DID_RESET << 16); + } } return SUCCESS; @@ -2504,7 +2577,7 @@ static ssize_t show_dgid(struct device *dev, struct device_attribute *attr, char *buf) { struct srp_target_port *target = host_to_target(class_to_shost(dev)); - struct srp_rdma_ch *ch = &target->ch; + struct srp_rdma_ch *ch = &target->ch[0]; return sprintf(buf, "%pI6\n", ch->path.dgid.raw); } @@ -2521,8 +2594,14 @@ static ssize_t show_req_lim(struct device *dev, struct device_attribute *attr, char *buf) { struct srp_target_port *target = host_to_target(class_to_shost(dev)); + struct srp_rdma_ch *ch; + int i, req_lim = INT_MAX; - return sprintf(buf, "%d\n", target->ch.req_lim); + for (i = 0; i < target->ch_count; i++) { + ch = &target->ch[i]; + req_lim = min(req_lim, ch->req_lim); + } + return sprintf(buf, "%d\n", req_lim); } static ssize_t show_zero_req_lim(struct device *dev, @@ -2549,6 +2628,14 @@ static ssize_t show_local_ib_device(struct device *dev, return sprintf(buf, "%s\n", target->srp_host->srp_dev->dev->name); } +static ssize_t show_ch_count(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct srp_target_port *target = host_to_target(class_to_shost(dev)); + + return sprintf(buf, "%d\n", target->ch_count); +} + static ssize_t show_comp_vector(struct device *dev, struct device_attribute *attr, char *buf) { @@ -2592,6 +2679,7 @@ static DEVICE_ATTR(req_lim, S_IRUGO, show_req_lim, NULL); static DEVICE_ATTR(zero_req_lim, S_IRUGO, show_zero_req_lim, NULL); static DEVICE_ATTR(local_ib_port, S_IRUGO, show_local_ib_port, NULL); static DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL); +static DEVICE_ATTR(ch_count, S_IRUGO, show_ch_count, NULL); static DEVICE_ATTR(comp_vector, S_IRUGO, show_comp_vector, NULL); static DEVICE_ATTR(tl_retry_count, S_IRUGO, show_tl_retry_count, NULL); static DEVICE_ATTR(cmd_sg_entries, S_IRUGO, show_cmd_sg_entries, NULL); @@ -2609,6 +2697,7 @@ static struct device_attribute *srp_host_attrs[] = { &dev_attr_zero_req_lim, &dev_attr_local_ib_port, &dev_attr_local_ib_device, + &dev_attr_ch_count, &dev_attr_comp_vector, &dev_attr_tl_retry_count, &dev_attr_cmd_sg_entries, @@ -3018,7 +3107,8 @@ static ssize_t srp_create_target(struct device *dev, struct srp_rdma_ch *ch; struct srp_device *srp_dev = host->srp_dev; struct ib_device *ibdev = srp_dev->dev; - int ret; + int ret, node_idx, node, cpu, i; + bool multich = false; target_host = scsi_host_alloc(&srp_template, sizeof (struct srp_target_port)); @@ -3088,34 +3178,82 @@ static ssize_t srp_create_target(struct device *dev, INIT_WORK(&target->tl_err_work, srp_tl_err_work); INIT_WORK(&target->remove_work, srp_remove_work); spin_lock_init(&target->lock); - ch = &target->ch; - ch->target = target; - ch->comp_vector = target->comp_vector; - spin_lock_init(&ch->lock); - INIT_LIST_HEAD(&ch->free_tx); - ret = srp_alloc_req_data(ch); - if (ret) - goto err_free_mem; - ret = ib_query_gid(ibdev, host->port, 0, &target->sgid); if (ret) - goto err_free_mem; + goto err; - ret = srp_create_ch_ib(ch); - if (ret) - goto err_free_mem; + ret = -ENOMEM; + target->ch_count = max_t(unsigned, num_online_nodes(), + min(ch_count ? : + min(4 * num_online_nodes(), + ibdev->num_comp_vectors), + num_online_cpus())); + target->ch = kcalloc(target->ch_count, sizeof(*target->ch), + GFP_KERNEL); + if (!target->ch) + goto err; - ret = srp_new_cm_id(ch); - if (ret) - goto err_free_ib; + node_idx = 0; + for_each_online_node(node) { + const int ch_start = (node_idx * target->ch_count / + num_online_nodes()); + const int ch_end = ((node_idx + 1) * target->ch_count / + num_online_nodes()); + const int cv_start = (node_idx * ibdev->num_comp_vectors / + num_online_nodes() + target->comp_vector) + % ibdev->num_comp_vectors; + const int cv_end = ((node_idx + 1) * ibdev->num_comp_vectors / + num_online_nodes() + target->comp_vector) + % ibdev->num_comp_vectors; + int cpu_idx = 0; + + for_each_online_cpu(cpu) { + if (cpu_to_node(cpu) != node) + continue; + if (ch_start + cpu_idx >= ch_end) + continue; + ch = &target->ch[ch_start + cpu_idx]; + ch->target = target; + ch->comp_vector = cv_start == cv_end ? cv_start : + cv_start + cpu_idx % (cv_end - cv_start); + spin_lock_init(&ch->lock); + INIT_LIST_HEAD(&ch->free_tx); + ret = srp_new_cm_id(ch); + if (ret) + goto err_disconnect; - ret = srp_connect_ch(ch); - if (ret) { - shost_printk(KERN_ERR, target->scsi_host, - PFX "Connection failed\n"); - goto err_free_ib; + ret = srp_create_ch_ib(ch); + if (ret) + goto err_disconnect; + + ret = srp_alloc_req_data(ch); + if (ret) + goto err_disconnect; + + ret = srp_connect_ch(ch, multich); + if (ret) { + shost_printk(KERN_ERR, target->scsi_host, + PFX "Connection %d/%d failed\n", + ch_start + cpu_idx, + target->ch_count); + if (node_idx == 0 && cpu_idx == 0) { + goto err_disconnect; + } else { + srp_free_ch_ib(target, ch); + srp_free_req_data(target, ch); + target->ch_count = ch - target->ch; + break; + } + } + + multich = true; + cpu_idx++; + } + node_idx++; } + target->scsi_host->nr_hw_queues = target->ch_count; + ret = srp_add_target(host, target); if (ret) goto err_disconnect; @@ -3142,11 +3280,13 @@ out: err_disconnect: srp_disconnect_target(target); -err_free_ib: - srp_free_ch_ib(target, ch); + for (i = 0; i < target->ch_count; i++) { + ch = &target->ch[i]; + srp_free_ch_ib(target, ch); + srp_free_req_data(target, ch); + } -err_free_mem: - srp_free_req_data(target, ch); + kfree(target->ch); err: scsi_host_put(target_host); diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index 37aa9f49947..ca7c6f06543 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h @@ -179,8 +179,9 @@ struct srp_target_port { /* read and written in the hot path */ spinlock_t lock; - struct srp_rdma_ch ch; /* read only in the hot path */ + struct srp_rdma_ch *ch; + u32 ch_count; u32 lkey; u32 rkey; enum srp_target_state state; -- cgit v1.2.3-70-g09d2 From 7dad6b2e440d810273946b0e7092a8fe043c3b8a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 21 Oct 2014 18:00:35 +0200 Subject: IB/srp: Fix a race condition triggered by destroying a queue pair At least LID reassignment can trigger a race condition in the SRP initiator driver, namely the receive completion handler trying to post a request on a QP during or after QP destruction and before the CQ's have been destroyed. Avoid this race by modifying a QP into the error state and by waiting until all receive completions have been processed before destroying a QP. Reported-by: Max Gurtuvoy Signed-off-by: Bart Van Assche Reviewed-by: Sagi Grimberg Signed-off-by: Christoph Hellwig --- drivers/infiniband/ulp/srp/ib_srp.c | 59 +++++++++++++++++++++++++++++++------ drivers/infiniband/ulp/srp/ib_srp.h | 2 ++ 2 files changed, 52 insertions(+), 9 deletions(-) (limited to 'drivers/infiniband') diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index aac844a6eef..57b5ff1bbcb 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -453,6 +453,41 @@ static struct srp_fr_pool *srp_alloc_fr_pool(struct srp_target_port *target) dev->max_pages_per_mr); } +/** + * srp_destroy_qp() - destroy an RDMA queue pair + * @ch: SRP RDMA channel. + * + * Change a queue pair into the error state and wait until all receive + * completions have been processed before destroying it. This avoids that + * the receive completion handler can access the queue pair while it is + * being destroyed. + */ +static void srp_destroy_qp(struct srp_rdma_ch *ch) +{ + struct srp_target_port *target = ch->target; + static struct ib_qp_attr attr = { .qp_state = IB_QPS_ERR }; + static struct ib_recv_wr wr = { .wr_id = SRP_LAST_WR_ID }; + struct ib_recv_wr *bad_wr; + int ret; + + /* Destroying a QP and reusing ch->done is only safe if not connected */ + WARN_ON_ONCE(target->connected); + + ret = ib_modify_qp(ch->qp, &attr, IB_QP_STATE); + WARN_ONCE(ret, "ib_cm_init_qp_attr() returned %d\n", ret); + if (ret) + goto out; + + init_completion(&ch->done); + ret = ib_post_recv(ch->qp, &wr, &bad_wr); + WARN_ONCE(ret, "ib_post_recv() returned %d\n", ret); + if (ret == 0) + wait_for_completion(&ch->done); + +out: + ib_destroy_qp(ch->qp); +} + static int srp_create_ch_ib(struct srp_rdma_ch *ch) { struct srp_target_port *target = ch->target; @@ -469,8 +504,9 @@ static int srp_create_ch_ib(struct srp_rdma_ch *ch) if (!init_attr) return -ENOMEM; + /* + 1 for SRP_LAST_WR_ID */ recv_cq = ib_create_cq(dev->dev, srp_recv_completion, NULL, ch, - target->queue_size, ch->comp_vector); + target->queue_size + 1, ch->comp_vector); if (IS_ERR(recv_cq)) { ret = PTR_ERR(recv_cq); goto err; @@ -487,7 +523,7 @@ static int srp_create_ch_ib(struct srp_rdma_ch *ch) init_attr->event_handler = srp_qp_event; init_attr->cap.max_send_wr = m * target->queue_size; - init_attr->cap.max_recv_wr = target->queue_size; + init_attr->cap.max_recv_wr = target->queue_size + 1; init_attr->cap.max_recv_sge = 1; init_attr->cap.max_send_sge = 1; init_attr->sq_sig_type = IB_SIGNAL_REQ_WR; @@ -530,7 +566,7 @@ static int srp_create_ch_ib(struct srp_rdma_ch *ch) } if (ch->qp) - ib_destroy_qp(ch->qp); + srp_destroy_qp(ch); if (ch->recv_cq) ib_destroy_cq(ch->recv_cq); if (ch->send_cq) @@ -586,7 +622,7 @@ static void srp_free_ch_ib(struct srp_target_port *target, if (ch->fmr_pool) ib_destroy_fmr_pool(ch->fmr_pool); } - ib_destroy_qp(ch->qp); + srp_destroy_qp(ch); ib_destroy_cq(ch->send_cq); ib_destroy_cq(ch->recv_cq); @@ -1883,8 +1919,15 @@ static void srp_tl_err_work(struct work_struct *work) } static void srp_handle_qp_err(u64 wr_id, enum ib_wc_status wc_status, - bool send_err, struct srp_target_port *target) + bool send_err, struct srp_rdma_ch *ch) { + struct srp_target_port *target = ch->target; + + if (wr_id == SRP_LAST_WR_ID) { + complete(&ch->done); + return; + } + if (target->connected && !target->qp_in_error) { if (wr_id & LOCAL_INV_WR_ID_MASK) { shost_printk(KERN_ERR, target->scsi_host, PFX @@ -1915,8 +1958,7 @@ static void srp_recv_completion(struct ib_cq *cq, void *ch_ptr) if (likely(wc.status == IB_WC_SUCCESS)) { srp_handle_recv(ch, &wc); } else { - srp_handle_qp_err(wc.wr_id, wc.status, false, - ch->target); + srp_handle_qp_err(wc.wr_id, wc.status, false, ch); } } } @@ -1932,8 +1974,7 @@ static void srp_send_completion(struct ib_cq *cq, void *ch_ptr) iu = (struct srp_iu *) (uintptr_t) wc.wr_id; list_add(&iu->list, &ch->free_tx); } else { - srp_handle_qp_err(wc.wr_id, wc.status, true, - ch->target); + srp_handle_qp_err(wc.wr_id, wc.status, true, ch); } } } diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index ca7c6f06543..a611556406a 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h @@ -70,6 +70,8 @@ enum { LOCAL_INV_WR_ID_MASK = 1, FAST_REG_WR_ID_MASK = 2, + + SRP_LAST_WR_ID = 0xfffffffcU, }; enum srp_target_state { -- cgit v1.2.3-70-g09d2 From c40ecc12cfdb630332198a04e2832ae8218a61f1 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 13 Nov 2014 14:25:11 +0100 Subject: scsi: avoid ->change_queue_depth indirection for queue full tracking All drivers use the implementation for ramping the queue up and down, so instead of overloading the change_queue_depth method call the implementation diretly if the driver opts into it by setting the track_queue_depth flag in the host template. Note that a few drivers validated the new queue depth in their change_queue_depth method, but as we never go over the queue depth set during slave_configure or the sysfs file this isn't nessecary and can safely be removed. Signed-off-by: Christoph Hellwig Reviewed-by: Mike Christie Reviewed-by: Hannes Reinecke Reviewed-by: Venkatesh Srinivas --- drivers/infiniband/ulp/iser/iscsi_iser.c | 1 + drivers/infiniband/ulp/srp/ib_srp.c | 20 ++++++------- drivers/s390/scsi/zfcp_scsi.c | 15 ++-------- drivers/scsi/aic94xx/aic94xx_init.c | 1 + drivers/scsi/be2iscsi/be_main.c | 2 +- drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 1 + drivers/scsi/bnx2i/bnx2i_iscsi.c | 1 + drivers/scsi/cxgbi/cxgb3i/cxgb3i.c | 1 + drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 1 + drivers/scsi/fcoe/fcoe.c | 1 + drivers/scsi/fnic/fnic_main.c | 1 + drivers/scsi/ibmvscsi/ibmvfc.c | 1 + drivers/scsi/isci/init.c | 1 + drivers/scsi/iscsi_tcp.c | 1 + drivers/scsi/libfc/fc_fcp.c | 14 +-------- drivers/scsi/libiscsi.c | 14 +-------- drivers/scsi/libsas/sas_scsi_host.c | 17 ++--------- drivers/scsi/lpfc/lpfc_scsi.c | 23 ++------------- drivers/scsi/mpt2sas/mpt2sas_scsih.c | 10 ++----- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 10 ++----- drivers/scsi/mvsas/mv_init.c | 1 + drivers/scsi/pm8001/pm8001_init.c | 1 + drivers/scsi/qla2xxx/qla_os.c | 48 ++----------------------------- drivers/scsi/qla4xxx/ql4_os.c | 16 +++-------- drivers/scsi/scsi_debug.c | 49 ++++++++------------------------ drivers/scsi/scsi_error.c | 15 ++++------ drivers/scsi/ufs/ufshcd.c | 14 ++------- drivers/scsi/virtio_scsi.c | 15 ++-------- drivers/target/loopback/tcm_loop.c | 15 ++-------- include/scsi/scsi_host.h | 7 +++-- 30 files changed, 73 insertions(+), 244 deletions(-) (limited to 'drivers/infiniband') diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index f42ab14105a..812a2891de5 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -922,6 +922,7 @@ static struct scsi_host_template iscsi_iser_sht = { .use_clustering = DISABLE_CLUSTERING, .proc_name = "iscsi_iser", .this_id = -1, + .track_queue_depth = 1, }; static struct iscsi_transport iscsi_iser_transport = { diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 57b5ff1bbcb..98a30355893 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -2402,7 +2402,7 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) * srp_change_queue_depth - setting device queue depth * @sdev: scsi device struct * @qdepth: requested queue depth - * @reason: SCSI_QDEPTH_DEFAULT/SCSI_QDEPTH_QFULL/SCSI_QDEPTH_RAMP_UP + * @reason: SCSI_QDEPTH_DEFAULT * (see include/scsi/scsi_host.h for definition) * * Returns queue depth. @@ -2412,18 +2412,13 @@ srp_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) { struct Scsi_Host *shost = sdev->host; int max_depth; - if (reason == SCSI_QDEPTH_DEFAULT || reason == SCSI_QDEPTH_RAMP_UP) { - max_depth = shost->can_queue; - if (!sdev->tagged_supported) - max_depth = 1; - if (qdepth > max_depth) - qdepth = max_depth; - scsi_adjust_queue_depth(sdev, qdepth); - } else if (reason == SCSI_QDEPTH_QFULL) - scsi_track_queue_full(sdev, qdepth); - else - return -EOPNOTSUPP; + max_depth = shost->can_queue; + if (!sdev->tagged_supported) + max_depth = 1; + if (qdepth > max_depth) + qdepth = max_depth; + scsi_adjust_queue_depth(sdev, qdepth); return sdev->queue_depth; } @@ -2766,6 +2761,7 @@ static struct scsi_host_template srp_template = { .use_clustering = ENABLE_CLUSTERING, .shost_attrs = srp_host_attrs, .use_blk_tags = 1, + .track_queue_depth = 1, }; static int srp_sdev_count(struct Scsi_Host *host) diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index b5dfa51f396..179bf3d8af6 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -35,19 +35,7 @@ MODULE_PARM_DESC(allow_lun_scan, "For NPIV, scan and attach all storage LUNs"); static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth, int reason) { - switch (reason) { - case SCSI_QDEPTH_DEFAULT: - scsi_adjust_queue_depth(sdev, depth); - break; - case SCSI_QDEPTH_QFULL: - scsi_track_queue_full(sdev, depth); - break; - case SCSI_QDEPTH_RAMP_UP: - scsi_adjust_queue_depth(sdev, depth); - break; - default: - return -EOPNOTSUPP; - } + scsi_adjust_queue_depth(sdev, depth); return sdev->queue_depth; } @@ -320,6 +308,7 @@ static struct scsi_host_template zfcp_scsi_host_template = { .use_clustering = 1, .shost_attrs = zfcp_sysfs_shost_attrs, .sdev_attrs = zfcp_sysfs_sdev_attrs, + .track_queue_depth = 1, }; /** diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 579dc2f460c..a64cf932d03 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c @@ -84,6 +84,7 @@ static struct scsi_host_template aic94xx_sht = { .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, .use_blk_tags = 1, + .track_queue_depth = 1, }; static int asd_map_memio(struct asd_ha_struct *asd_ha) diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 30d74a06b99..d9b999a3416 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -570,7 +570,7 @@ static struct scsi_host_template beiscsi_sht = { .cmd_per_lun = BEISCSI_CMD_PER_LUN, .use_clustering = ENABLE_CLUSTERING, .vendor_id = SCSI_NL_VID_TYPE_PCI | BE_VENDOR_ID, - + .track_queue_depth = 1, }; static struct scsi_transport_template *beiscsi_scsi_transport; diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 2262c75f45d..cc537972f3e 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -2792,6 +2792,7 @@ static struct scsi_host_template bnx2fc_shost_template = { .sg_tablesize = BNX2FC_MAX_BDS_PER_CMD, .max_sectors = 1024, .use_blk_tags = 1, + .track_queue_depth = 1, }; static struct libfc_function_template bnx2fc_libfc_fcn_templ = { diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index 7a36388822a..9de1c20bb0f 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -2268,6 +2268,7 @@ static struct scsi_host_template bnx2i_host_template = { .use_clustering = ENABLE_CLUSTERING, .sg_tablesize = ISCSI_MAX_BDS_PER_CMD, .shost_attrs = bnx2i_dev_attributes, + .track_queue_depth = 1, }; struct iscsi_transport bnx2i_iscsi_transport = { diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c index 49692a1ac44..99ea67dcdd2 100644 --- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c +++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c @@ -96,6 +96,7 @@ static struct scsi_host_template cxgb3i_host_template = { .target_alloc = iscsi_target_alloc, .use_clustering = DISABLE_CLUSTERING, .this_id = -1, + .track_queue_depth = 1, }; static struct iscsi_transport cxgb3i_iscsi_transport = { diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c index 81bb3bd7909..af86e8f57b8 100644 --- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c +++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c @@ -99,6 +99,7 @@ static struct scsi_host_template cxgb4i_host_template = { .target_alloc = iscsi_target_alloc, .use_clustering = DISABLE_CLUSTERING, .this_id = -1, + .track_queue_depth = 1, }; static struct iscsi_transport cxgb4i_iscsi_transport = { diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index a3eeb684249..97229860398 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -289,6 +289,7 @@ static struct scsi_host_template fcoe_shost_template = { .sg_tablesize = SG_ALL, .max_sectors = 0xffff, .use_blk_tags = 1, + .track_queue_depth = 1, }; /** diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index 1e5706ed9a4..86b496c8633 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@ -120,6 +120,7 @@ static struct scsi_host_template fnic_host_template = { .max_sectors = 0xffff, .shost_attrs = fnic_attrs, .use_blk_tags = 1, + .track_queue_depth = 1, }; static void diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 147b80e07b0..381449d5be7 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -3103,6 +3103,7 @@ static struct scsi_host_template driver_template = { .use_clustering = ENABLE_CLUSTERING, .shost_attrs = ibmvfc_attrs, .use_blk_tags = 1, + .track_queue_depth = 1, }; /** diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c index 89756205601..a81e546595d 100644 --- a/drivers/scsi/isci/init.c +++ b/drivers/scsi/isci/init.c @@ -173,6 +173,7 @@ static struct scsi_host_template isci_sht = { .ioctl = sas_ioctl, .shost_attrs = isci_host_attrs, .use_blk_tags = 1, + .track_queue_depth = 1, }; static struct sas_domain_function_template isci_transport_ops = { diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 427af0f24b0..a575d845b66 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -966,6 +966,7 @@ static struct scsi_host_template iscsi_sw_tcp_sht = { .target_alloc = iscsi_target_alloc, .proc_name = "iscsi_tcp", .this_id = -1, + .track_queue_depth = 1, }; static struct iscsi_transport iscsi_sw_tcp_transport = { diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index bf954ee050f..0d2d024e77c 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c @@ -2173,19 +2173,7 @@ EXPORT_SYMBOL(fc_slave_alloc); */ int fc_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) { - switch (reason) { - case SCSI_QDEPTH_DEFAULT: - scsi_adjust_queue_depth(sdev, qdepth); - break; - case SCSI_QDEPTH_QFULL: - scsi_track_queue_full(sdev, qdepth); - break; - case SCSI_QDEPTH_RAMP_UP: - scsi_adjust_queue_depth(sdev, qdepth); - break; - default: - return -EOPNOTSUPP; - } + scsi_adjust_queue_depth(sdev, qdepth); return sdev->queue_depth; } EXPORT_SYMBOL(fc_change_queue_depth); diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index d521624dedf..79e977484ad 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -1773,19 +1773,7 @@ EXPORT_SYMBOL_GPL(iscsi_queuecommand); int iscsi_change_queue_depth(struct scsi_device *sdev, int depth, int reason) { - switch (reason) { - case SCSI_QDEPTH_DEFAULT: - scsi_adjust_queue_depth(sdev, depth); - break; - case SCSI_QDEPTH_QFULL: - scsi_track_queue_full(sdev, depth); - break; - case SCSI_QDEPTH_RAMP_UP: - scsi_adjust_queue_depth(sdev, depth); - break; - default: - return -EOPNOTSUPP; - } + scsi_adjust_queue_depth(sdev, depth); return sdev->queue_depth; } EXPORT_SYMBOL_GPL(iscsi_change_queue_depth); diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 89e8b687a67..914e4116513 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -961,20 +961,9 @@ int sas_change_queue_depth(struct scsi_device *sdev, int depth, int reason) return __ata_change_queue_depth(dev->sata_dev.ap, sdev, depth, reason); - switch (reason) { - case SCSI_QDEPTH_DEFAULT: - case SCSI_QDEPTH_RAMP_UP: - if (!sdev->tagged_supported) - depth = 1; - scsi_adjust_queue_depth(sdev, depth); - break; - case SCSI_QDEPTH_QFULL: - scsi_track_queue_full(sdev, depth); - break; - default: - return -EOPNOTSUPP; - } - + if (!sdev->tagged_supported) + depth = 1; + scsi_adjust_queue_depth(sdev, depth); return depth; } diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 80351fff1a0..52285492036 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -255,26 +255,7 @@ lpfc_update_stats(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) static int lpfc_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) { - struct lpfc_vport *vport = (struct lpfc_vport *) sdev->host->hostdata; - - switch (reason) { - case SCSI_QDEPTH_DEFAULT: - /* change request from sysfs, fall through */ - case SCSI_QDEPTH_RAMP_UP: - scsi_adjust_queue_depth(sdev, qdepth); - break; - case SCSI_QDEPTH_QFULL: - if (scsi_track_queue_full(sdev, qdepth) == 0) - return sdev->queue_depth; - - lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, - "0711 detected queue full - lun queue " - "depth adjusted to %d.\n", sdev->queue_depth); - break; - default: - return -EOPNOTSUPP; - } - + scsi_adjust_queue_depth(sdev, qdepth); return sdev->queue_depth; } @@ -5918,6 +5899,7 @@ struct scsi_host_template lpfc_template = { .change_queue_depth = lpfc_change_queue_depth, .change_queue_type = scsi_change_queue_type, .use_blk_tags = 1, + .track_queue_depth = 1, }; struct scsi_host_template lpfc_vport_template = { @@ -5942,4 +5924,5 @@ struct scsi_host_template lpfc_vport_template = { .change_queue_depth = lpfc_change_queue_depth, .change_queue_type = scsi_change_queue_type, .use_blk_tags = 1, + .track_queue_depth = 1, }; diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 42fef914d44..b006e1e9fcb 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -1229,7 +1229,7 @@ _scsih_adjust_queue_depth(struct scsi_device *sdev, int qdepth) * _scsih_change_queue_depth - setting device queue depth * @sdev: scsi device struct * @qdepth: requested queue depth - * @reason: SCSI_QDEPTH_DEFAULT/SCSI_QDEPTH_QFULL/SCSI_QDEPTH_RAMP_UP + * @reason: SCSI_QDEPTH_DEFAULT * (see include/scsi/scsi_host.h for definition) * * Returns queue depth. @@ -1237,12 +1237,7 @@ _scsih_adjust_queue_depth(struct scsi_device *sdev, int qdepth) static int _scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) { - if (reason == SCSI_QDEPTH_DEFAULT || reason == SCSI_QDEPTH_RAMP_UP) - _scsih_adjust_queue_depth(sdev, qdepth); - else if (reason == SCSI_QDEPTH_QFULL) - scsi_track_queue_full(sdev, qdepth); - else - return -EOPNOTSUPP; + _scsih_adjust_queue_depth(sdev, qdepth); if (sdev->inquiry_len > 7) sdev_printk(KERN_INFO, sdev, "qdepth(%d), tagged(%d), " @@ -7637,6 +7632,7 @@ static struct scsi_host_template scsih_driver_template = { .use_clustering = ENABLE_CLUSTERING, .shost_attrs = mpt2sas_host_attrs, .sdev_attrs = mpt2sas_dev_attrs, + .track_queue_depth = 1, }; /** diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index b23c2e7588e..568dcaed36c 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -1097,7 +1097,7 @@ _scsih_adjust_queue_depth(struct scsi_device *sdev, int qdepth) * _scsih_change_queue_depth - setting device queue depth * @sdev: scsi device struct * @qdepth: requested queue depth - * @reason: SCSI_QDEPTH_DEFAULT/SCSI_QDEPTH_QFULL/SCSI_QDEPTH_RAMP_UP + * @reason: SCSI_QDEPTH_DEFAULT * (see include/scsi/scsi_host.h for definition) * * Returns queue depth. @@ -1105,12 +1105,7 @@ _scsih_adjust_queue_depth(struct scsi_device *sdev, int qdepth) static int _scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) { - if (reason == SCSI_QDEPTH_DEFAULT || reason == SCSI_QDEPTH_RAMP_UP) - _scsih_adjust_queue_depth(sdev, qdepth); - else if (reason == SCSI_QDEPTH_QFULL) - scsi_track_queue_full(sdev, qdepth); - else - return -EOPNOTSUPP; + _scsih_adjust_queue_depth(sdev, qdepth); if (sdev->inquiry_len > 7) sdev_printk(KERN_INFO, sdev, "qdepth(%d), tagged(%d), " \ @@ -7266,6 +7261,7 @@ static struct scsi_host_template scsih_driver_template = { .use_clustering = ENABLE_CLUSTERING, .shost_attrs = mpt3sas_host_attrs, .sdev_attrs = mpt3sas_dev_attrs, + .track_queue_depth = 1, }; /** diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index d3c1fa5e76f..ac7c0307840 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -77,6 +77,7 @@ static struct scsi_host_template mvs_sht = { .ioctl = sas_ioctl, .shost_attrs = mvst_host_attrs, .use_blk_tags = 1, + .track_queue_depth = 1, }; static struct sas_domain_function_template mvs_transport_ops = { diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 3ff759a3b74..19ae6cab5e4 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -90,6 +90,7 @@ static struct scsi_host_template pm8001_sht = { .ioctl = sas_ioctl, .shost_attrs = pm8001_host_attrs, .use_blk_tags = 1, + .track_queue_depth = 1, }; /** diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 33166ebec7d..20049b176b6 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -270,6 +270,7 @@ struct scsi_host_template qla2xxx_driver_template = { .supported_mode = MODE_INITIATOR, .use_blk_tags = 1, + .track_queue_depth = 1, }; static struct scsi_transport_template *qla2xxx_transport_template = NULL; @@ -1415,55 +1416,10 @@ qla2xxx_slave_destroy(struct scsi_device *sdev) sdev->hostdata = NULL; } -static void qla2x00_handle_queue_full(struct scsi_device *sdev, int qdepth) -{ - fc_port_t *fcport = (struct fc_port *) sdev->hostdata; - - if (!scsi_track_queue_full(sdev, qdepth)) - return; - - ql_dbg(ql_dbg_io, fcport->vha, 0x3029, - "Queue depth adjusted-down to %d for nexus=%ld:%d:%llu.\n", - sdev->queue_depth, fcport->vha->host_no, sdev->id, sdev->lun); -} - -static void qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, int qdepth) -{ - fc_port_t *fcport = sdev->hostdata; - struct scsi_qla_host *vha = fcport->vha; - struct req_que *req = NULL; - - req = vha->req; - if (!req) - return; - - if (req->max_q_depth <= sdev->queue_depth || req->max_q_depth < qdepth) - return; - - scsi_adjust_queue_depth(sdev, qdepth); - - ql_dbg(ql_dbg_io, vha, 0x302a, - "Queue depth adjusted-up to %d for nexus=%ld:%d:%llu.\n", - sdev->queue_depth, fcport->vha->host_no, sdev->id, sdev->lun); -} - static int qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) { - switch (reason) { - case SCSI_QDEPTH_DEFAULT: - scsi_adjust_queue_depth(sdev, qdepth); - break; - case SCSI_QDEPTH_QFULL: - qla2x00_handle_queue_full(sdev, qdepth); - break; - case SCSI_QDEPTH_RAMP_UP: - qla2x00_adjust_sdev_qdepth_up(sdev, qdepth); - break; - default: - return -EOPNOTSUPP; - } - + scsi_adjust_queue_depth(sdev, qdepth); return sdev->queue_depth; } diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index f8724f2e015..2bfde373ea2 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -164,8 +164,6 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd); static int qla4xxx_slave_alloc(struct scsi_device *device); static umode_t qla4_attr_is_visible(int param_type, int param); static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type); -static int qla4xxx_change_queue_depth(struct scsi_device *sdev, int qdepth, - int reason); /* * iSCSI Flash DDB sysfs entry points @@ -203,7 +201,7 @@ static struct scsi_host_template qla4xxx_driver_template = { .eh_timed_out = qla4xxx_eh_cmd_timed_out, .slave_alloc = qla4xxx_slave_alloc, - .change_queue_depth = qla4xxx_change_queue_depth, + .change_queue_depth = iscsi_change_queue_depth, .this_id = -1, .cmd_per_lun = 3, @@ -9065,15 +9063,6 @@ static int qla4xxx_slave_alloc(struct scsi_device *sdev) return 0; } -static int qla4xxx_change_queue_depth(struct scsi_device *sdev, int qdepth, - int reason) -{ - if (!ql4xqfulltracking) - return -EOPNOTSUPP; - - return iscsi_change_queue_depth(sdev, qdepth, reason); -} - /** * qla4xxx_del_from_active_array - returns an active srb * @ha: Pointer to host adapter structure. @@ -9873,6 +9862,9 @@ static int __init qla4xxx_module_init(void) { int ret; + if (ql4xqfulltracking) + qla4xxx_driver_template.track_queue_depth = 1; + /* Allocate cache for SRBs. */ srb_cachep = kmem_cache_create("qla4xxx_srbs", sizeof(struct srb), 0, SLAB_HWCACHE_ALIGN, NULL); diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index fce393f3e7e..84cf82e0782 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -4472,7 +4472,6 @@ static int sdebug_change_qdepth(struct scsi_device *sdev, int qdepth, int reason) { int num_in_q = 0; - int bad = 0; unsigned long iflags; struct sdebug_dev_info *devip; @@ -4484,43 +4483,18 @@ sdebug_change_qdepth(struct scsi_device *sdev, int qdepth, int reason) } num_in_q = atomic_read(&devip->num_in_q); spin_unlock_irqrestore(&queued_arr_lock, iflags); - if (reason == SCSI_QDEPTH_DEFAULT || reason == SCSI_QDEPTH_RAMP_UP) { - if (qdepth < 1) - qdepth = 1; - /* allow to exceed max host queued_arr elements for testing */ - if (qdepth > SCSI_DEBUG_CANQUEUE + 10) - qdepth = SCSI_DEBUG_CANQUEUE + 10; - scsi_adjust_queue_depth(sdev, qdepth); - } else if (reason == SCSI_QDEPTH_QFULL) - scsi_track_queue_full(sdev, qdepth); - else - bad = 1; - if (bad) - sdev_printk(KERN_WARNING, sdev, - "%s: unknown reason=0x%x\n", __func__, reason); + + if (qdepth < 1) + qdepth = 1; + /* allow to exceed max host queued_arr elements for testing */ + if (qdepth > SCSI_DEBUG_CANQUEUE + 10) + qdepth = SCSI_DEBUG_CANQUEUE + 10; + scsi_adjust_queue_depth(sdev, qdepth); + if (SCSI_DEBUG_OPT_Q_NOISE & scsi_debug_opts) { - if (SCSI_QDEPTH_QFULL == reason) - sdev_printk(KERN_INFO, sdev, - "%s: -> %d, num_in_q=%d, reason: queue full\n", - __func__, qdepth, num_in_q); - else { - const char *cp; - - switch (reason) { - case SCSI_QDEPTH_DEFAULT: - cp = "default (sysfs ?)"; - break; - case SCSI_QDEPTH_RAMP_UP: - cp = "ramp up"; - break; - default: - cp = "unknown"; - break; - } - sdev_printk(KERN_INFO, sdev, - "%s: qdepth=%d, num_in_q=%d, reason: %s\n", - __func__, qdepth, num_in_q, cp); - } + sdev_printk(KERN_INFO, sdev, + "%s: qdepth=%d, num_in_q=%d\n", + __func__, qdepth, num_in_q); } return sdev->queue_depth; } @@ -4576,6 +4550,7 @@ static struct scsi_host_template sdebug_driver_template = { .max_sectors = -1U, .use_clustering = DISABLE_CLUSTERING, .module = THIS_MODULE, + .track_queue_depth = 1, }; static int sdebug_driver_probe(struct device * dev) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index a6f6b9222b5..2d0f5155ee5 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -610,7 +610,7 @@ static void scsi_handle_queue_ramp_up(struct scsi_device *sdev) struct scsi_host_template *sht = sdev->host->hostt; struct scsi_device *tmp_sdev; - if (!sht->change_queue_depth || + if (!sht->track_queue_depth || sdev->queue_depth >= sdev->max_queue_depth) return; @@ -631,12 +631,8 @@ static void scsi_handle_queue_ramp_up(struct scsi_device *sdev) tmp_sdev->id != sdev->id || tmp_sdev->queue_depth == sdev->max_queue_depth) continue; - /* - * call back into LLD to increase queue_depth by one - * with ramp up reason code. - */ - sht->change_queue_depth(tmp_sdev, tmp_sdev->queue_depth + 1, - SCSI_QDEPTH_RAMP_UP); + + scsi_adjust_queue_depth(tmp_sdev, tmp_sdev->queue_depth + 1); sdev->last_queue_ramp_up = jiffies; } } @@ -646,7 +642,7 @@ static void scsi_handle_queue_full(struct scsi_device *sdev) struct scsi_host_template *sht = sdev->host->hostt; struct scsi_device *tmp_sdev; - if (!sht->change_queue_depth) + if (!sht->track_queue_depth) return; shost_for_each_device(tmp_sdev, sdev->host) { @@ -658,8 +654,7 @@ static void scsi_handle_queue_full(struct scsi_device *sdev) * the device when we got the queue full so we start * from the highest possible value and work our way down. */ - sht->change_queue_depth(tmp_sdev, tmp_sdev->queue_depth - 1, - SCSI_QDEPTH_QFULL); + scsi_track_queue_full(tmp_sdev, tmp_sdev->queue_depth - 1); } } diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 362b818ad82..e96ab253e3e 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2800,18 +2800,7 @@ static int ufshcd_change_queue_depth(struct scsi_device *sdev, if (depth > hba->nutrs) depth = hba->nutrs; - switch (reason) { - case SCSI_QDEPTH_DEFAULT: - case SCSI_QDEPTH_RAMP_UP: - scsi_adjust_queue_depth(sdev, depth); - break; - case SCSI_QDEPTH_QFULL: - scsi_track_queue_full(sdev, depth); - break; - default: - return -EOPNOTSUPP; - } - + scsi_adjust_queue_depth(sdev, depth); return depth; } @@ -4231,6 +4220,7 @@ static struct scsi_host_template ufshcd_driver_template = { .can_queue = UFSHCD_CAN_QUEUE, .max_host_blocked = 1, .use_blk_tags = 1, + .track_queue_depth = 1, }; static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg, diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 8e40347da0a..0f7e4c7ff8c 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -691,18 +691,7 @@ static int virtscsi_change_queue_depth(struct scsi_device *sdev, struct Scsi_Host *shost = sdev->host; int max_depth = shost->cmd_per_lun; - switch (reason) { - case SCSI_QDEPTH_QFULL: /* Drop qdepth in response to BUSY state */ - scsi_track_queue_full(sdev, qdepth); - break; - case SCSI_QDEPTH_RAMP_UP: /* Raise qdepth after BUSY state resolved */ - case SCSI_QDEPTH_DEFAULT: /* Manual change via sysfs */ - scsi_adjust_queue_depth(sdev, min(max_depth, qdepth)); - break; - default: - return -EOPNOTSUPP; - } - + scsi_adjust_queue_depth(sdev, min(max_depth, qdepth)); return sdev->queue_depth; } @@ -770,6 +759,7 @@ static struct scsi_host_template virtscsi_host_template_single = { .use_clustering = ENABLE_CLUSTERING, .target_alloc = virtscsi_target_alloc, .target_destroy = virtscsi_target_destroy, + .track_queue_depth = 1, }; static struct scsi_host_template virtscsi_host_template_multi = { @@ -788,6 +778,7 @@ static struct scsi_host_template virtscsi_host_template_multi = { .use_clustering = ENABLE_CLUSTERING, .target_alloc = virtscsi_target_alloc, .target_destroy = virtscsi_target_destroy, + .track_queue_depth = 1, }; #define virtscsi_config_get(vdev, fld) \ diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 0ed96644ec9..670b75a6224 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -119,19 +119,7 @@ static int tcm_loop_change_queue_depth( int depth, int reason) { - switch (reason) { - case SCSI_QDEPTH_DEFAULT: - scsi_adjust_queue_depth(sdev, depth); - break; - case SCSI_QDEPTH_QFULL: - scsi_track_queue_full(sdev, depth); - break; - case SCSI_QDEPTH_RAMP_UP: - scsi_adjust_queue_depth(sdev, depth); - break; - default: - return -EOPNOTSUPP; - } + scsi_adjust_queue_depth(sdev, depth); return sdev->queue_depth; } @@ -423,6 +411,7 @@ static struct scsi_host_template tcm_loop_driver_template = { .slave_alloc = tcm_loop_slave_alloc, .module = THIS_MODULE, .use_blk_tags = 1, + .track_queue_depth = 1, }; static int tcm_loop_driver_probe(struct device *dev) diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 61a81bf77e2..a0b13a5cd25 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -48,8 +48,6 @@ struct blk_queue_tags; enum { SCSI_QDEPTH_DEFAULT, /* default requested change, e.g. from sysfs */ - SCSI_QDEPTH_QFULL, /* scsi-ml requested due to queue full */ - SCSI_QDEPTH_RAMP_UP, /* scsi-ml requested due to threshold event */ }; struct scsi_host_template { @@ -426,6 +424,11 @@ struct scsi_host_template { */ unsigned use_blk_tags:1; + /* + * Track QUEUE_FULL events and reduce queue depth on demand. + */ + unsigned track_queue_depth:1; + /* * This specifies the mode that a LLD supports. */ -- cgit v1.2.3-70-g09d2 From 1e6f2416044c062a56091ebf8d76760956dd5872 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 13 Nov 2014 14:27:41 +0100 Subject: scsi: don't allow setting of queue_depth bigger than can_queue We won't ever queue more commands than the host allows. Instead of letting drivers either reject or ignore this case handle it in common code. Note that various driver use internal constant or variables that are assigned to both shost->can_queue and checked in ->change_queue_depth - I did remove those checks as well. Signed-off-by: Christoph Hellwig Reviewed-by: Mike Christie Reviewed-by: Hannes Reinecke --- drivers/infiniband/ulp/srp/ib_srp.c | 8 +------- drivers/scsi/3w-9xxx.c | 2 -- drivers/scsi/3w-sas.c | 2 -- drivers/scsi/3w-xxxx.c | 2 -- drivers/scsi/hpsa.c | 5 ----- drivers/scsi/megaraid/megaraid_mbox.c | 2 -- drivers/scsi/megaraid/megaraid_sas_base.c | 2 -- drivers/scsi/scsi_sysfs.c | 2 +- drivers/scsi/vmw_pvscsi.c | 8 +------- 9 files changed, 3 insertions(+), 30 deletions(-) (limited to 'drivers/infiniband') diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 98a30355893..8d13a19e04b 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -2410,14 +2410,8 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) static int srp_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) { - struct Scsi_Host *shost = sdev->host; - int max_depth; - - max_depth = shost->can_queue; if (!sdev->tagged_supported) - max_depth = 1; - if (qdepth > max_depth) - qdepth = max_depth; + qdepth = 1; scsi_adjust_queue_depth(sdev, qdepth); return sdev->queue_depth; } diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 02021f5ca86..1cf37032290 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -196,8 +196,6 @@ static int twa_change_queue_depth(struct scsi_device *sdev, int queue_depth, if (reason != SCSI_QDEPTH_DEFAULT) return -EOPNOTSUPP; - if (queue_depth > TW_Q_LENGTH-2) - queue_depth = TW_Q_LENGTH-2; scsi_adjust_queue_depth(sdev, queue_depth); return queue_depth; } /* End twa_change_queue_depth() */ diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c index ac0c2544a47..547756b7d5b 100644 --- a/drivers/scsi/3w-sas.c +++ b/drivers/scsi/3w-sas.c @@ -198,8 +198,6 @@ static int twl_change_queue_depth(struct scsi_device *sdev, int queue_depth, if (reason != SCSI_QDEPTH_DEFAULT) return -EOPNOTSUPP; - if (queue_depth > TW_Q_LENGTH-2) - queue_depth = TW_Q_LENGTH-2; scsi_adjust_queue_depth(sdev, queue_depth); return queue_depth; } /* End twl_change_queue_depth() */ diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index 1ec9ad92b6c..261a4c1da96 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -530,8 +530,6 @@ static int tw_change_queue_depth(struct scsi_device *sdev, int queue_depth, if (reason != SCSI_QDEPTH_DEFAULT) return -EOPNOTSUPP; - if (queue_depth > TW_Q_LENGTH-2) - queue_depth = TW_Q_LENGTH-2; scsi_adjust_queue_depth(sdev, queue_depth); return queue_depth; } /* End tw_change_queue_depth() */ diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 3569f420194..617f218e2a1 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -4082,11 +4082,6 @@ static int hpsa_change_queue_depth(struct scsi_device *sdev, if (reason != SCSI_QDEPTH_DEFAULT) return -ENOTSUPP; - if (qdepth < 1) - qdepth = 1; - else - if (qdepth > h->nr_cmds) - qdepth = h->nr_cmds; scsi_adjust_queue_depth(sdev, qdepth); return sdev->queue_depth; } diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index 6b077d839f2..d56eb9d3d40 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -347,8 +347,6 @@ static int megaraid_change_queue_depth(struct scsi_device *sdev, int qdepth, if (reason != SCSI_QDEPTH_DEFAULT) return -EOPNOTSUPP; - if (qdepth > MBOX_MAX_SCSI_CMDS) - qdepth = MBOX_MAX_SCSI_CMDS; scsi_adjust_queue_depth(sdev, qdepth); return sdev->queue_depth; } diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 3ccfbec682d..69a9dd6ae04 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -2597,8 +2597,6 @@ static int megasas_change_queue_depth(struct scsi_device *sdev, if (reason != SCSI_QDEPTH_DEFAULT) return -EOPNOTSUPP; - if (queue_depth > sdev->host->can_queue) - queue_depth = sdev->host->can_queue; scsi_adjust_queue_depth(sdev, queue_depth); return queue_depth; diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 35d93b0af82..bffd5abdcd1 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -877,7 +877,7 @@ sdev_store_queue_depth(struct device *dev, struct device_attribute *attr, depth = simple_strtoul(buf, NULL, 0); - if (depth < 1) + if (depth < 1 || depth > sht->can_queue) return -EINVAL; retval = sht->change_queue_depth(sdev, depth, diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c index 4a01c0598a2..03ad24be728 100644 --- a/drivers/scsi/vmw_pvscsi.c +++ b/drivers/scsi/vmw_pvscsi.c @@ -508,20 +508,14 @@ static int pvscsi_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) { - int max_depth; - struct Scsi_Host *shost = sdev->host; - if (reason != SCSI_QDEPTH_DEFAULT) /* * We support only changing default. */ return -EOPNOTSUPP; - max_depth = shost->can_queue; if (!sdev->tagged_supported) - max_depth = 1; - if (qdepth > max_depth) - qdepth = max_depth; + qdepth = 1; scsi_adjust_queue_depth(sdev, qdepth); if (sdev->inquiry_len > 7) -- cgit v1.2.3-70-g09d2 From db5ed4dfd5dd0142ec36ff7b335e0ec3b836b3e6 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 13 Nov 2014 15:08:42 +0100 Subject: scsi: drop reason argument from ->change_queue_depth Drop the now unused reason argument from the ->change_queue_depth method. Also add a return value to scsi_adjust_queue_depth, and rename it to scsi_change_queue_depth now that it can be used as the default ->change_queue_depth implementation. Signed-off-by: Christoph Hellwig Reviewed-by: Mike Christie Reviewed-by: Hannes Reinecke --- Documentation/scsi/scsi_mid_low_api.txt | 20 +++++++-------- drivers/ata/libata-scsi.c | 17 ++++--------- drivers/ata/sata_nv.c | 2 +- drivers/infiniband/ulp/iser/iscsi_iser.c | 2 +- drivers/infiniband/ulp/srp/ib_srp.c | 7 ++---- drivers/message/fusion/mptscsih.c | 12 +++------ drivers/message/fusion/mptscsih.h | 3 +-- drivers/s390/scsi/zfcp_scsi.c | 11 ++------- drivers/scsi/3w-9xxx.c | 13 +--------- drivers/scsi/3w-sas.c | 13 +--------- drivers/scsi/3w-xxxx.c | 13 +--------- drivers/scsi/53c700.c | 19 ++++++-------- drivers/scsi/BusLogic.c | 4 +-- drivers/scsi/aacraid/linit.c | 18 ++++++-------- drivers/scsi/advansys.c | 8 +++--- drivers/scsi/aic7xxx/aic79xx_osm.c | 4 +-- drivers/scsi/aic7xxx/aic7xxx_osm.c | 4 +-- drivers/scsi/arcmsr/arcmsr_hba.c | 9 ++----- drivers/scsi/be2iscsi/be_main.c | 2 +- drivers/scsi/bfa/bfad_im.c | 4 +-- drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 2 +- drivers/scsi/bnx2i/bnx2i_iscsi.c | 2 +- drivers/scsi/csiostor/csio_scsi.c | 2 +- drivers/scsi/cxgbi/cxgb3i/cxgb3i.c | 2 +- drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 2 +- drivers/scsi/dpt_i2o.c | 2 +- drivers/scsi/eata.c | 6 ++--- drivers/scsi/esas2r/esas2r.h | 1 - drivers/scsi/esas2r/esas2r_main.c | 11 +-------- drivers/scsi/esp_scsi.c | 2 +- drivers/scsi/fcoe/fcoe.c | 2 +- drivers/scsi/fnic/fnic_main.c | 4 +-- drivers/scsi/hpsa.c | 16 +----------- drivers/scsi/hptiop.c | 8 ++---- drivers/scsi/ibmvscsi/ibmvfc.c | 9 ++----- drivers/scsi/ibmvscsi/ibmvscsi.c | 10 ++------ drivers/scsi/ipr.c | 10 +++----- drivers/scsi/ips.c | 2 +- drivers/scsi/iscsi_tcp.c | 2 +- drivers/scsi/libfc/fc_fcp.c | 15 +---------- drivers/scsi/libiscsi.c | 7 ------ drivers/scsi/libsas/sas_scsi_host.c | 12 ++++----- drivers/scsi/lpfc/lpfc_scsi.c | 26 +++----------------- drivers/scsi/megaraid/megaraid_mbox.c | 21 +--------------- drivers/scsi/megaraid/megaraid_sas_base.c | 13 +--------- drivers/scsi/mpt2sas/mpt2sas_scsih.c | 10 +++----- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 10 +++----- drivers/scsi/ncr53c8xx.c | 2 +- drivers/scsi/pmcraid.c | 12 ++------- drivers/scsi/qla1280.c | 4 +-- drivers/scsi/qla2xxx/qla_os.c | 12 ++------- drivers/scsi/qla4xxx/ql4_os.c | 4 +-- drivers/scsi/scsi.c | 41 +++++++++++-------------------- drivers/scsi/scsi_debug.c | 4 +-- drivers/scsi/scsi_error.c | 2 +- drivers/scsi/scsi_scan.c | 2 +- drivers/scsi/scsi_sysfs.c | 3 +-- drivers/scsi/storvsc_drv.c | 2 +- drivers/scsi/sym53c8xx_2/sym_glue.c | 2 +- drivers/scsi/tmscsim.c | 2 +- drivers/scsi/u14-34f.c | 10 ++++---- drivers/scsi/ufs/ufshcd.c | 13 +++------- drivers/scsi/virtio_scsi.c | 8 ++---- drivers/scsi/vmw_pvscsi.c | 12 ++------- drivers/scsi/wd7000.c | 1 - drivers/target/loopback/tcm_loop.c | 15 +---------- drivers/usb/storage/uas.c | 2 +- include/linux/libata.h | 4 +-- include/scsi/libfc.h | 1 - include/scsi/libiscsi.h | 2 -- include/scsi/libsas.h | 3 +-- include/scsi/scsi_device.h | 2 +- include/scsi/scsi_host.h | 8 ++---- 73 files changed, 155 insertions(+), 412 deletions(-) (limited to 'drivers/infiniband') diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt index bee7d86b9dc..731bc4f4c5e 100644 --- a/Documentation/scsi/scsi_mid_low_api.txt +++ b/Documentation/scsi/scsi_mid_low_api.txt @@ -149,7 +149,7 @@ scsi_add_host() ----> scsi_scan_host() -------+ | slave_alloc() - slave_configure() --> scsi_adjust_queue_depth() + slave_configure() --> scsi_change_queue_depth() | slave_alloc() slave_configure() @@ -159,7 +159,7 @@ scsi_scan_host() -------+ ------------------------------------------------------------ If the LLD wants to adjust the default queue settings, it can invoke -scsi_adjust_queue_depth() in its slave_configure() routine. +scsi_change_queue_depth() in its slave_configure() routine. *** For scsi devices that the mid level tries to scan but do not respond, a slave_alloc(), slave_destroy() pair is called. @@ -203,7 +203,7 @@ LLD mid level LLD scsi_add_device() ------+ | slave_alloc() - slave_configure() [--> scsi_adjust_queue_depth()] + slave_configure() [--> scsi_change_queue_depth()] ------------------------------------------------------------ In a similar fashion, an LLD may become aware that a SCSI device has been @@ -261,7 +261,7 @@ init_this_scsi_driver() ----+ | scsi_register() | slave_alloc() - slave_configure() --> scsi_adjust_queue_depth() + slave_configure() --> scsi_change_queue_depth() slave_alloc() *** slave_destroy() *** | @@ -271,7 +271,7 @@ init_this_scsi_driver() ----+ slave_destroy() *** ------------------------------------------------------------ -The mid level invokes scsi_adjust_queue_depth() with "cmd_per_lun" for that +The mid level invokes scsi_change_queue_depth() with "cmd_per_lun" for that host as the queue length. These settings can be overridden by a slave_configure() supplied by the LLD. @@ -368,7 +368,7 @@ names all start with "scsi_". Summary: scsi_add_device - creates new scsi device (lu) instance scsi_add_host - perform sysfs registration and set up transport class - scsi_adjust_queue_depth - change the queue depth on a SCSI device + scsi_change_queue_depth - change the queue depth on a SCSI device scsi_bios_ptable - return copy of block device's partition table scsi_block_requests - prevent further commands being queued to given host scsi_host_alloc - return a new scsi_host instance whose refcount==1 @@ -436,7 +436,7 @@ int scsi_add_host(struct Scsi_Host *shost, struct device * dev) /** - * scsi_adjust_queue_depth - allow LLD to change queue depth on a SCSI device + * scsi_change_queue_depth - allow LLD to change queue depth on a SCSI device * @sdev: pointer to SCSI device to change queue depth on * @tags Number of tags allowed if tagged queuing enabled, * or number of commands the LLD can queue up @@ -453,7 +453,7 @@ int scsi_add_host(struct Scsi_Host *shost, struct device * dev) * Defined in: drivers/scsi/scsi.c [see source code for more notes] * **/ -void scsi_adjust_queue_depth(struct scsi_device *sdev, int tags) +int scsi_change_queue_depth(struct scsi_device *sdev, int tags) /** @@ -1214,7 +1214,7 @@ of interest: for disk firmware uploads. cmd_per_lun - maximum number of commands that can be queued on devices controlled by the host. Overridden by LLD calls to - scsi_adjust_queue_depth(). + scsi_change_queue_depth(). unchecked_isa_dma - 1=>only use bottom 16 MB of ram (ISA DMA addressing restriction), 0=>can use full 32 bit (or better) DMA address space @@ -1254,7 +1254,7 @@ struct scsi_cmnd Instances of this structure convey SCSI commands to the LLD and responses back to the mid level. The SCSI mid level will ensure that no more SCSI commands become queued against the LLD than are indicated by -scsi_adjust_queue_depth() (or struct Scsi_Host::cmd_per_lun). There will +scsi_change_queue_depth() (or struct Scsi_Host::cmd_per_lun). There will be at least one instance of struct scsi_cmnd available for each SCSI device. Members of interest: cmnd - array containing SCSI command diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index c8bb6abbf12..de46385dbe7 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1164,7 +1164,7 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id)); depth = min(ATA_MAX_QUEUE - 1, depth); - scsi_adjust_queue_depth(sdev, depth); + scsi_change_queue_depth(sdev, depth); } blk_queue_flush_queueable(q, false); @@ -1243,21 +1243,17 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) * @ap: ATA port to which the device change the queue depth * @sdev: SCSI device to configure queue depth for * @queue_depth: new queue depth - * @reason: calling context * * libsas and libata have different approaches for associating a sdev to * its ata_port. * */ int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, - int queue_depth, int reason) + int queue_depth) { struct ata_device *dev; unsigned long flags; - if (reason != SCSI_QDEPTH_DEFAULT) - return -EOPNOTSUPP; - if (queue_depth < 1 || queue_depth == sdev->queue_depth) return sdev->queue_depth; @@ -1282,15 +1278,13 @@ int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, if (sdev->queue_depth == queue_depth) return -EINVAL; - scsi_adjust_queue_depth(sdev, queue_depth); - return queue_depth; + return scsi_change_queue_depth(sdev, queue_depth); } /** * ata_scsi_change_queue_depth - SCSI callback for queue depth config * @sdev: SCSI device to configure queue depth for * @queue_depth: new queue depth - * @reason: calling context * * This is libata standard hostt->change_queue_depth callback. * SCSI will call into this callback when user tries to set queue @@ -1302,12 +1296,11 @@ int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, * RETURNS: * Newly configured queue depth. */ -int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth, - int reason) +int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) { struct ata_port *ap = ata_shost_to_port(sdev->host); - return __ata_change_queue_depth(ap, sdev, queue_depth, reason); + return __ata_change_queue_depth(ap, sdev, queue_depth); } /** diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index cdf99fac139..1db6f5ce5e8 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -1951,7 +1951,7 @@ static int nv_swncq_slave_config(struct scsi_device *sdev) ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num)); if (strncmp(model_num, "Maxtor", 6) == 0) { - ata_scsi_change_queue_depth(sdev, 1, SCSI_QDEPTH_DEFAULT); + ata_scsi_change_queue_depth(sdev, 1); ata_dev_notice(dev, "Disabling SWNCQ mode (depth %x)\n", sdev->queue_depth); } diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 812a2891de5..20ca6a61947 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -911,7 +911,7 @@ static struct scsi_host_template iscsi_iser_sht = { .module = THIS_MODULE, .name = "iSCSI Initiator over iSER", .queuecommand = iscsi_queuecommand, - .change_queue_depth = iscsi_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .sg_tablesize = ISCSI_ISER_SG_TABLESIZE, .max_sectors = 1024, .cmd_per_lun = ISER_DEF_CMD_PER_LUN, diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 8d13a19e04b..5461924c9f1 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -2402,18 +2402,15 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) * srp_change_queue_depth - setting device queue depth * @sdev: scsi device struct * @qdepth: requested queue depth - * @reason: SCSI_QDEPTH_DEFAULT - * (see include/scsi/scsi_host.h for definition) * * Returns queue depth. */ static int -srp_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) +srp_change_queue_depth(struct scsi_device *sdev, int qdepth) { if (!sdev->tagged_supported) qdepth = 1; - scsi_adjust_queue_depth(sdev, qdepth); - return sdev->queue_depth; + return scsi_change_queue_depth(sdev, qdepth); } static int srp_send_tsk_mgmt(struct srp_rdma_ch *ch, u64 req_tag, diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index dee06d6f0b6..6c9fc11efb8 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -2311,12 +2311,11 @@ mptscsih_slave_destroy(struct scsi_device *sdev) * mptscsih_change_queue_depth - This function will set a devices queue depth * @sdev: per scsi_device pointer * @qdepth: requested queue depth - * @reason: calling context * * Adding support for new 'change_queue_depth' api. */ int -mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) +mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth) { MPT_SCSI_HOST *hd = shost_priv(sdev->host); VirtTarget *vtarget; @@ -2327,9 +2326,6 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) starget = scsi_target(sdev); vtarget = starget->hostdata; - if (reason != SCSI_QDEPTH_DEFAULT) - return -EOPNOTSUPP; - if (ioc->bus_type == SPI) { if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)) max_depth = 1; @@ -2347,8 +2343,7 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) if (qdepth > max_depth) qdepth = max_depth; - scsi_adjust_queue_depth(sdev, qdepth); - return sdev->queue_depth; + return scsi_change_queue_depth(sdev, qdepth); } /* @@ -2392,8 +2387,7 @@ mptscsih_slave_configure(struct scsi_device *sdev) ioc->name, vtarget->negoFlags, vtarget->maxOffset, vtarget->minSyncFactor)); - mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH, - SCSI_QDEPTH_DEFAULT); + mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "tagged %d, simple %d\n", ioc->name,sdev->tagged_supported, sdev->simple_tags)); diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h index e1b1a198a62..2baeefd9be7 100644 --- a/drivers/message/fusion/mptscsih.h +++ b/drivers/message/fusion/mptscsih.h @@ -128,8 +128,7 @@ extern int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_F extern int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); -extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth, - int reason); +extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth); extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id); extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id); extern struct device_attribute *mptscsih_host_attrs[]; diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 179bf3d8af6..75f4bfc2b98 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -32,13 +32,6 @@ static bool allow_lun_scan = 1; module_param(allow_lun_scan, bool, 0600); MODULE_PARM_DESC(allow_lun_scan, "For NPIV, scan and attach all storage LUNs"); -static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth, - int reason) -{ - scsi_adjust_queue_depth(sdev, depth); - return sdev->queue_depth; -} - static void zfcp_scsi_slave_destroy(struct scsi_device *sdev) { struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); @@ -54,7 +47,7 @@ static void zfcp_scsi_slave_destroy(struct scsi_device *sdev) static int zfcp_scsi_slave_configure(struct scsi_device *sdp) { if (sdp->tagged_supported) - scsi_adjust_queue_depth(sdp, default_depth); + scsi_change_queue_depth(sdp, default_depth); return 0; } @@ -293,7 +286,7 @@ static struct scsi_host_template zfcp_scsi_host_template = { .slave_alloc = zfcp_scsi_slave_alloc, .slave_configure = zfcp_scsi_slave_configure, .slave_destroy = zfcp_scsi_slave_destroy, - .change_queue_depth = zfcp_scsi_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .proc_name = "zfcp", .can_queue = 4096, .this_id = -1, diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 1cf37032290..cd4129ff7ae 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -189,17 +189,6 @@ static ssize_t twa_show_stats(struct device *dev, return len; } /* End twa_show_stats() */ -/* This function will set a devices queue depth */ -static int twa_change_queue_depth(struct scsi_device *sdev, int queue_depth, - int reason) -{ - if (reason != SCSI_QDEPTH_DEFAULT) - return -EOPNOTSUPP; - - scsi_adjust_queue_depth(sdev, queue_depth); - return queue_depth; -} /* End twa_change_queue_depth() */ - /* Create sysfs 'stats' entry */ static struct device_attribute twa_host_stats_attr = { .attr = { @@ -2014,7 +2003,7 @@ static struct scsi_host_template driver_template = { .queuecommand = twa_scsi_queue, .eh_host_reset_handler = twa_scsi_eh_reset, .bios_param = twa_scsi_biosparam, - .change_queue_depth = twa_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .can_queue = TW_Q_LENGTH-2, .slave_configure = twa_slave_configure, .this_id = -1, diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c index 547756b7d5b..2361772d590 100644 --- a/drivers/scsi/3w-sas.c +++ b/drivers/scsi/3w-sas.c @@ -191,17 +191,6 @@ static ssize_t twl_show_stats(struct device *dev, return len; } /* End twl_show_stats() */ -/* This function will set a devices queue depth */ -static int twl_change_queue_depth(struct scsi_device *sdev, int queue_depth, - int reason) -{ - if (reason != SCSI_QDEPTH_DEFAULT) - return -EOPNOTSUPP; - - scsi_adjust_queue_depth(sdev, queue_depth); - return queue_depth; -} /* End twl_change_queue_depth() */ - /* stats sysfs attribute initializer */ static struct device_attribute twl_host_stats_attr = { .attr = { @@ -1588,7 +1577,7 @@ static struct scsi_host_template driver_template = { .queuecommand = twl_scsi_queue, .eh_host_reset_handler = twl_scsi_eh_reset, .bios_param = twl_scsi_biosparam, - .change_queue_depth = twl_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .can_queue = TW_Q_LENGTH-2, .slave_configure = twl_slave_configure, .this_id = -1, diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index 261a4c1da96..c75f2048319 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -523,17 +523,6 @@ static ssize_t tw_show_stats(struct device *dev, struct device_attribute *attr, return len; } /* End tw_show_stats() */ -/* This function will set a devices queue depth */ -static int tw_change_queue_depth(struct scsi_device *sdev, int queue_depth, - int reason) -{ - if (reason != SCSI_QDEPTH_DEFAULT) - return -EOPNOTSUPP; - - scsi_adjust_queue_depth(sdev, queue_depth); - return queue_depth; -} /* End tw_change_queue_depth() */ - /* Create sysfs 'stats' entry */ static struct device_attribute tw_host_stats_attr = { .attr = { @@ -2268,7 +2257,7 @@ static struct scsi_host_template driver_template = { .queuecommand = tw_scsi_queue, .eh_host_reset_handler = tw_scsi_eh_reset, .bios_param = tw_scsi_biosparam, - .change_queue_depth = tw_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .can_queue = TW_Q_LENGTH-2, .slave_configure = tw_slave_configure, .this_id = -1, diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index d7557b93211..aa915da2a5e 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -175,7 +175,7 @@ STATIC void NCR_700_chip_reset(struct Scsi_Host *host); STATIC int NCR_700_slave_alloc(struct scsi_device *SDpnt); STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt); STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt); -static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth, int reason); +static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth); static int NCR_700_change_queue_type(struct scsi_device *SDpnt, int depth); STATIC struct device_attribute *NCR_700_dev_attrs[]; @@ -904,7 +904,7 @@ process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata hostdata->tag_negotiated &= ~(1<device->tagged_supported = 0; - scsi_adjust_queue_depth(SCp->device, host->cmd_per_lun); + scsi_change_queue_depth(SCp->device, host->cmd_per_lun); scsi_set_tag_type(SCp->device, 0); } else { shost_printk(KERN_WARNING, host, @@ -2052,7 +2052,7 @@ NCR_700_slave_configure(struct scsi_device *SDp) /* to do here: allocate memory; build a queue_full list */ if(SDp->tagged_supported) { - scsi_adjust_queue_depth(SDp, NCR_700_DEFAULT_TAGS); + scsi_change_queue_depth(SDp, NCR_700_DEFAULT_TAGS); NCR_700_set_tag_neg_state(SDp, NCR_700_START_TAG_NEGOTIATION); } @@ -2075,16 +2075,11 @@ NCR_700_slave_destroy(struct scsi_device *SDp) } static int -NCR_700_change_queue_depth(struct scsi_device *SDp, int depth, int reason) +NCR_700_change_queue_depth(struct scsi_device *SDp, int depth) { - if (reason != SCSI_QDEPTH_DEFAULT) - return -EOPNOTSUPP; - if (depth > NCR_700_MAX_TAGS) depth = NCR_700_MAX_TAGS; - - scsi_adjust_queue_depth(SDp, depth); - return depth; + return scsi_change_queue_depth(SDp, depth); } static int NCR_700_change_queue_type(struct scsi_device *SDp, int tag_type) @@ -2105,12 +2100,12 @@ static int NCR_700_change_queue_type(struct scsi_device *SDp, int tag_type) if (!tag_type) { /* shift back to the default unqueued number of commands * (the user can still raise this) */ - scsi_adjust_queue_depth(SDp, SDp->host->cmd_per_lun); + scsi_change_queue_depth(SDp, SDp->host->cmd_per_lun); hostdata->tag_negotiated &= ~(1 << sdev_id(SDp)); } else { /* Here, we cleared the negotiation flag above, so this * will force the driver to renegotiate */ - scsi_adjust_queue_depth(SDp, SDp->queue_depth); + scsi_change_queue_depth(SDp, SDp->queue_depth); if (change_tag) NCR_700_set_tag_neg_state(SDp, NCR_700_START_TAG_NEGOTIATION); } diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 5aa476b6b8a..8d66a6469e2 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -2327,12 +2327,12 @@ static int blogic_slaveconfig(struct scsi_device *dev) if (qdepth == 0) qdepth = BLOGIC_MAX_AUTO_TAG_DEPTH; adapter->qdepth[tgt_id] = qdepth; - scsi_adjust_queue_depth(dev, qdepth); + scsi_change_queue_depth(dev, qdepth); } else { adapter->tagq_ok &= ~(1 << tgt_id); qdepth = adapter->untag_qdepth; adapter->qdepth[tgt_id] = qdepth; - scsi_adjust_queue_depth(dev, qdepth); + scsi_change_queue_depth(dev, qdepth); } qdepth = 0; for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 41b9c68bca6..d11c23aad04 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -462,9 +462,9 @@ static int aac_slave_configure(struct scsi_device *sdev) depth = 256; else if (depth < 2) depth = 2; - scsi_adjust_queue_depth(sdev, depth); + scsi_change_queue_depth(sdev, depth); } else - scsi_adjust_queue_depth(sdev, 1); + scsi_change_queue_depth(sdev, 1); return 0; } @@ -478,12 +478,8 @@ static int aac_slave_configure(struct scsi_device *sdev) * total capacity and the queue depth supported by the target device. */ -static int aac_change_queue_depth(struct scsi_device *sdev, int depth, - int reason) +static int aac_change_queue_depth(struct scsi_device *sdev, int depth) { - if (reason != SCSI_QDEPTH_DEFAULT) - return -EOPNOTSUPP; - if (sdev->tagged_supported && (sdev->type == TYPE_DISK) && (sdev_channel(sdev) == CONTAINER_CHANNEL)) { struct scsi_device * dev; @@ -504,10 +500,10 @@ static int aac_change_queue_depth(struct scsi_device *sdev, int depth, depth = 256; else if (depth < 2) depth = 2; - scsi_adjust_queue_depth(sdev, depth); - } else - scsi_adjust_queue_depth(sdev, 1); - return sdev->queue_depth; + return scsi_change_queue_depth(sdev, depth); + } + + return scsi_change_queue_depth(sdev, 1); } static ssize_t aac_show_raid_level(struct device *dev, struct device_attribute *attr, char *buf) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index ae4840e4c1c..6719a3390eb 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -7706,7 +7706,7 @@ advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc) asc_dvc->cfg->can_tagged_qng |= tid_bit; asc_dvc->use_tagged_qng |= tid_bit; } - scsi_adjust_queue_depth(sdev, + scsi_change_queue_depth(sdev, asc_dvc->max_dvc_qng[sdev->id]); } } else { @@ -7847,10 +7847,8 @@ advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc) } } - if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) { - scsi_adjust_queue_depth(sdev, - adv_dvc->max_dvc_qng); - } + if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) + scsi_change_queue_depth(sdev, adv_dvc->max_dvc_qng); } /* diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 80cb4fd7caa..d5c7b193d8d 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -1470,7 +1470,7 @@ ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev, switch ((dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED))) { case AHD_DEV_Q_BASIC: case AHD_DEV_Q_TAGGED: - scsi_adjust_queue_depth(sdev, + scsi_change_queue_depth(sdev, dev->openings + dev->active); break; default: @@ -1480,7 +1480,7 @@ ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev, * serially on the controller/device. This should * remove some latency. */ - scsi_adjust_queue_depth(sdev, 1); + scsi_change_queue_depth(sdev, 1); break; } } diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index a6a27d5398d..88360116dbc 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -1336,7 +1336,7 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev, switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) { case AHC_DEV_Q_BASIC: case AHC_DEV_Q_TAGGED: - scsi_adjust_queue_depth(sdev, + scsi_change_queue_depth(sdev, dev->openings + dev->active); default: /* @@ -1345,7 +1345,7 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev, * serially on the controller/device. This should * remove some latency. */ - scsi_adjust_queue_depth(sdev, 2); + scsi_change_queue_depth(sdev, 2); break; } } diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 209f77162d0..914c39f9f38 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -114,16 +114,11 @@ static void arcmsr_hardware_reset(struct AdapterControlBlock *acb); static const char *arcmsr_info(struct Scsi_Host *); static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb); static void arcmsr_free_irq(struct pci_dev *, struct AdapterControlBlock *); -static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, - int queue_depth, int reason) +static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_depth) { - if (reason != SCSI_QDEPTH_DEFAULT) - return -EOPNOTSUPP; - if (queue_depth > ARCMSR_MAX_CMD_PERLUN) queue_depth = ARCMSR_MAX_CMD_PERLUN; - scsi_adjust_queue_depth(sdev, queue_depth); - return queue_depth; + return scsi_change_queue_depth(sdev, queue_depth); } static struct scsi_host_template arcmsr_scsi_host_template = { diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index d9b999a3416..f3193406776 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -556,7 +556,7 @@ static struct scsi_host_template beiscsi_sht = { .name = "Emulex 10Gbe open-iscsi Initiator Driver", .proc_name = DRV_NAME, .queuecommand = iscsi_queuecommand, - .change_queue_depth = iscsi_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .slave_configure = beiscsi_slave_configure, .target_alloc = iscsi_target_alloc, .eh_abort_handler = beiscsi_eh_abort, diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index 87b09cd232c..7223b000674 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c @@ -776,7 +776,7 @@ bfad_thread_workq(struct bfad_s *bfad) static int bfad_im_slave_configure(struct scsi_device *sdev) { - scsi_adjust_queue_depth(sdev, bfa_lun_queue_depth); + scsi_change_queue_depth(sdev, bfa_lun_queue_depth); return 0; } @@ -866,7 +866,7 @@ bfad_ramp_up_qdepth(struct bfad_itnim_s *itnim, struct scsi_device *sdev) if (bfa_lun_queue_depth > tmp_sdev->queue_depth) { if (tmp_sdev->id != sdev->id) continue; - scsi_adjust_queue_depth(tmp_sdev, + scsi_change_queue_depth(tmp_sdev, tmp_sdev->queue_depth + 1); itnim->last_ramp_up_time = jiffies; diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index cc537972f3e..386c2cfad30 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -2784,7 +2784,7 @@ static struct scsi_host_template bnx2fc_shost_template = { .eh_target_reset_handler = bnx2fc_eh_target_reset, /* tgt reset */ .eh_host_reset_handler = fc_eh_host_reset, .slave_alloc = fc_slave_alloc, - .change_queue_depth = fc_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .change_queue_type = scsi_change_queue_type, .this_id = -1, .cmd_per_lun = 3, diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index 9de1c20bb0f..e53078d0330 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -2259,7 +2259,7 @@ static struct scsi_host_template bnx2i_host_template = { .eh_abort_handler = iscsi_eh_abort, .eh_device_reset_handler = iscsi_eh_device_reset, .eh_target_reset_handler = iscsi_eh_recover_target, - .change_queue_depth = iscsi_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .target_alloc = iscsi_target_alloc, .can_queue = 2048, .max_sectors = 127, diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c index 44a8cc51428..4d0b6ce55f2 100644 --- a/drivers/scsi/csiostor/csio_scsi.c +++ b/drivers/scsi/csiostor/csio_scsi.c @@ -2241,7 +2241,7 @@ csio_slave_alloc(struct scsi_device *sdev) static int csio_slave_configure(struct scsi_device *sdev) { - scsi_adjust_queue_depth(sdev, csio_lun_qdepth); + scsi_change_queue_depth(sdev, csio_lun_qdepth); return 0; } diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c index 99ea67dcdd2..3db4c63978c 100644 --- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c +++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c @@ -86,7 +86,7 @@ static struct scsi_host_template cxgb3i_host_template = { .proc_name = DRV_MODULE_NAME, .can_queue = CXGB3I_SCSI_HOST_QDEPTH, .queuecommand = iscsi_queuecommand, - .change_queue_depth = iscsi_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .sg_tablesize = SG_ALL, .max_sectors = 0xFFFF, .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c index af86e8f57b8..efe42ef7d92 100644 --- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c +++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c @@ -89,7 +89,7 @@ static struct scsi_host_template cxgb4i_host_template = { .proc_name = DRV_MODULE_NAME, .can_queue = CXGB4I_SCSI_HOST_QDEPTH, .queuecommand = iscsi_queuecommand, - .change_queue_depth = iscsi_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .sg_tablesize = SG_ALL, .max_sectors = 0xFFFF, .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 1af8d54bcde..0bf976936a1 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c @@ -415,7 +415,7 @@ static int adpt_slave_configure(struct scsi_device * device) pHba = (adpt_hba *) host->hostdata[0]; if (host->can_queue && device->tagged_supported) { - scsi_adjust_queue_depth(device, + scsi_change_queue_depth(device, host->can_queue - 1); } return 0; diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c index bc0f918f172..227dd2c2ec2 100644 --- a/drivers/scsi/eata.c +++ b/drivers/scsi/eata.c @@ -952,12 +952,12 @@ static int eata2x_slave_configure(struct scsi_device *dev) } else { tag_suffix = ", no tags"; } - scsi_adjust_queue_depth(dev, tqd); + scsi_change_queue_depth(dev, tqd); } else if (TLDEV(dev->type) && linked_comm) { - scsi_adjust_queue_depth(dev, tqd); + scsi_change_queue_depth(dev, tqd); tag_suffix = ", untagged"; } else { - scsi_adjust_queue_depth(dev, utqd); + scsi_change_queue_depth(dev, utqd); tag_suffix = ""; } diff --git a/drivers/scsi/esas2r/esas2r.h b/drivers/scsi/esas2r/esas2r.h index 1941d837f6f..b6030e3edd0 100644 --- a/drivers/scsi/esas2r/esas2r.h +++ b/drivers/scsi/esas2r/esas2r.h @@ -972,7 +972,6 @@ u8 handle_hba_ioctl(struct esas2r_adapter *a, struct atto_ioctl *ioctl_hba); int esas2r_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd); int esas2r_show_info(struct seq_file *m, struct Scsi_Host *sh); -int esas2r_change_queue_depth(struct scsi_device *dev, int depth, int reason); long esas2r_proc_ioctl(struct file *fp, unsigned int cmd, unsigned long arg); /* SCSI error handler (eh) functions */ diff --git a/drivers/scsi/esas2r/esas2r_main.c b/drivers/scsi/esas2r/esas2r_main.c index 30fce64faf7..593ff8a63c7 100644 --- a/drivers/scsi/esas2r/esas2r_main.c +++ b/drivers/scsi/esas2r/esas2r_main.c @@ -254,7 +254,7 @@ static struct scsi_host_template driver_template = { .use_clustering = ENABLE_CLUSTERING, .emulated = 0, .proc_name = ESAS2R_DRVR_NAME, - .change_queue_depth = esas2r_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .change_queue_type = scsi_change_queue_type, .max_sectors = 0xFFFF, .use_blk_tags = 1, @@ -1257,15 +1257,6 @@ int esas2r_target_reset(struct scsi_cmnd *cmd) return esas2r_dev_targ_reset(cmd, true); } -int esas2r_change_queue_depth(struct scsi_device *dev, int depth, int reason) -{ - esas2r_log(ESAS2R_LOG_INFO, "change_queue_depth %p, %d", dev, depth); - - scsi_adjust_queue_depth(dev, depth); - - return dev->queue_depth; -} - void esas2r_log_request_failure(struct esas2r_adapter *a, struct esas2r_request *rq) { diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index 38c23e0b73a..7e7687f73de 100644 --- a/drivers/scsi/esp_scsi.c +++ b/drivers/scsi/esp_scsi.c @@ -2407,7 +2407,7 @@ static int esp_slave_configure(struct scsi_device *dev) /* XXX make this configurable somehow XXX */ int goal_tags = min(ESP_DEFAULT_TAGS, ESP_MAX_TAG); - scsi_adjust_queue_depth(dev, goal_tags); + scsi_change_queue_depth(dev, goal_tags); } tp->flags |= ESP_TGT_DISCONNECT; diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 97229860398..308a016fdae 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -280,7 +280,7 @@ static struct scsi_host_template fcoe_shost_template = { .eh_device_reset_handler = fc_eh_device_reset, .eh_host_reset_handler = fc_eh_host_reset, .slave_alloc = fc_slave_alloc, - .change_queue_depth = fc_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .change_queue_type = scsi_change_queue_type, .this_id = -1, .cmd_per_lun = 3, diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index 86b496c8633..0c1f8177b5b 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@ -98,7 +98,7 @@ static int fnic_slave_alloc(struct scsi_device *sdev) if (!rport || fc_remote_port_chkready(rport)) return -ENXIO; - scsi_adjust_queue_depth(sdev, fnic_max_qdepth); + scsi_change_queue_depth(sdev, fnic_max_qdepth); return 0; } @@ -110,7 +110,7 @@ static struct scsi_host_template fnic_host_template = { .eh_device_reset_handler = fnic_device_reset, .eh_host_reset_handler = fnic_host_reset, .slave_alloc = fnic_slave_alloc, - .change_queue_depth = fc_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .change_queue_type = scsi_change_queue_type, .this_id = -1, .cmd_per_lun = 3, diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 617f218e2a1..6bb4611b238 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -216,8 +216,6 @@ static int hpsa_scsi_queue_command(struct Scsi_Host *h, struct scsi_cmnd *cmd); static void hpsa_scan_start(struct Scsi_Host *); static int hpsa_scan_finished(struct Scsi_Host *sh, unsigned long elapsed_time); -static int hpsa_change_queue_depth(struct scsi_device *sdev, - int qdepth, int reason); static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd); static int hpsa_eh_abort_handler(struct scsi_cmnd *scsicmd); @@ -673,7 +671,7 @@ static struct scsi_host_template hpsa_driver_template = { .queuecommand = hpsa_scsi_queue_command, .scan_start = hpsa_scan_start, .scan_finished = hpsa_scan_finished, - .change_queue_depth = hpsa_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .this_id = -1, .use_clustering = ENABLE_CLUSTERING, .eh_abort_handler = hpsa_eh_abort_handler, @@ -4074,18 +4072,6 @@ static int hpsa_scan_finished(struct Scsi_Host *sh, return finished; } -static int hpsa_change_queue_depth(struct scsi_device *sdev, - int qdepth, int reason) -{ - struct ctlr_info *h = sdev_to_hba(sdev); - - if (reason != SCSI_QDEPTH_DEFAULT) - return -ENOTSUPP; - - scsi_adjust_queue_depth(sdev, qdepth); - return sdev->queue_depth; -} - static void hpsa_unregister_scsi(struct ctlr_info *h) { /* we are being forcibly unloaded, and may not refuse. */ diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c index 151893148ab..e995218476e 100644 --- a/drivers/scsi/hptiop.c +++ b/drivers/scsi/hptiop.c @@ -1118,17 +1118,13 @@ static int hptiop_reset(struct scsi_cmnd *scp) } static int hptiop_adjust_disk_queue_depth(struct scsi_device *sdev, - int queue_depth, int reason) + int queue_depth) { struct hptiop_hba *hba = (struct hptiop_hba *)sdev->host->hostdata; - if (reason != SCSI_QDEPTH_DEFAULT) - return -EOPNOTSUPP; - if (queue_depth > hba->max_requests) queue_depth = hba->max_requests; - scsi_adjust_queue_depth(sdev, queue_depth); - return queue_depth; + return scsi_change_queue_depth(sdev, queue_depth); } static ssize_t hptiop_show_version(struct device *dev, diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 381449d5be7..f58c6d8e026 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -2900,17 +2900,12 @@ static int ibmvfc_slave_configure(struct scsi_device *sdev) * Return value: * actual depth set **/ -static int ibmvfc_change_queue_depth(struct scsi_device *sdev, int qdepth, - int reason) +static int ibmvfc_change_queue_depth(struct scsi_device *sdev, int qdepth) { - if (reason != SCSI_QDEPTH_DEFAULT) - return -EOPNOTSUPP; - if (qdepth > IBMVFC_MAX_CMDS_PER_LUN) qdepth = IBMVFC_MAX_CMDS_PER_LUN; - scsi_adjust_queue_depth(sdev, qdepth); - return sdev->queue_depth; + return scsi_change_queue_depth(sdev, qdepth); } static ssize_t ibmvfc_show_host_partition_name(struct device *dev, diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index e8c3cdf0d03..acea5d6eebd 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -1941,17 +1941,11 @@ static int ibmvscsi_slave_configure(struct scsi_device *sdev) * Return value: * actual depth set **/ -static int ibmvscsi_change_queue_depth(struct scsi_device *sdev, int qdepth, - int reason) +static int ibmvscsi_change_queue_depth(struct scsi_device *sdev, int qdepth) { - if (reason != SCSI_QDEPTH_DEFAULT) - return -EOPNOTSUPP; - if (qdepth > IBMVSCSI_MAX_CMDS_PER_LUN) qdepth = IBMVSCSI_MAX_CMDS_PER_LUN; - - scsi_adjust_queue_depth(sdev, qdepth); - return sdev->queue_depth; + return scsi_change_queue_depth(sdev, qdepth); } /* ------------------------------------------------------------ diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index d8d16625a87..54029438935 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -4328,16 +4328,12 @@ static int ipr_free_dump(struct ipr_ioa_cfg *ioa_cfg) { return 0; }; * Return value: * actual depth set **/ -static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth, - int reason) +static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth) { struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata; struct ipr_resource_entry *res; unsigned long lock_flags = 0; - if (reason != SCSI_QDEPTH_DEFAULT) - return -EOPNOTSUPP; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); res = (struct ipr_resource_entry *)sdev->hostdata; @@ -4345,7 +4341,7 @@ static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth, qdepth = IPR_MAX_CMD_PER_ATA_LUN; spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - scsi_adjust_queue_depth(sdev, qdepth); + scsi_change_queue_depth(sdev, qdepth); return sdev->queue_depth; } @@ -4752,7 +4748,7 @@ static int ipr_slave_configure(struct scsi_device *sdev) spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); if (ap) { - scsi_adjust_queue_depth(sdev, IPR_MAX_CMD_PER_ATA_LUN); + scsi_change_queue_depth(sdev, IPR_MAX_CMD_PER_ATA_LUN); ata_sas_slave_configure(sdev, ap); } diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 454741a8da4..e5c28435d76 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -1210,7 +1210,7 @@ ips_slave_configure(struct scsi_device * SDptr) min = ha->max_cmds / 2; if (ha->enq->ucLogDriveCount <= 2) min = ha->max_cmds - 1; - scsi_adjust_queue_depth(SDptr, min); + scsi_change_queue_depth(SDptr, min); } SDptr->skip_ms_page_8 = 1; diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index a575d845b66..0b8af186e70 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -952,7 +952,7 @@ static struct scsi_host_template iscsi_sw_tcp_sht = { .module = THIS_MODULE, .name = "iSCSI Initiator over TCP/IP", .queuecommand = iscsi_queuecommand, - .change_queue_depth = iscsi_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .can_queue = ISCSI_DEF_XMIT_CMDS_MAX - 1, .sg_tablesize = 4096, .max_sectors = 0xFFFF, diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index 0d2d024e77c..c6795941b45 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c @@ -2160,24 +2160,11 @@ int fc_slave_alloc(struct scsi_device *sdev) if (!rport || fc_remote_port_chkready(rport)) return -ENXIO; - scsi_adjust_queue_depth(sdev, FC_FCP_DFLT_QUEUE_DEPTH); + scsi_change_queue_depth(sdev, FC_FCP_DFLT_QUEUE_DEPTH); return 0; } EXPORT_SYMBOL(fc_slave_alloc); -/** - * fc_change_queue_depth() - Change a device's queue depth - * @sdev: The SCSI device whose queue depth is to change - * @qdepth: The new queue depth - * @reason: The resason for the change - */ -int fc_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) -{ - scsi_adjust_queue_depth(sdev, qdepth); - return sdev->queue_depth; -} -EXPORT_SYMBOL(fc_change_queue_depth); - /** * fc_fcp_destory() - Tear down the FCP layer for a given local port * @lport: The local port that no longer needs the FCP layer diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 79e977484ad..8053f24f034 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -1771,13 +1771,6 @@ fault: } EXPORT_SYMBOL_GPL(iscsi_queuecommand); -int iscsi_change_queue_depth(struct scsi_device *sdev, int depth, int reason) -{ - scsi_adjust_queue_depth(sdev, depth); - return sdev->queue_depth; -} -EXPORT_SYMBOL_GPL(iscsi_change_queue_depth); - int iscsi_target_alloc(struct scsi_target *starget) { struct iscsi_cls_session *cls_session = starget_to_session(starget); diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 914e4116513..b492293d51f 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -940,12 +940,12 @@ int sas_slave_configure(struct scsi_device *scsi_dev) sas_read_port_mode_page(scsi_dev); if (scsi_dev->tagged_supported) { - scsi_adjust_queue_depth(scsi_dev, SAS_DEF_QD); + scsi_change_queue_depth(scsi_dev, SAS_DEF_QD); } else { SAS_DPRINTK("device %llx, LUN %llx doesn't support " "TCQ\n", SAS_ADDR(dev->sas_addr), scsi_dev->lun); - scsi_adjust_queue_depth(scsi_dev, 1); + scsi_change_queue_depth(scsi_dev, 1); } scsi_dev->allow_restart = 1; @@ -953,18 +953,16 @@ int sas_slave_configure(struct scsi_device *scsi_dev) return 0; } -int sas_change_queue_depth(struct scsi_device *sdev, int depth, int reason) +int sas_change_queue_depth(struct scsi_device *sdev, int depth) { struct domain_device *dev = sdev_to_domain_dev(sdev); if (dev_is_sata(dev)) - return __ata_change_queue_depth(dev->sata_dev.ap, sdev, depth, - reason); + return __ata_change_queue_depth(dev->sata_dev.ap, sdev, depth); if (!sdev->tagged_supported) depth = 1; - scsi_adjust_queue_depth(sdev, depth); - return depth; + return scsi_change_queue_depth(sdev, depth); } int sas_change_queue_type(struct scsi_device *scsi_dev, int type) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 52285492036..fd85952b621 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -242,23 +242,6 @@ lpfc_update_stats(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) spin_unlock_irqrestore(shost->host_lock, flags); } -/** - * lpfc_change_queue_depth - Alter scsi device queue depth - * @sdev: Pointer the scsi device on which to change the queue depth. - * @qdepth: New queue depth to set the sdev to. - * @reason: The reason for the queue depth change. - * - * This function is called by the midlayer and the LLD to alter the queue - * depth for a scsi device. This function sets the queue depth to the new - * value and sends an event out to log the queue depth change. - **/ -static int -lpfc_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) -{ - scsi_adjust_queue_depth(sdev, qdepth); - return sdev->queue_depth; -} - /** * lpfc_rampdown_queue_depth - Post RAMP_DOWN_QUEUE event to worker thread * @phba: The Hba for which this call is being executed. @@ -344,8 +327,7 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) else new_queue_depth = sdev->queue_depth - new_queue_depth; - lpfc_change_queue_depth(sdev, new_queue_depth, - SCSI_QDEPTH_DEFAULT); + scsi_change_queue_depth(sdev, new_queue_depth); } } lpfc_destroy_vport_work_array(phba, vports); @@ -5513,7 +5495,7 @@ lpfc_slave_configure(struct scsi_device *sdev) struct lpfc_vport *vport = (struct lpfc_vport *) sdev->host->hostdata; struct lpfc_hba *phba = vport->phba; - scsi_adjust_queue_depth(sdev, vport->cfg_lun_queue_depth); + scsi_change_queue_depth(sdev, vport->cfg_lun_queue_depth); if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { lpfc_sli_handle_fast_ring_event(phba, @@ -5896,7 +5878,7 @@ struct scsi_host_template lpfc_template = { .shost_attrs = lpfc_hba_attrs, .max_sectors = 0xFFFF, .vendor_id = LPFC_NL_VENDOR_ID, - .change_queue_depth = lpfc_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .change_queue_type = scsi_change_queue_type, .use_blk_tags = 1, .track_queue_depth = 1, @@ -5921,7 +5903,7 @@ struct scsi_host_template lpfc_vport_template = { .use_clustering = ENABLE_CLUSTERING, .shost_attrs = lpfc_vport_attrs, .max_sectors = 0xFFFF, - .change_queue_depth = lpfc_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .change_queue_type = scsi_change_queue_type, .use_blk_tags = 1, .track_queue_depth = 1, diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index d56eb9d3d40..f0987f22ea7 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -332,25 +332,6 @@ static struct device_attribute *megaraid_sdev_attrs[] = { NULL, }; -/** - * megaraid_change_queue_depth - Change the device's queue depth - * @sdev: scsi device struct - * @qdepth: depth to set - * @reason: calling context - * - * Return value: - * actual depth set - */ -static int megaraid_change_queue_depth(struct scsi_device *sdev, int qdepth, - int reason) -{ - if (reason != SCSI_QDEPTH_DEFAULT) - return -EOPNOTSUPP; - - scsi_adjust_queue_depth(sdev, qdepth); - return sdev->queue_depth; -} - /* * Scsi host template for megaraid unified driver */ @@ -363,7 +344,7 @@ static struct scsi_host_template megaraid_template_g = { .eh_device_reset_handler = megaraid_reset_handler, .eh_bus_reset_handler = megaraid_reset_handler, .eh_host_reset_handler = megaraid_reset_handler, - .change_queue_depth = megaraid_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .use_clustering = ENABLE_CLUSTERING, .no_write_same = 1, .sdev_attrs = megaraid_sdev_attrs, diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 69a9dd6ae04..f05580e693d 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -2591,17 +2591,6 @@ megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd) } } -static int megasas_change_queue_depth(struct scsi_device *sdev, - int queue_depth, int reason) -{ - if (reason != SCSI_QDEPTH_DEFAULT) - return -EOPNOTSUPP; - - scsi_adjust_queue_depth(sdev, queue_depth); - - return queue_depth; -} - static ssize_t megasas_fw_crash_buffer_store(struct device *cdev, struct device_attribute *attr, const char *buf, size_t count) @@ -2766,7 +2755,7 @@ static struct scsi_host_template megasas_template = { .shost_attrs = megaraid_host_attrs, .bios_param = megasas_bios_param, .use_clustering = ENABLE_CLUSTERING, - .change_queue_depth = megasas_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .no_write_same = 1, }; diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index b006e1e9fcb..12229de433b 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -1222,20 +1222,18 @@ _scsih_adjust_queue_depth(struct scsi_device *sdev, int qdepth) max_depth = 1; if (qdepth > max_depth) qdepth = max_depth; - scsi_adjust_queue_depth(sdev, qdepth); + scsi_change_queue_depth(sdev, qdepth); } /** * _scsih_change_queue_depth - setting device queue depth * @sdev: scsi device struct * @qdepth: requested queue depth - * @reason: SCSI_QDEPTH_DEFAULT - * (see include/scsi/scsi_host.h for definition) * * Returns queue depth. */ static int -_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) +_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth) { _scsih_adjust_queue_depth(sdev, qdepth); @@ -2077,7 +2075,7 @@ _scsih_slave_configure(struct scsi_device *sdev) r_level, raid_device->handle, (unsigned long long)raid_device->wwid, raid_device->num_pds, ds); - _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); + _scsih_change_queue_depth(sdev, qdepth); /* raid transport support */ if (!ioc->is_warpdrive) _scsih_set_level(sdev, raid_device->volume_type); @@ -2142,7 +2140,7 @@ _scsih_slave_configure(struct scsi_device *sdev) _scsih_display_sata_capabilities(ioc, handle, sdev); - _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); + _scsih_change_queue_depth(sdev, qdepth); if (ssp_target) { sas_read_port_mode_page(sdev); diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 568dcaed36c..de175b9915e 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -1090,20 +1090,18 @@ _scsih_adjust_queue_depth(struct scsi_device *sdev, int qdepth) max_depth = 1; if (qdepth > max_depth) qdepth = max_depth; - scsi_adjust_queue_depth(sdev, qdepth); + scsi_change_queue_depth(sdev, qdepth); } /** * _scsih_change_queue_depth - setting device queue depth * @sdev: scsi device struct * @qdepth: requested queue depth - * @reason: SCSI_QDEPTH_DEFAULT - * (see include/scsi/scsi_host.h for definition) * * Returns queue depth. */ static int -_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) +_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth) { _scsih_adjust_queue_depth(sdev, qdepth); @@ -1734,7 +1732,7 @@ _scsih_slave_configure(struct scsi_device *sdev) raid_device->num_pds, ds); - _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); + _scsih_change_queue_depth(sdev, qdepth); /* raid transport support */ _scsih_set_level(sdev, raid_device->volume_type); @@ -1800,7 +1798,7 @@ _scsih_slave_configure(struct scsi_device *sdev) _scsih_display_sata_capabilities(ioc, handle, sdev); - _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); + _scsih_change_queue_depth(sdev, qdepth); if (ssp_target) { sas_read_port_mode_page(sdev); diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 9c331b7bfdc..5b93ed810f6 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -7997,7 +7997,7 @@ static int ncr53c8xx_slave_configure(struct scsi_device *device) if (depth_to_use > MAX_TAGS) depth_to_use = MAX_TAGS; - scsi_adjust_queue_depth(device, depth_to_use); + scsi_change_queue_depth(device, depth_to_use); /* ** Since the queue depth is not tunable under Linux, diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index d8b9ba251fb..b1b1f66b1ab 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -285,23 +285,15 @@ static void pmcraid_slave_destroy(struct scsi_device *scsi_dev) * pmcraid_change_queue_depth - Change the device's queue depth * @scsi_dev: scsi device struct * @depth: depth to set - * @reason: calling context * * Return value * actual depth set */ -static int pmcraid_change_queue_depth(struct scsi_device *scsi_dev, int depth, - int reason) +static int pmcraid_change_queue_depth(struct scsi_device *scsi_dev, int depth) { - if (reason != SCSI_QDEPTH_DEFAULT) - return -EOPNOTSUPP; - if (depth > PMCRAID_MAX_CMD_PER_LUN) depth = PMCRAID_MAX_CMD_PER_LUN; - - scsi_adjust_queue_depth(scsi_dev, depth); - - return scsi_dev->queue_depth; + return scsi_change_queue_depth(scsi_dev, depth); } /** diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index adedb6ef8ee..c68a66e8cfc 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -1224,9 +1224,9 @@ qla1280_slave_configure(struct scsi_device *device) if (device->tagged_supported && (ha->bus_settings[bus].qtag_enables & (BIT_0 << target))) { - scsi_adjust_queue_depth(device, ha->bus_settings[bus].hiwat); + scsi_change_queue_depth(device, ha->bus_settings[bus].hiwat); } else { - scsi_adjust_queue_depth(device, default_depth); + scsi_change_queue_depth(device, default_depth); } nv->bus[bus].target[target].parameter.enable_sync = device->sdtr; diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 20049b176b6..6b4d9235368 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -236,7 +236,6 @@ static int qla2xxx_eh_target_reset(struct scsi_cmnd *); static int qla2xxx_eh_bus_reset(struct scsi_cmnd *); static int qla2xxx_eh_host_reset(struct scsi_cmnd *); -static int qla2x00_change_queue_depth(struct scsi_device *, int, int); static void qla2x00_clear_drv_active(struct qla_hw_data *); static void qla2x00_free_device(scsi_qla_host_t *); static void qla83xx_disable_laser(scsi_qla_host_t *vha); @@ -258,7 +257,7 @@ struct scsi_host_template qla2xxx_driver_template = { .slave_destroy = qla2xxx_slave_destroy, .scan_finished = qla2xxx_scan_finished, .scan_start = qla2xxx_scan_start, - .change_queue_depth = qla2x00_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .change_queue_type = scsi_change_queue_type, .this_id = -1, .cmd_per_lun = 3, @@ -1406,7 +1405,7 @@ qla2xxx_slave_configure(struct scsi_device *sdev) if (IS_T10_PI_CAPABLE(vha->hw)) blk_queue_update_dma_alignment(sdev->request_queue, 0x7); - scsi_adjust_queue_depth(sdev, req->max_q_depth); + scsi_change_queue_depth(sdev, req->max_q_depth); return 0; } @@ -1416,13 +1415,6 @@ qla2xxx_slave_destroy(struct scsi_device *sdev) sdev->hostdata = NULL; } -static int -qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) -{ - scsi_adjust_queue_depth(sdev, qdepth); - return sdev->queue_depth; -} - /** * qla2x00_config_dma_addressing() - Configure OS DMA addressing method. * @ha: HA context diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 2bfde373ea2..6d25879d87c 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -201,7 +201,7 @@ static struct scsi_host_template qla4xxx_driver_template = { .eh_timed_out = qla4xxx_eh_cmd_timed_out, .slave_alloc = qla4xxx_slave_alloc, - .change_queue_depth = iscsi_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .this_id = -1, .cmd_per_lun = 3, @@ -9059,7 +9059,7 @@ static int qla4xxx_slave_alloc(struct scsi_device *sdev) if (ql4xmaxqdepth != 0 && ql4xmaxqdepth <= 0xffffU) queue_depth = ql4xmaxqdepth; - scsi_adjust_queue_depth(sdev, queue_depth); + scsi_change_queue_depth(sdev, queue_depth); return 0; } diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 106fa2f886d..5ea15fc7d2f 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -742,30 +742,18 @@ void scsi_finish_command(struct scsi_cmnd *cmd) } /** - * scsi_adjust_queue_depth - Let low level drivers change a device's queue depth + * scsi_change_queue_depth - change a device's queue depth * @sdev: SCSI Device in question - * @tags: Number of tags allowed if tagged queueing enabled, - * or number of commands the low level driver can - * queue up in non-tagged mode (as per cmd_per_lun). + * @depth: number of commands allowed to be queued to the driver * - * Returns: Nothing - * - * Lock Status: None held on entry - * - * Notes: Low level drivers may call this at any time and we will do - * the right thing depending on whether or not the device is - * currently active and whether or not it even has the - * command blocks built yet. + * Sets the device queue depth and returns the new value. */ -void scsi_adjust_queue_depth(struct scsi_device *sdev, int tags) +int scsi_change_queue_depth(struct scsi_device *sdev, int depth) { unsigned long flags; - /* - * refuse to set tagged depth to an unworkable size - */ - if (tags <= 0) - return; + if (depth <= 0) + goto out; spin_lock_irqsave(sdev->request_queue->queue_lock, flags); @@ -780,15 +768,17 @@ void scsi_adjust_queue_depth(struct scsi_device *sdev, int tags) */ if (!shost_use_blk_mq(sdev->host) && !sdev->host->bqt) { if (blk_queue_tagged(sdev->request_queue) && - blk_queue_resize_tags(sdev->request_queue, tags) != 0) - goto out; + blk_queue_resize_tags(sdev->request_queue, depth) != 0) + goto out_unlock; } - sdev->queue_depth = tags; - out: + sdev->queue_depth = depth; +out_unlock: spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); +out: + return sdev->queue_depth; } -EXPORT_SYMBOL(scsi_adjust_queue_depth); +EXPORT_SYMBOL(scsi_change_queue_depth); /** * scsi_track_queue_full - track QUEUE_FULL events to adjust queue depth @@ -833,12 +823,11 @@ int scsi_track_queue_full(struct scsi_device *sdev, int depth) if (sdev->last_queue_full_depth < 8) { /* Drop back to untagged */ scsi_set_tag_type(sdev, 0); - scsi_adjust_queue_depth(sdev, sdev->host->cmd_per_lun); + scsi_change_queue_depth(sdev, sdev->host->cmd_per_lun); return -1; } - scsi_adjust_queue_depth(sdev, depth); - return depth; + return scsi_change_queue_depth(sdev, depth); } EXPORT_SYMBOL(scsi_track_queue_full); diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 84cf82e0782..ce71b6d4393 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -4469,7 +4469,7 @@ sdebug_queuecommand_lock_or_not(struct Scsi_Host *shost, struct scsi_cmnd *cmd) } static int -sdebug_change_qdepth(struct scsi_device *sdev, int qdepth, int reason) +sdebug_change_qdepth(struct scsi_device *sdev, int qdepth) { int num_in_q = 0; unsigned long iflags; @@ -4489,7 +4489,7 @@ sdebug_change_qdepth(struct scsi_device *sdev, int qdepth, int reason) /* allow to exceed max host queued_arr elements for testing */ if (qdepth > SCSI_DEBUG_CANQUEUE + 10) qdepth = SCSI_DEBUG_CANQUEUE + 10; - scsi_adjust_queue_depth(sdev, qdepth); + scsi_change_queue_depth(sdev, qdepth); if (SCSI_DEBUG_OPT_Q_NOISE & scsi_debug_opts) { sdev_printk(KERN_INFO, sdev, diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 2d0f5155ee5..1f63559184b 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -632,7 +632,7 @@ static void scsi_handle_queue_ramp_up(struct scsi_device *sdev) tmp_sdev->queue_depth == sdev->max_queue_depth) continue; - scsi_adjust_queue_depth(tmp_sdev, tmp_sdev->queue_depth + 1); + scsi_change_queue_depth(tmp_sdev, tmp_sdev->queue_depth + 1); sdev->last_queue_ramp_up = jiffies; } } diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index d97597e6337..0af713375db 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -292,7 +292,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, blk_queue_init_tags(sdev->request_queue, sdev->host->cmd_per_lun, shost->bqt); } - scsi_adjust_queue_depth(sdev, sdev->host->cmd_per_lun); + scsi_change_queue_depth(sdev, sdev->host->cmd_per_lun); scsi_sysfs_device_initialize(sdev); diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index bffd5abdcd1..1cb64a8e18c 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -880,8 +880,7 @@ sdev_store_queue_depth(struct device *dev, struct device_attribute *attr, if (depth < 1 || depth > sht->can_queue) return -EINVAL; - retval = sht->change_queue_depth(sdev, depth, - SCSI_QDEPTH_DEFAULT); + retval = sht->change_queue_depth(sdev, depth); if (retval < 0) return retval; diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index ff8befbdf17..e3ba251fb6e 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -1429,7 +1429,7 @@ static void storvsc_device_destroy(struct scsi_device *sdevice) static int storvsc_device_configure(struct scsi_device *sdevice) { - scsi_adjust_queue_depth(sdevice, STORVSC_MAX_IO_REQUESTS); + scsi_change_queue_depth(sdevice, STORVSC_MAX_IO_REQUESTS); blk_queue_max_segment_size(sdevice->request_queue, PAGE_SIZE); diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 3557b385251..5d00e514ff2 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -820,7 +820,7 @@ static int sym53c8xx_slave_configure(struct scsi_device *sdev) if (reqtags > SYM_CONF_MAX_TAG) reqtags = SYM_CONF_MAX_TAG; depth_to_use = reqtags ? reqtags : 1; - scsi_adjust_queue_depth(sdev, depth_to_use); + scsi_change_queue_depth(sdev, depth_to_use); lp->s.scdev_depth = depth_to_use; sym_tune_dev_queuing(tp, sdev->lun, reqtags); diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c index 844c9a048c0..6c3c2cef389 100644 --- a/drivers/scsi/tmscsim.c +++ b/drivers/scsi/tmscsim.c @@ -2194,7 +2194,7 @@ static int dc390_slave_configure(struct scsi_device *sdev) if (sdev->tagged_supported && (dcb->DevMode & TAG_QUEUEING_)) { dcb->SyncMode |= EN_TAG_QUEUEING; - scsi_adjust_queue_depth(sdev, acb->TagMaxNum); + scsi_change_queue_depth(sdev, acb->TagMaxNum); } return 0; diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c index aa0f4035afa..14eb50b95a1 100644 --- a/drivers/scsi/u14-34f.c +++ b/drivers/scsi/u14-34f.c @@ -696,25 +696,25 @@ static int u14_34f_slave_configure(struct scsi_device *dev) { if (TLDEV(dev->type) && dev->tagged_supported) if (tag_mode == TAG_SIMPLE) { - scsi_adjust_queue_depth(dev, tqd); + scsi_change_queue_depth(dev, tqd); tag_suffix = ", simple tags"; } else if (tag_mode == TAG_ORDERED) { - scsi_adjust_queue_depth(dev, tqd); + scsi_change_queue_depth(dev, tqd); tag_suffix = ", ordered tags"; } else { - scsi_adjust_queue_depth(dev, tqd); + scsi_change_queue_depth(dev, tqd); tag_suffix = ", no tags"; } else if (TLDEV(dev->type) && linked_comm) { - scsi_adjust_queue_depth(dev, tqd); + scsi_change_queue_depth(dev, tqd); tag_suffix = ", untagged"; } else { - scsi_adjust_queue_depth(dev, utqd); + scsi_change_queue_depth(dev, utqd); tag_suffix = ""; } diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index e96ab253e3e..0c4f98ee604 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2695,7 +2695,7 @@ static void ufshcd_set_queue_depth(struct scsi_device *sdev) dev_dbg(hba->dev, "%s: activate tcq with queue depth %d\n", __func__, lun_qdepth); - scsi_adjust_queue_depth(sdev, lun_qdepth); + scsi_change_queue_depth(sdev, lun_qdepth); } /* @@ -2787,21 +2787,16 @@ static int ufshcd_slave_alloc(struct scsi_device *sdev) * ufshcd_change_queue_depth - change queue depth * @sdev: pointer to SCSI device * @depth: required depth to set - * @reason: reason for changing the depth * - * Change queue depth according to the reason and make sure - * the max. limits are not crossed. + * Change queue depth and make sure the max. limits are not crossed. */ -static int ufshcd_change_queue_depth(struct scsi_device *sdev, - int depth, int reason) +static int ufshcd_change_queue_depth(struct scsi_device *sdev, int depth) { struct ufs_hba *hba = shost_priv(sdev->host); if (depth > hba->nutrs) depth = hba->nutrs; - - scsi_adjust_queue_depth(sdev, depth); - return depth; + return scsi_change_queue_depth(sdev, depth); } /** diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 0f7e4c7ff8c..22e70126425 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -682,17 +682,13 @@ static int virtscsi_device_reset(struct scsi_cmnd *sc) * virtscsi_change_queue_depth() - Change a virtscsi target's queue depth * @sdev: Virtscsi target whose queue depth to change * @qdepth: New queue depth - * @reason: Reason for the queue depth change. */ -static int virtscsi_change_queue_depth(struct scsi_device *sdev, - int qdepth, - int reason) +static int virtscsi_change_queue_depth(struct scsi_device *sdev, int qdepth) { struct Scsi_Host *shost = sdev->host; int max_depth = shost->cmd_per_lun; - scsi_adjust_queue_depth(sdev, min(max_depth, qdepth)); - return sdev->queue_depth; + return scsi_change_queue_depth(sdev, min(max_depth, qdepth)); } static int virtscsi_abort(struct scsi_cmnd *sc) diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c index 03ad24be728..ade1f1d013b 100644 --- a/drivers/scsi/vmw_pvscsi.c +++ b/drivers/scsi/vmw_pvscsi.c @@ -504,19 +504,11 @@ static void pvscsi_setup_all_rings(const struct pvscsi_adapter *adapter) } } -static int pvscsi_change_queue_depth(struct scsi_device *sdev, - int qdepth, - int reason) +static int pvscsi_change_queue_depth(struct scsi_device *sdev, int qdepth) { - if (reason != SCSI_QDEPTH_DEFAULT) - /* - * We support only changing default. - */ - return -EOPNOTSUPP; - if (!sdev->tagged_supported) qdepth = 1; - scsi_adjust_queue_depth(sdev, qdepth); + scsi_change_queue_depth(sdev, qdepth); if (sdev->inquiry_len > 7) sdev_printk(KERN_INFO, sdev, diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c index 32674236fec..f94d73611ab 100644 --- a/drivers/scsi/wd7000.c +++ b/drivers/scsi/wd7000.c @@ -1653,7 +1653,6 @@ static struct scsi_host_template driver_template = { .can_queue = WD7000_Q, .this_id = 7, .sg_tablesize = WD7000_SG, - .cmd_per_lun = 1, .unchecked_isa_dma = 1, .use_clustering = ENABLE_CLUSTERING, }; diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 670b75a6224..4d1b7224a7f 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -110,19 +110,6 @@ static struct device_driver tcm_loop_driverfs = { */ struct device *tcm_loop_primary; -/* - * Copied from drivers/scsi/libfc/fc_fcp.c:fc_change_queue_depth() and - * drivers/scsi/libiscsi.c:iscsi_change_queue_depth() - */ -static int tcm_loop_change_queue_depth( - struct scsi_device *sdev, - int depth, - int reason) -{ - scsi_adjust_queue_depth(sdev, depth); - return sdev->queue_depth; -} - static void tcm_loop_submission_work(struct work_struct *work) { struct tcm_loop_cmd *tl_cmd = @@ -397,7 +384,7 @@ static struct scsi_host_template tcm_loop_driver_template = { .proc_name = "tcm_loopback", .name = "TCM_Loopback", .queuecommand = tcm_loop_queuecommand, - .change_queue_depth = tcm_loop_change_queue_depth, + .change_queue_depth = scsi_change_queue_depth, .change_queue_type = scsi_change_queue_type, .eh_abort_handler = tcm_loop_abort_task, .eh_device_reset_handler = tcm_loop_device_reset, diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 33f211b56a4..4047edfb64e 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -799,7 +799,7 @@ static int uas_slave_configure(struct scsi_device *sdev) if (devinfo->flags & US_FL_NO_REPORT_OPCODES) sdev->no_report_opcodes = 1; - scsi_adjust_queue_depth(sdev, devinfo->qdepth - 2); + scsi_change_queue_depth(sdev, devinfo->qdepth - 2); return 0; } diff --git a/include/linux/libata.h b/include/linux/libata.h index bd5fefeaf54..bfbc817c34e 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1191,9 +1191,9 @@ extern void ata_scsi_unlock_native_capacity(struct scsi_device *sdev); extern int ata_scsi_slave_config(struct scsi_device *sdev); extern void ata_scsi_slave_destroy(struct scsi_device *sdev); extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, - int queue_depth, int reason); + int queue_depth); extern int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, - int queue_depth, int reason); + int queue_depth); extern struct ata_device *ata_dev_pair(struct ata_device *adev); extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev); extern void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap); diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h index 2e0cf568a9c..93d14daf099 100644 --- a/include/scsi/libfc.h +++ b/include/scsi/libfc.h @@ -1105,7 +1105,6 @@ int fc_eh_abort(struct scsi_cmnd *); int fc_eh_device_reset(struct scsi_cmnd *); int fc_eh_host_reset(struct scsi_cmnd *); int fc_slave_alloc(struct scsi_device *); -int fc_change_queue_depth(struct scsi_device *, int qdepth, int reason); /* * ELS/CT interface diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 728c9ad9feb..4d1c46aac33 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -378,8 +378,6 @@ struct iscsi_host { /* * scsi host template */ -extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth, - int reason); extern int iscsi_eh_abort(struct scsi_cmnd *sc); extern int iscsi_eh_recover_target(struct scsi_cmnd *sc); extern int iscsi_eh_session_reset(struct scsi_cmnd *sc); diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index ef7872c20da..1f8b33ec612 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -704,8 +704,7 @@ int sas_queue_up(struct sas_task *task); extern int sas_queuecommand(struct Scsi_Host * ,struct scsi_cmnd *); extern int sas_target_alloc(struct scsi_target *); extern int sas_slave_configure(struct scsi_device *); -extern int sas_change_queue_depth(struct scsi_device *, int new_depth, - int reason); +extern int sas_change_queue_depth(struct scsi_device *, int new_depth); extern int sas_change_queue_type(struct scsi_device *, int qt); extern int sas_bios_param(struct scsi_device *, struct block_device *, diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 0aeaa003c3c..6364e23454d 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -380,7 +380,7 @@ extern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *, #define __shost_for_each_device(sdev, shost) \ list_for_each_entry((sdev), &((shost)->__devices), siblings) -extern void scsi_adjust_queue_depth(struct scsi_device *, int); +extern int scsi_change_queue_depth(struct scsi_device *, int); extern int scsi_track_queue_full(struct scsi_device *, int); extern int scsi_set_medium_removal(struct scsi_device *, char); diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index a0b13a5cd25..c8a462ef9a4 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -46,10 +46,6 @@ struct blk_queue_tags; #define DISABLE_CLUSTERING 0 #define ENABLE_CLUSTERING 1 -enum { - SCSI_QDEPTH_DEFAULT, /* default requested change, e.g. from sysfs */ -}; - struct scsi_host_template { struct module *module; const char *name; @@ -193,7 +189,7 @@ struct scsi_host_template { * Things currently recommended to be handled at this time include: * * 1. Setting the device queue depth. Proper setting of this is - * described in the comments for scsi_adjust_queue_depth. + * described in the comments for scsi_change_queue_depth. * 2. Determining if the device supports the various synchronous * negotiation protocols. The device struct will already have * responded to INQUIRY and the results of the standard items @@ -279,7 +275,7 @@ struct scsi_host_template { * * Status: OPTIONAL */ - int (* change_queue_depth)(struct scsi_device *, int, int); + int (* change_queue_depth)(struct scsi_device *, int); /* * Fill in this function to allow the changing of tag types -- cgit v1.2.3-70-g09d2