Skip to contentSkip to conversation

handles queue_depth adjustments in scsi_error.c

PATCH In review Vasu Dev 9 participants 29 messages Sep 3, 2009 – Oct 15, 2009 2 messages not in the archive

Subsystems (21)
SCSI PowerPC s390 libata +17 more subsystems
lore
Share & tools
lore

Vasu Dev

author
#0 lore raw

cover handles queue_depth adjustments in scsi_error.c

This patch series moves the QUEUE_FULL and then the ramp up code from drivers like qla2xxx and lpfc to scsi-ml. The change_queue_depth callback is used to allow the drivers to adjust the queue depth, so LLDs do not have to worry about parsing the sense, see some additional info on these changes in first RFC cover at:-

http://www.spinics.net/lists/linux-scsi/msg35959.html

I've tested this series with libfc/fcoe for queue_depth ramp down and up.

This series is based on scsi-misc -rc7 and also cleanly applies & works on top recently submitted 64 fcoe patches series by Rob "[PATCH 00/64] libfc, libfcoe and fcoe updates for scsi-misc"

I'm posting this series with Mike and Christof patches per this mail thread discussion
http://marc.info/?l=linux-scsi&m=125196587107768&w=2

---

Christof Schmitt (1):
zfcp: Adapt change_queue_depth for queue full tracking

Mike Christie (4):
drivers: convert fc drivers calling scsi_track_queue_full
drivers: convert drivers setting the change_queue_depth callback scsi error: have scsi-ml call change_queue_depth to handle QUEUE_FULL
scsi-ml: modify change_queue_depth to take in reason why it is being called

Vasu Dev (5):
libfc: adds queue_depth ramp up to libfc
fcoe, libfc: fix an libfc issue with queue ramp down in libfc
scsi: add common queue_depth ramp up code
scsi: adds sdev->queue_ramp_up_period to sysfs
scsi: updates sdev to add queue_depth ramp up code

 drivers/ata/libata-scsi.c             |    7 +++
 drivers/ata/sata_nv.c                 |    2 -
 drivers/message/fusion/mptscsih.c     |    9 +++-
 drivers/message/fusion/mptscsih.h     |    3 +
 drivers/s390/scsi/zfcp_scsi.c         |   21 ++++++++-
 drivers/scsi/3w-9xxx.c                |    5 ++
 drivers/scsi/3w-xxxx.c                |    5 ++
 drivers/scsi/53c700.c                 |    5 ++
 drivers/scsi/aacraid/linit.c          |    6 ++-
 drivers/scsi/arcmsr/arcmsr_hba.c      |    5 ++
 drivers/scsi/fcoe/fcoe.c              |    2 -
 drivers/scsi/hptiop.c                 |    5 ++
 drivers/scsi/ibmvscsi/ibmvfc.c        |    7 +++
 drivers/scsi/ibmvscsi/ibmvscsi.c      |    7 +++
 drivers/scsi/ipr.c                    |    7 +++
 drivers/scsi/libfc/fc_fcp.c           |   47 ++++++++++-----------
 drivers/scsi/libiscsi.c               |    4 +-
 drivers/scsi/libsas/sas_scsi_host.c   |    6 ++-
 drivers/scsi/lpfc/lpfc_scsi.c         |   75 ++++++++++++++++++---------------
 drivers/scsi/megaraid/megaraid_mbox.c |    7 +++
 drivers/scsi/mpt2sas/mpt2sas_scsih.c  |   10 +++-
 drivers/scsi/qla2xxx/qla_isr.c        |   32 --------------
 drivers/scsi/qla2xxx/qla_os.c         |   32 +++++++++++++-
 drivers/scsi/scsi.c                   |   10 ++++
 drivers/scsi/scsi_error.c             |   62 +++++++++++++++++++++++++++
 drivers/scsi/scsi_scan.c              |    1 
 drivers/scsi/scsi_sysfs.c             |   41 +++++++++++++++++-
 include/linux/libata.h                |    2 -
 include/scsi/libfc.h                  |    2 -
 include/scsi/libiscsi.h               |    3 +
 include/scsi/libsas.h                 |    3 +
 include/scsi/scsi_device.h            |    8 ++--
 include/scsi/scsi_host.h              |    8 +++-
 33 files changed, 317 insertions(+), 132 deletions(-)
author
#1 lore raw

PATCH 1/10 scsi-ml: modify change_queue_depth to take in reason why it is being called

From: Mike Christie <[email protected]>

This patch modifies scsi_host_tematepl->change_queue_depth so that it takes an argument indicating why it is being called. This will be used so that if a LLD needs to do some extra processing when handling queue fulls or later ramp ups, it can do so.

To simplify the review, this patch only modifies scsi-ml. The next patches will convert each driver.

---

 drivers/scsi/scsi_sysfs.c |    3 ++-
 include/scsi/scsi_host.h  |    8 +++++++-
 2 files changed, 9 insertions(+), 2 deletions(-)
drivers/scsi/scsi_sysfs.c +2 -1
index 91482f2..4530626 100644
@@ -766,7 +766,8 @@ sdev_store_queue_depth_rw(struct device *dev, struct device_attribute *attr,
 	if (depth < 1)
 		return -EINVAL;
 
-	retval = sht->change_queue_depth(sdev, depth);
+	retval = sht->change_queue_depth(sdev, depth,
+					 SCSI_QDEPTH_DEFAULT);
 	if (retval < 0)
 		return retval;
 
include/scsi/scsi_host.h +7 -1
index b62a097..854d510 100644
@@ -43,6 +43,12 @@ struct blk_queue_tags;
 #define DISABLE_CLUSTERING 0
 #define ENABLE_CLUSTERING 1
 
+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 threshhold event */
+};
+
 struct scsi_host_template {
 	struct module *module;
 	const char *name;
@@ -294,7 +300,7 @@ struct scsi_host_template {
 	 *
 	 * Status: OPTIONAL
 	 */
-	int (* change_queue_depth)(struct scsi_device *, int);
+	int (* change_queue_depth)(struct scsi_device *, int, int);
 
 	/*
 	 * Fill in this function to allow the changing of tag types
author
#2 lore raw

PATCH 2/10 scsi error: have scsi-ml call change_queue_depth to handle QUEUE_FULL

In reply to Vasu Dev

From: Mike Christie <[email protected]>

This has scsi-ml call the change_queue_depth functions when we get a QUEUE_FULL. It will only change the queue depth if change_queue_depth is set because the LLD may have to modify some internal resources, so I thought this would be the safest route.

---

 drivers/scsi/scsi_error.c |   26 +++++++++++++++++++++++++-
 1 files changed, 25 insertions(+), 1 deletions(-)
drivers/scsi/scsi_error.c +25 -1
index 877204d..7d1b862 100644
@@ -331,6 +331,27 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
 	}
 }
 
+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)
+		return;
+
+	shost_for_each_device(tmp_sdev, sdev->host) {
+		if (tmp_sdev->id != sdev->id)
+			continue;
+		/*
+		 * We do not know the number of commands that were at
+		 * 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_eh_completed_normally - Disposition a eh cmd on return from LLD.
  * @scmd:	SCSI cmd to examine.
@@ -387,8 +408,10 @@ static int scsi_eh_completed_normally(struct scsi_cmnd *scmd)
 		 * let issuer deal with this, it could be just fine
 		 */
 		return SUCCESS;
-	case BUSY:
 	case QUEUE_FULL:
+		scsi_handle_queue_full(scmd->device);
+		/* fall through */
+	case BUSY:
 	default:
 		return FAILED;
 	}
@@ -1384,6 +1407,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
 	 */
 	switch (status_byte(scmd->result)) {
 	case QUEUE_FULL:
+		scsi_handle_queue_full(scmd->device);
 		/*
 		 * the case of trying to send too many commands to a
 		 * tagged queueing device.
author
#3 lore raw

PATCH v2 2/10 scsi error: have scsi-ml call change_queue_depth to handle QUEUE_FULL

From: Mike Christie <[email protected]>

This has scsi-ml call the change_queue_depth functions when we get a QUEUE_FULL. It will only change the queue depth if change_queue_depth is set because the LLD may have to modify some internal resources, so I thought this would be the safest route.

-v2
Limits change_queue_depth to only all luns of target by adding channel check while iterating for all luns of Scsi_Host. This is same as currently qla2xxx FC HBA does on QUEUE_FULL event.

---

 drivers/scsi/scsi_error.c |   27 ++++++++++++++++++++++++++-
 1 files changed, 26 insertions(+), 1 deletions(-)
drivers/scsi/scsi_error.c +26 -1
index 877204d..3eac11b 100644
@@ -331,6 +331,28 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
 	}
 }
 
+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)
+		return;
+
+	shost_for_each_device(tmp_sdev, sdev->host) {
+		if ((tmp_sdev->channel != sdev->channel) ||
+		    (tmp_sdev->id != sdev->id))
+			continue;
+		/*
+		 * We do not know the number of commands that were at
+		 * 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_eh_completed_normally - Disposition a eh cmd on return from LLD.
  * @scmd:	SCSI cmd to examine.
@@ -387,8 +409,10 @@ static int scsi_eh_completed_normally(struct scsi_cmnd *scmd)
 		 * let issuer deal with this, it could be just fine
 		 */
 		return SUCCESS;
-	case BUSY:
 	case QUEUE_FULL:
+		scsi_handle_queue_full(scmd->device);
+		/* fall through */
+	case BUSY:
 	default:
 		return FAILED;
 	}
@@ -1384,6 +1408,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
 	 */
 	switch (status_byte(scmd->result)) {
 	case QUEUE_FULL:
+		scsi_handle_queue_full(scmd->device);
 		/*
 		 * the case of trying to send too many commands to a
 		 * tagged queueing device.
author
#4 lore raw

PATCH 3/10 drivers: convert drivers setting the change_queue_depth callback

In reply to Vasu Dev

From: Mike Christie <[email protected]>

This is a simple port of the drivers setting a change_queue_depth callback but were not tracking queue fulls. In the patch I just have these LLDs adjust the queue depth if the user was requesting it.

Patch is only compile tested.

---

 drivers/ata/libata-scsi.c             |    7 ++++++-
 drivers/ata/sata_nv.c                 |    2 +-
 drivers/message/fusion/mptscsih.c     |    9 +++++++--
 drivers/message/fusion/mptscsih.h     |    3 ++-
 drivers/s390/scsi/zfcp_scsi.c         |    5 ++++-
 drivers/scsi/3w-9xxx.c                |    5 ++++-
 drivers/scsi/3w-xxxx.c                |    5 ++++-
 drivers/scsi/53c700.c                 |    5 ++++-
 drivers/scsi/aacraid/linit.c          |    6 +++++-
 drivers/scsi/arcmsr/arcmsr_hba.c      |    5 ++++-
 drivers/scsi/hptiop.c                 |    5 ++++-
 drivers/scsi/ibmvscsi/ibmvfc.c        |    7 ++++++-
 drivers/scsi/ibmvscsi/ibmvscsi.c      |    7 ++++++-
 drivers/scsi/ipr.c                    |    7 ++++++-
 drivers/scsi/libfc/fc_fcp.c           |    4 +++-
 drivers/scsi/libiscsi.c               |    4 +++-
 drivers/scsi/libsas/sas_scsi_host.c   |    6 +++++-
 drivers/scsi/megaraid/megaraid_mbox.c |    7 ++++++-
 drivers/scsi/mpt2sas/mpt2sas_scsih.c  |   10 +++++++---
 drivers/scsi/qla2xxx/qla_os.c         |    6 ++++--
 include/linux/libata.h                |    2 +-
 include/scsi/libfc.h                  |    2 +-
 include/scsi/libiscsi.h               |    3 ++-
 include/scsi/libsas.h                 |    3 ++-
 24 files changed, 97 insertions(+), 28 deletions(-)
drivers/ata/libata-scsi.c +6 -1
index d0dfeef..050fae6 100644
@@ -1212,6 +1212,7 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)
  *	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
@@ -1223,12 +1224,16 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)
  *	RETURNS:
  *	Newly configured queue depth.
  */
-int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
+int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth,
+				int reason)
 {
 	struct ata_port *ap = ata_shost_to_port(sdev->host);
 	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;
 
drivers/ata/sata_nv.c +1 -1
index 86a4058..9bb4afb 100644
@@ -1963,7 +1963,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);
+		ata_scsi_change_queue_depth(sdev, 1, SCSI_QDEPTH_DEFAULT);
 		ata_dev_printk(dev, KERN_NOTICE,
 			"Disabling SWNCQ mode (depth %x)\n", sdev->queue_depth);
 	}
drivers/message/fusion/mptscsih.c +7 -2
index 0e402eb..5af9edb 100644
@@ -2265,11 +2265,12 @@ 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)
+mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 {
 	MPT_SCSI_HOST		*hd = shost_priv(sdev->host);
 	VirtTarget 		*vtarget;
@@ -2281,6 +2282,9 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
 	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,7 +2351,8 @@ 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);
+	mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH,
+				    SCSI_QDEPTH_DEFAULT);
 	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 		"tagged %d, simple %d, ordered %d\n",
 		ioc->name,sdev->tagged_supported, sdev->simple_tags,
drivers/message/fusion/mptscsih.h +2 -1
index e0b33e0..45a5ff3 100644
@@ -128,7 +128,8 @@ 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);
+extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				       int reason);
 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[];
drivers/s390/scsi/zfcp_scsi.c +4 -1
index 6925a17..bdff1bf 100644
@@ -28,8 +28,11 @@ char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *fcp_rsp_iu)
 	return fcp_sns_info_ptr;
 }
 
-static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth)
+static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth,
+					int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
 	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
 	return sdev->queue_depth;
 }
drivers/scsi/3w-9xxx.c +4 -1
index 36c21b1..f7d52d8 100644
@@ -186,8 +186,11 @@ static ssize_t twa_show_stats(struct device *dev,
 } /* 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)
+static int twa_change_queue_depth(struct scsi_device *sdev, int queue_depth,
+				  int reason)
 {
+	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, MSG_ORDERED_TAG, queue_depth);
drivers/scsi/3w-xxxx.c +4 -1
index faa0fcf..927f5ce 100644
@@ -521,8 +521,11 @@ static ssize_t tw_show_stats(struct device *dev, struct device_attribute *attr,
 } /* 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)
+static int tw_change_queue_depth(struct scsi_device *sdev, int queue_depth,
+				 int reason)
 {
+	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, MSG_ORDERED_TAG, queue_depth);
drivers/scsi/53c700.c +4 -1
index f5a9add..a5a493d 100644
@@ -2082,8 +2082,11 @@ NCR_700_slave_destroy(struct scsi_device *SDp)
 }
 
 static int
-NCR_700_change_queue_depth(struct scsi_device *SDp, int depth)
+NCR_700_change_queue_depth(struct scsi_device *SDp, int depth, int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (depth > NCR_700_MAX_TAGS)
 		depth = NCR_700_MAX_TAGS;
 
drivers/scsi/aacraid/linit.c +5 -1
index 9b97c3e..e9373a2 100644
@@ -472,8 +472,12 @@ 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)
+static int aac_change_queue_depth(struct scsi_device *sdev, int depth,
+				  int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (sdev->tagged_supported && (sdev->type == TYPE_DISK) &&
 	    (sdev_channel(sdev) == CONTAINER_CHANNEL)) {
 		struct scsi_device * dev;
drivers/scsi/arcmsr/arcmsr_hba.c +4 -1
index 80aac01..47d5d19 100644
@@ -98,8 +98,11 @@ static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb);
 static const char *arcmsr_info(struct Scsi_Host *);
 static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
 static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev,
-								int queue_depth)
+					  int queue_depth, int reason)
 {
+	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, MSG_ORDERED_TAG, queue_depth);
drivers/scsi/hptiop.c +4 -1
index c596ab5..19620e9 100644
@@ -847,10 +847,13 @@ static int hptiop_reset(struct scsi_cmnd *scp)
 }
 
 static int hptiop_adjust_disk_queue_depth(struct scsi_device *sdev,
-						int queue_depth)
+					  int queue_depth, int reason)
 {
 	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, MSG_ORDERED_TAG, queue_depth);
drivers/scsi/ibmvscsi/ibmvfc.c +6 -1
index bb2c696..07e2e35 100644
@@ -2478,12 +2478,17 @@ static int ibmvfc_slave_configure(struct scsi_device *sdev)
  * ibmvfc_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 ibmvfc_change_queue_depth(struct scsi_device *sdev, int qdepth)
+static int ibmvfc_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				     int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (qdepth > IBMVFC_MAX_CMDS_PER_LUN)
 		qdepth = IBMVFC_MAX_CMDS_PER_LUN;
 
drivers/scsi/ibmvscsi/ibmvscsi.c +6 -1
index 9928704..15fa8c7 100644
@@ -1638,12 +1638,17 @@ static int ibmvscsi_slave_configure(struct scsi_device *sdev)
  * ibmvscsi_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 ibmvscsi_change_queue_depth(struct scsi_device *sdev, int qdepth)
+static int ibmvscsi_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				       int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (qdepth > IBMVSCSI_MAX_CMDS_PER_LUN)
 		qdepth = IBMVSCSI_MAX_CMDS_PER_LUN;
 
drivers/scsi/ipr.c +6 -1
index 5f04550..d40d5c7 100644
@@ -3367,16 +3367,21 @@ static int ipr_free_dump(struct ipr_ioa_cfg *ioa_cfg) { return 0; };
  * ipr_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 ipr_change_queue_depth(struct scsi_device *sdev, int qdepth)
+static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				  int reason)
 {
 	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;
 
drivers/scsi/libfc/fc_fcp.c +3 -1
index 7d5ffcb..20b88cd 100644
@@ -2062,8 +2062,10 @@ int fc_slave_alloc(struct scsi_device *sdev)
 }
 EXPORT_SYMBOL(fc_slave_alloc);
 
-int fc_change_queue_depth(struct scsi_device *sdev, int qdepth)
+int fc_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
 	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
 	return sdev->queue_depth;
 }
drivers/scsi/libiscsi.c +3 -1
index a751f62..dc4f86a 100644
@@ -1539,8 +1539,10 @@ fault:
 }
 EXPORT_SYMBOL_GPL(iscsi_queuecommand);
 
-int iscsi_change_queue_depth(struct scsi_device *sdev, int depth)
+int iscsi_change_queue_depth(struct scsi_device *sdev, int depth, int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
 	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
 	return sdev->queue_depth;
 }
drivers/scsi/libsas/sas_scsi_host.c +5 -1
index 1c558d3..14b1319 100644
@@ -820,10 +820,14 @@ void sas_slave_destroy(struct scsi_device *scsi_dev)
 		ata_port_disable(dev->sata_dev.ap);
 }
 
-int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth)
+int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth,
+			   int reason)
 {
 	int res = min(new_depth, SAS_MAX_QD);
 
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (scsi_dev->tagged_supported)
 		scsi_adjust_queue_depth(scsi_dev, scsi_get_tag_type(scsi_dev),
 					res);
drivers/scsi/megaraid/megaraid_mbox.c +6 -1
index 234f0b7..fd181c2 100644
@@ -335,12 +335,17 @@ static struct device_attribute *megaraid_sdev_attrs[] = {
  * 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)
+static int megaraid_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				       int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (qdepth > MBOX_MAX_SCSI_CMDS)
 		qdepth = MBOX_MAX_SCSI_CMDS;
 	scsi_adjust_queue_depth(sdev, 0, qdepth);
drivers/scsi/mpt2sas/mpt2sas_scsih.c +7 -3
index 2e9a444..6e6ee0d 100644
@@ -1085,16 +1085,20 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
  * _scsih_change_queue_depth - setting device queue depth
  * @sdev: scsi device struct
  * @qdepth: requested queue depth
+ * @reason: calling context
  *
  * Returns queue depth.
  */
 static int
-_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
+_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 {
 	struct Scsi_Host *shost = sdev->host;
 	int max_depth;
 	int tag_type;
 
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	max_depth = shost->can_queue;
 	if (!sdev->tagged_supported)
 		max_depth = 1;
@@ -1524,7 +1528,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);
+		_scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
 		return 0;
 	}
 
@@ -1570,7 +1574,7 @@ _scsih_slave_configure(struct scsi_device *sdev)
 			_scsih_display_sata_capabilities(ioc, sas_device, sdev);
 	}
 
-	_scsih_change_queue_depth(sdev, qdepth);
+	_scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
 
 	if (ssp_target)
 		sas_read_port_mode_page(sdev);
drivers/scsi/qla2xxx/qla_os.c +4 -2
index d7b2713..c05c460 100644
@@ -137,7 +137,7 @@ 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);
+static int qla2x00_change_queue_depth(struct scsi_device *, int, int);
 static int qla2x00_change_queue_type(struct scsi_device *, int);
 
 struct scsi_host_template qla2xxx_driver_template = {
@@ -1223,8 +1223,10 @@ qla2xxx_slave_destroy(struct scsi_device *sdev)
 }
 
 static int
-qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth)
+qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
 	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
 	return sdev->queue_depth;
 }
include/linux/libata.h +1 -1
index e5b6e33..a4744c8 100644
@@ -1010,7 +1010,7 @@ extern int ata_std_bios_param(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 queue_depth, int reason);
 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);
 
include/scsi/libfc.h +1 -1
index c2b928c..861a3b5 100644
@@ -904,7 +904,7 @@ int fc_slave_alloc(struct scsi_device *sdev);
 /*
  * Adjust the queue depth.
  */
-int fc_change_queue_depth(struct scsi_device *sdev, int qdepth);
+int fc_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason);
 
 /*
  * Change the tag type.
include/scsi/libiscsi.h +2 -1
index 61afeb5..b0188b6 100644
@@ -332,7 +332,8 @@ struct iscsi_host {
 /*
  * scsi host template
  */
-extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth);
+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_target_reset(struct scsi_cmnd *sc);
 extern int iscsi_eh_device_reset(struct scsi_cmnd *sc);
include/scsi/libsas.h +2 -1
index e78d3b6..9eaa3f0 100644
@@ -634,7 +634,8 @@ extern int sas_target_alloc(struct scsi_target *);
 extern int sas_slave_alloc(struct scsi_device *);
 extern int sas_slave_configure(struct scsi_device *);
 extern void sas_slave_destroy(struct scsi_device *);
-extern int sas_change_queue_depth(struct scsi_device *, int new_depth);
+extern int sas_change_queue_depth(struct scsi_device *, int new_depth,
+				  int reason);
 extern int sas_change_queue_type(struct scsi_device *, int qt);
 extern int sas_bios_param(struct scsi_device *,
 			  struct block_device *,
author
#5 lore raw

PATCH v2 3/10 drivers: convert drivers setting the change_queue_depth callback

From: Mike Christie <[email protected]>

This is a simple port of the drivers setting a change_queue_depth callback but were not tracking queue fulls. In the patch I just have these LLDs adjust the queue depth if the user was requesting it.

Patch is only compile tested.

-v2
Also converted pmcraid_change_queue_depth and then verified
all modules compile using "make allmodconfig" for any new build warnings on X86_64.

---

 drivers/ata/libata-scsi.c             |    7 ++++++-
 drivers/ata/sata_nv.c                 |    2 +-
 drivers/message/fusion/mptscsih.c     |    9 +++++++--
 drivers/message/fusion/mptscsih.h     |    3 ++-
 drivers/s390/scsi/zfcp_scsi.c         |    5 ++++-
 drivers/scsi/3w-9xxx.c                |    5 ++++-
 drivers/scsi/3w-xxxx.c                |    5 ++++-
 drivers/scsi/53c700.c                 |    5 ++++-
 drivers/scsi/aacraid/linit.c          |    6 +++++-
 drivers/scsi/arcmsr/arcmsr_hba.c      |    5 ++++-
 drivers/scsi/hptiop.c                 |    5 ++++-
 drivers/scsi/ibmvscsi/ibmvfc.c        |    7 ++++++-
 drivers/scsi/ibmvscsi/ibmvscsi.c      |    7 ++++++-
 drivers/scsi/ipr.c                    |    7 ++++++-
 drivers/scsi/libfc/fc_fcp.c           |    4 +++-
 drivers/scsi/libiscsi.c               |    4 +++-
 drivers/scsi/libsas/sas_scsi_host.c   |    6 +++++-
 drivers/scsi/megaraid/megaraid_mbox.c |    7 ++++++-
 drivers/scsi/mpt2sas/mpt2sas_scsih.c  |   10 +++++++---
 drivers/scsi/pmcraid.c                |    7 ++++++-
 drivers/scsi/qla2xxx/qla_os.c         |    6 ++++--
 include/linux/libata.h                |    2 +-
 include/scsi/libfc.h                  |    2 +-
 include/scsi/libiscsi.h               |    3 ++-
 include/scsi/libsas.h                 |    3 ++-
 25 files changed, 103 insertions(+), 29 deletions(-)
drivers/ata/libata-scsi.c +6 -1
index d0dfeef..050fae6 100644
@@ -1212,6 +1212,7 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)
  *	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
@@ -1223,12 +1224,16 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)
  *	RETURNS:
  *	Newly configured queue depth.
  */
-int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
+int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth,
+				int reason)
 {
 	struct ata_port *ap = ata_shost_to_port(sdev->host);
 	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;
 
drivers/ata/sata_nv.c +1 -1
index 86a4058..9bb4afb 100644
@@ -1963,7 +1963,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);
+		ata_scsi_change_queue_depth(sdev, 1, SCSI_QDEPTH_DEFAULT);
 		ata_dev_printk(dev, KERN_NOTICE,
 			"Disabling SWNCQ mode (depth %x)\n", sdev->queue_depth);
 	}
drivers/message/fusion/mptscsih.c +7 -2
index c295786..e132c17 100644
@@ -2275,11 +2275,12 @@ 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)
+mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 {
 	MPT_SCSI_HOST		*hd = shost_priv(sdev->host);
 	VirtTarget 		*vtarget;
@@ -2291,6 +2292,9 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
 	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;
@@ -2357,7 +2361,8 @@ 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);
+	mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH,
+				    SCSI_QDEPTH_DEFAULT);
 	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 		"tagged %d, simple %d, ordered %d\n",
 		ioc->name,sdev->tagged_supported, sdev->simple_tags,
drivers/message/fusion/mptscsih.h +2 -1
index e0b33e0..45a5ff3 100644
@@ -128,7 +128,8 @@ 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);
+extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				       int reason);
 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[];
drivers/s390/scsi/zfcp_scsi.c +4 -1
index 3ff726a..c46e04c 100644
@@ -29,8 +29,11 @@ char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *fcp_rsp_iu)
 	return fcp_sns_info_ptr;
 }
 
-static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth)
+static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth,
+					int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
 	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
 	return sdev->queue_depth;
 }
drivers/scsi/3w-9xxx.c +4 -1
index 36c21b1..f7d52d8 100644
@@ -186,8 +186,11 @@ static ssize_t twa_show_stats(struct device *dev,
 } /* 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)
+static int twa_change_queue_depth(struct scsi_device *sdev, int queue_depth,
+				  int reason)
 {
+	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, MSG_ORDERED_TAG, queue_depth);
drivers/scsi/3w-xxxx.c +4 -1
index faa0fcf..927f5ce 100644
@@ -521,8 +521,11 @@ static ssize_t tw_show_stats(struct device *dev, struct device_attribute *attr,
 } /* 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)
+static int tw_change_queue_depth(struct scsi_device *sdev, int queue_depth,
+				 int reason)
 {
+	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, MSG_ORDERED_TAG, queue_depth);
drivers/scsi/53c700.c +4 -1
index f5a9add..a5a493d 100644
@@ -2082,8 +2082,11 @@ NCR_700_slave_destroy(struct scsi_device *SDp)
 }
 
 static int
-NCR_700_change_queue_depth(struct scsi_device *SDp, int depth)
+NCR_700_change_queue_depth(struct scsi_device *SDp, int depth, int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (depth > NCR_700_MAX_TAGS)
 		depth = NCR_700_MAX_TAGS;
 
drivers/scsi/aacraid/linit.c +5 -1
index 9b97c3e..e9373a2 100644
@@ -472,8 +472,12 @@ 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)
+static int aac_change_queue_depth(struct scsi_device *sdev, int depth,
+				  int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (sdev->tagged_supported && (sdev->type == TYPE_DISK) &&
 	    (sdev_channel(sdev) == CONTAINER_CHANNEL)) {
 		struct scsi_device * dev;
drivers/scsi/arcmsr/arcmsr_hba.c +4 -1
index 80aac01..47d5d19 100644
@@ -98,8 +98,11 @@ static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb);
 static const char *arcmsr_info(struct Scsi_Host *);
 static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
 static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev,
-								int queue_depth)
+					  int queue_depth, int reason)
 {
+	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, MSG_ORDERED_TAG, queue_depth);
drivers/scsi/hptiop.c +4 -1
index c596ab5..19620e9 100644
@@ -847,10 +847,13 @@ static int hptiop_reset(struct scsi_cmnd *scp)
 }
 
 static int hptiop_adjust_disk_queue_depth(struct scsi_device *sdev,
-						int queue_depth)
+					  int queue_depth, int reason)
 {
 	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, MSG_ORDERED_TAG, queue_depth);
drivers/scsi/ibmvscsi/ibmvfc.c +6 -1
index bb2c696..07e2e35 100644
@@ -2478,12 +2478,17 @@ static int ibmvfc_slave_configure(struct scsi_device *sdev)
  * ibmvfc_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 ibmvfc_change_queue_depth(struct scsi_device *sdev, int qdepth)
+static int ibmvfc_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				     int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (qdepth > IBMVFC_MAX_CMDS_PER_LUN)
 		qdepth = IBMVFC_MAX_CMDS_PER_LUN;
 
drivers/scsi/ibmvscsi/ibmvscsi.c +6 -1
index 9928704..15fa8c7 100644
@@ -1638,12 +1638,17 @@ static int ibmvscsi_slave_configure(struct scsi_device *sdev)
  * ibmvscsi_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 ibmvscsi_change_queue_depth(struct scsi_device *sdev, int qdepth)
+static int ibmvscsi_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				       int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (qdepth > IBMVSCSI_MAX_CMDS_PER_LUN)
 		qdepth = IBMVSCSI_MAX_CMDS_PER_LUN;
 
drivers/scsi/ipr.c +6 -1
index 5f04550..d40d5c7 100644
@@ -3367,16 +3367,21 @@ static int ipr_free_dump(struct ipr_ioa_cfg *ioa_cfg) { return 0; };
  * ipr_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 ipr_change_queue_depth(struct scsi_device *sdev, int qdepth)
+static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				  int reason)
 {
 	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;
 
drivers/scsi/libfc/fc_fcp.c +3 -1
index 59a4408..d748e03 100644
@@ -2062,8 +2062,10 @@ int fc_slave_alloc(struct scsi_device *sdev)
 }
 EXPORT_SYMBOL(fc_slave_alloc);
 
-int fc_change_queue_depth(struct scsi_device *sdev, int qdepth)
+int fc_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
 	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
 	return sdev->queue_depth;
 }
drivers/scsi/libiscsi.c +3 -1
index 8dc73c4..e3879e6 100644
@@ -1643,8 +1643,10 @@ fault:
 }
 EXPORT_SYMBOL_GPL(iscsi_queuecommand);
 
-int iscsi_change_queue_depth(struct scsi_device *sdev, int depth)
+int iscsi_change_queue_depth(struct scsi_device *sdev, int depth, int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
 	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
 	return sdev->queue_depth;
 }
drivers/scsi/libsas/sas_scsi_host.c +5 -1
index 1c558d3..14b1319 100644
@@ -820,10 +820,14 @@ void sas_slave_destroy(struct scsi_device *scsi_dev)
 		ata_port_disable(dev->sata_dev.ap);
 }
 
-int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth)
+int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth,
+			   int reason)
 {
 	int res = min(new_depth, SAS_MAX_QD);
 
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (scsi_dev->tagged_supported)
 		scsi_adjust_queue_depth(scsi_dev, scsi_get_tag_type(scsi_dev),
 					res);
drivers/scsi/megaraid/megaraid_mbox.c +6 -1
index 234f0b7..fd181c2 100644
@@ -335,12 +335,17 @@ static struct device_attribute *megaraid_sdev_attrs[] = {
  * 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)
+static int megaraid_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				       int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (qdepth > MBOX_MAX_SCSI_CMDS)
 		qdepth = MBOX_MAX_SCSI_CMDS;
 	scsi_adjust_queue_depth(sdev, 0, qdepth);
drivers/scsi/mpt2sas/mpt2sas_scsih.c +7 -3
index 774b345..c6f4cee 100644
@@ -1084,16 +1084,20 @@ _scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
  * _scsih_change_queue_depth - setting device queue depth
  * @sdev: scsi device struct
  * @qdepth: requested queue depth
+ * @reason: calling context
  *
  * Returns queue depth.
  */
 static int
-_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
+_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 {
 	struct Scsi_Host *shost = sdev->host;
 	int max_depth;
 	int tag_type;
 
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	max_depth = shost->can_queue;
 	if (!sdev->tagged_supported)
 		max_depth = 1;
@@ -1529,7 +1533,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);
+		_scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
 		return 0;
 	}
 
@@ -1575,7 +1579,7 @@ _scsih_slave_configure(struct scsi_device *sdev)
 			_scsih_display_sata_capabilities(ioc, sas_device, sdev);
 	}
 
-	_scsih_change_queue_depth(sdev, qdepth);
+	_scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
 
 	if (ssp_target)
 		sas_read_port_mode_page(sdev);
drivers/scsi/pmcraid.c +6 -1
index 4302f06..2ae3fce 100644
@@ -277,12 +277,17 @@ 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)
+static int pmcraid_change_queue_depth(struct scsi_device *scsi_dev, int depth,
+				      int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (depth > PMCRAID_MAX_CMD_PER_LUN)
 		depth = PMCRAID_MAX_CMD_PER_LUN;
 
drivers/scsi/qla2xxx/qla_os.c +4 -2
index 64ff147..16801ed 100644
@@ -138,7 +138,7 @@ 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);
+static int qla2x00_change_queue_depth(struct scsi_device *, int, int);
 static int qla2x00_change_queue_type(struct scsi_device *, int);
 
 struct scsi_host_template qla2xxx_driver_template = {
@@ -1235,8 +1235,10 @@ qla2xxx_slave_destroy(struct scsi_device *sdev)
 }
 
 static int
-qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth)
+qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
 	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
 	return sdev->queue_depth;
 }
include/linux/libata.h +1 -1
index e5b6e33..a4744c8 100644
@@ -1010,7 +1010,7 @@ extern int ata_std_bios_param(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 queue_depth, int reason);
 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);
 
include/scsi/libfc.h +1 -1
index 65dc9aa..9874ea7 100644
@@ -919,7 +919,7 @@ int fc_slave_alloc(struct scsi_device *sdev);
 /*
  * Adjust the queue depth.
  */
-int fc_change_queue_depth(struct scsi_device *sdev, int qdepth);
+int fc_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason);
 
 /*
  * Change the tag type.
include/scsi/libiscsi.h +2 -1
index 887e57e..d4142de 100644
@@ -332,7 +332,8 @@ struct iscsi_host {
 /*
  * scsi host template
  */
-extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth);
+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_target_reset(struct scsi_cmnd *sc);
 extern int iscsi_eh_device_reset(struct scsi_cmnd *sc);
include/scsi/libsas.h +2 -1
index e78d3b6..9eaa3f0 100644
@@ -634,7 +634,8 @@ extern int sas_target_alloc(struct scsi_target *);
 extern int sas_slave_alloc(struct scsi_device *);
 extern int sas_slave_configure(struct scsi_device *);
 extern void sas_slave_destroy(struct scsi_device *);
-extern int sas_change_queue_depth(struct scsi_device *, int new_depth);
+extern int sas_change_queue_depth(struct scsi_device *, int new_depth,
+				  int reason);
 extern int sas_change_queue_type(struct scsi_device *, int qt);
 extern int sas_bios_param(struct scsi_device *,
 			  struct block_device *,
author
#6 lore raw

PATCH 4/10 drivers: convert fc drivers calling scsi_track_queue_full

In reply to Vasu Dev

From: Mike Christie <[email protected]>

This converts the fc drivers that were using scsi_track_queue_full to track the queue full from the change_queue_depth callback.

I have not yet tested the qla2xxx or lpfc parts.

--
Adds check to ignore SCSI_QDEPTH_QFULL in case the ql2xqfulltracking is not set.

---

 drivers/scsi/libfc/fc_fcp.c    |   26 +++++---------
 drivers/scsi/lpfc/lpfc_scsi.c  |   75 ++++++++++++++++++++++------------------
 drivers/scsi/qla2xxx/qla_isr.c |   32 -----------------
 drivers/scsi/qla2xxx/qla_os.c  |   30 ++++++++++++++--
 4 files changed, 77 insertions(+), 86 deletions(-)
drivers/scsi/libfc/fc_fcp.c +9 -17
index 20b88cd..d919c2a 100644
@@ -1814,21 +1814,6 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
 			sc_cmd->result = DID_OK << 16;
 			if (fsp->scsi_resid)
 				CMD_RESID_LEN(sc_cmd) = fsp->scsi_resid;
-		} else if (fsp->cdb_status == QUEUE_FULL) {
-			struct scsi_device *tmp_sdev;
-			struct scsi_device *sdev = sc_cmd->device;
-
-			shost_for_each_device(tmp_sdev, sdev->host) {
-				if (tmp_sdev->id != sdev->id)
-					continue;
-
-				if (tmp_sdev->queue_depth > 1) {
-					scsi_track_queue_full(tmp_sdev,
-							      tmp_sdev->
-							      queue_depth - 1);
-				}
-			}
-			sc_cmd->result = (DID_OK << 16) | fsp->cdb_status;
 		} else {
 			/*
 			 * transport level I/O was ok but scsi
@@ -2064,9 +2049,16 @@ EXPORT_SYMBOL(fc_slave_alloc);
 
 int fc_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 {
-	if (reason != SCSI_QDEPTH_DEFAULT)
+	switch (reason) {
+	case SCSI_QDEPTH_DEFAULT:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+		break;
+	case SCSI_QDEPTH_QFULL:
+		scsi_track_queue_full(sdev, qdepth);
+		break;
+	default:
 		return -EOPNOTSUPP;
-	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+	}
 	return sdev->queue_depth;
 }
 EXPORT_SYMBOL(fc_change_queue_depth);
drivers/scsi/lpfc/lpfc_scsi.c +41 -34

105 lines not on this page · raw message

drivers/scsi/qla2xxx/qla_isr.c +0 -32
index 74fa6f9..66fda3a 100644
@@ -836,20 +836,6 @@ qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, void *data)
 	    sdev->queue_depth));
 }
 
-static void
-qla2x00_adjust_sdev_qdepth_down(struct scsi_device *sdev, void *data)
-{
-	fc_port_t *fcport = data;
-
-	if (!scsi_track_queue_full(sdev, sdev->queue_depth - 1))
-		return;
-
-	DEBUG2(qla_printk(KERN_INFO, fcport->vha->hw,
-	    "scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n",
-	    fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun,
-	    sdev->queue_depth));
-}
-
 static inline void
 qla2x00_ramp_up_queue_depth(scsi_qla_host_t *vha, struct req_que *req,
 								srb_t *sp)
@@ -1176,13 +1162,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
 			    "scsi(%ld): QUEUE FULL status detected "
 			    "0x%x-0x%x.\n", vha->host_no, comp_status,
 			    scsi_status));
-
-			/* Adjust queue depth for all luns on the port. */
-			if (!ql2xqfulltracking)
-				break;
-			fcport->last_queue_full = jiffies;
-			starget_for_each_device(cp->device->sdev_target,
-			    fcport, qla2x00_adjust_sdev_qdepth_down);
 			break;
 		}
 		if (lscsi_status != SS_CHECK_CONDITION)
@@ -1233,17 +1212,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
 				    "scsi(%ld): QUEUE FULL status detected "
 				    "0x%x-0x%x.\n", vha->host_no, comp_status,
 				    scsi_status));
-
-				/*
-				 * Adjust queue depth for all luns on the
-				 * port.
-				 */
-				if (!ql2xqfulltracking)
-					break;
-				fcport->last_queue_full = jiffies;
-				starget_for_each_device(
-				    cp->device->sdev_target, fcport,
-				    qla2x00_adjust_sdev_qdepth_down);
 				break;
 			}
 			if (lscsi_status != SS_CHECK_CONDITION)
drivers/scsi/qla2xxx/qla_os.c +27 -3
index c05c460..9652aac 100644
@@ -1222,12 +1222,36 @@ 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;
+
+	fcport->last_queue_full = jiffies;
+
+	if (!scsi_track_queue_full(sdev, qdepth))
+		return;
+
+	DEBUG2(qla_printk(KERN_INFO, fcport->vha->hw,
+		"scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n",
+		fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun,
+		sdev->queue_depth));
+}
+
 static int
 qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 {
-	if (reason != SCSI_QDEPTH_DEFAULT)
-		return -EOPNOTSUPP;
-	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+	switch (reason) {
+	case SCSI_QDEPTH_DEFAULT:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+		break;
+	case SCSI_QDEPTH_QFULL:
+		if (!ql2xqfulltracking)
+			qla2x00_handle_queue_full(sdev, qdepth);
+		break;
+	default:
+		return EOPNOTSUPP;
+	}
+
 	return sdev->queue_depth;
 }
 
#7 lore raw

RE: [PATCH 04/10] drivers: convert fc drivers calling scsi_track_queue_full

It looks like you moved the ramp up functionality into the scsi layer, but did not move the ramp up code from the lpfc driver in the lpfc_scsi_cmd_iocb_cmpl routine (just above the code that was removed for the ramp down in this patch) to the new lpfc_change_queue_depth routine. I think that this new routine should handle both ramp up and ramp down but you have it only handling the ramp down case.

-Alex

Quoted 94 lines

-----Original Message-----
From: [email protected] [mailto:linux-scsi- [email protected]] On Behalf Of Vasu Dev
Sent: Thursday, September 03, 2009 6:23 PM
To: James Bottomley; [email protected]
Cc: Andrew Vasquez; Smart, James; Mike Christie; Robert Love; Christof Schmitt
Subject: [PATCH 04/10] drivers: convert fc drivers calling scsi_track_queue_full

From: Mike Christie <[email protected]>

This converts the fc drivers that were using scsi_track_queue_full to track the queue full from the change_queue_depth callback.

I have not yet tested the qla2xxx or lpfc parts.

--
Adds check to ignore SCSI_QDEPTH_QFULL in case the ql2xqfulltracking is not set.

---

 drivers/scsi/libfc/fc_fcp.c    |   26 +++++---------
 drivers/scsi/lpfc/lpfc_scsi.c  |   75 ++++++++++++++++++++++----------
--------
 drivers/scsi/qla2xxx/qla_isr.c |   32 -----------------
 drivers/scsi/qla2xxx/qla_os.c  |   30 ++++++++++++++--
 4 files changed, 77 insertions(+), 86 deletions(-)
drivers/scsi/libfc/fc_fcp.c +9 -17
index 20b88cd..d919c2a 100644
@@ -1814,21 +1814,6 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
 			sc_cmd->result = DID_OK << 16;
 			if (fsp->scsi_resid)
 				CMD_RESID_LEN(sc_cmd) = fsp->scsi_resid;
-		} else if (fsp->cdb_status == QUEUE_FULL) {
-			struct scsi_device *tmp_sdev;
-			struct scsi_device *sdev = sc_cmd->device;
-
-			shost_for_each_device(tmp_sdev, sdev->host) {
-				if (tmp_sdev->id != sdev->id)
-					continue;
-
-				if (tmp_sdev->queue_depth > 1) {
-					scsi_track_queue_full(tmp_sdev,
-							      tmp_sdev->
-							      queue_depth - 1);
-				}
-			}
-			sc_cmd->result = (DID_OK << 16) | fsp->cdb_status;
 		} else {
 			/*
 			 * transport level I/O was ok but scsi
@@ -2064,9 +2049,16 @@ EXPORT_SYMBOL(fc_slave_alloc);
 
 int fc_change_queue_depth(struct scsi_device *sdev, int qdepth, int
 reason)
 {
-	if (reason != SCSI_QDEPTH_DEFAULT)
+	switch (reason) {
+	case SCSI_QDEPTH_DEFAULT:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev),
 qdepth);
+		break;
+	case SCSI_QDEPTH_QFULL:
+		scsi_track_queue_full(sdev, qdepth);
+		break;
+	default:
 		return -EOPNOTSUPP;
-	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+	}
 	return sdev->queue_depth;

}
EXPORT_SYMBOL(fc_change_queue_depth);

drivers/scsi/lpfc/lpfc_scsi.c +0 -1
index 61d0897..2d39d84 100644
@@ -2189,7 +2189,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba,
 struct lpfc_iocbq *pIocbIn,
 	struct scsi_cmnd *cmd = lpfc_cmd->pCmd;
 	int result;
 	struct scsi_device *tmp_sdev;
-	int depth = 0;
 	unsigned long flags;
 	struct lpfc_fast_path_event *fast_path_evt;
drivers/scsi/lpfc/lpfc_scsi.c +0 -0
 	struct Scsi_Host *shost = cmd->device->host;

drivers/scsi/lpfc/lpfc_scsi.c lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, · line 2389

Quoted 3 lines
drivers/scsi/lpfc/lpfc_scsi.c +0 -0
@@ -2388,39 +2387,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba,
 struct lpfc_iocbq *pIocbIn,
 	}
 

The code just above this area should be moved into the lpfc_change_queue_depth routine.

Quoted 45 lines
drivers/scsi/lpfc/lpfc_scsi.c +0 -1
 	/*
-	 * Check for queue full.  If the lun is reporting queue full,

then

drivers/scsi/lpfc/lpfc_scsi.c +2 -32
-	 * back off the lun queue depth to prevent target overloads.
-	 */
-	if (result == SAM_STAT_TASK_SET_FULL && pnode &&
-	    NLP_CHK_NODE_ACT(pnode)) {
-		pnode->last_q_full_time = jiffies;
-
-		shost_for_each_device(tmp_sdev, shost) {
-			if (tmp_sdev->id != scsi_id)
-				continue;
-			depth = scsi_track_queue_full(tmp_sdev,
-					tmp_sdev->queue_depth - 1);
-		}
-		/*
-		 * The queue depth cannot be lowered any more.
-		 * Modify the returned error code to store
-		 * the final depth value set by
-		 * scsi_track_queue_full.
-		 */
-		if (depth == -1)
-			depth = shost->cmd_per_lun;
-
-		if (depth) {
-			lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
-					 "0711 detected queue full - lun queue "
-					 "depth adjusted to %d.\n", depth);
-			lpfc_send_sdev_queuedepth_change_event(phba, vport,
-				pnode, 0xFFFFFFFF,
-				depth+1, depth);
-		}
-	}
-
-	/*
 	 * If there is a thread waiting for command completion
 	 * wake up the thread.
 	 */
@@ -3551,6 +3517,45 @@ lpfc_slave_configure(struct scsi_device *sdev)
 	return 0;
 }
 
+static int lpfc_change_queue_depth(struct scsi_device *sdev, int
 queue_depth,
+				   int reason)

drivers/scsi/lpfc/lpfc_scsi.c lpfc_slave_configure(struct scsi_device *sdev) · line 3532

Quoted 10 lines
drivers/scsi/lpfc/lpfc_scsi.c +10 -0
+{
+	struct Scsi_Host *shost = sdev->host;
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba *phba = vport->phba;
+	struct lpfc_rport_data *rdata = sdev->hostdata;
+	struct lpfc_nodelist *pnode = rdata->pnode;
+	int depth;
+
+	if (reason != SCSI_QDEPTH_QFULL)
+		return -EOPNOTSUPP;

This should handle qfull(ramp up) and ramp down.

Quoted 162 lines
drivers/scsi/lpfc/lpfc_scsi.c +27 -0
+
+	if (!pnode || !NLP_CHK_NODE_ACT(pnode))
+		return -EINVAL;
+
+	pnode->last_q_full_time = jiffies;
+
+	depth = scsi_track_queue_full(sdev, queue_depth);
+	/*
+	 * The queue depth cannot be lowered any more.
+	 * Modify the returned error code to store
+	 * the final depth value set by
+	 * scsi_track_queue_full.
+	 */
+	if (depth == -1)
+		depth = shost->cmd_per_lun;
+
+	if (depth) {
+		lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
+				 "0711 detected queue full - lun queue "
+				 "depth adjusted to %d.\n", depth);
+		lpfc_send_sdev_queuedepth_change_event(phba, vport,
+						       pnode, 0xFFFFFFFF,
+						       depth + 1, depth);
+	}
+	return sdev->queue_depth;
+}
+
 /**
  * lpfc_slave_destroy - slave_destroy entry point of SHT data

structure
* @sdev: Pointer to scsi_device.

drivers/scsi/lpfc/lpfc_scsi.c +2 -0
@@ -3574,6 +3579,7 @@ struct scsi_host_template lpfc_template = {
 	.eh_device_reset_handler = lpfc_device_reset_handler,
 	.eh_target_reset_handler = lpfc_target_reset_handler,
 	.eh_bus_reset_handler	= lpfc_bus_reset_handler,
+	.change_queue_depth	= lpfc_change_queue_depth,
 	.slave_alloc		= lpfc_slave_alloc,
 	.slave_configure	= lpfc_slave_configure,
 	.slave_destroy		= lpfc_slave_destroy,
@@ -3596,6 +3602,7 @@ struct scsi_host_template lpfc_vport_template = {
 	.eh_device_reset_handler = lpfc_device_reset_handler,
 	.eh_target_reset_handler = lpfc_target_reset_handler,
 	.eh_bus_reset_handler	= lpfc_bus_reset_handler,
+	.change_queue_depth	= lpfc_change_queue_depth,
 	.slave_alloc		= lpfc_slave_alloc,
 	.slave_configure	= lpfc_slave_configure,
 	.slave_destroy		= lpfc_slave_destroy,
drivers/scsi/qla2xxx/qla_isr.c +0 -14
index 74fa6f9..66fda3a 100644
@@ -836,20 +836,6 @@ qla2x00_adjust_sdev_qdepth_up(struct scsi_device
 *sdev, void *data)
 	    sdev->queue_depth));
 }
 
-static void
-qla2x00_adjust_sdev_qdepth_down(struct scsi_device *sdev, void *data)
-{
-	fc_port_t *fcport = data;
-
-	if (!scsi_track_queue_full(sdev, sdev->queue_depth - 1))
-		return;
-
-	DEBUG2(qla_printk(KERN_INFO, fcport->vha->hw,
-	    "scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n",
-	    fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun,
-	    sdev->queue_depth));
-}
-
 static inline void
 qla2x00_ramp_up_queue_depth(scsi_qla_host_t *vha, struct req_que *req,
drivers/scsi/qla2xxx/qla_isr.c +0 -7
 								srb_t *sp)
@@ -1176,13 +1162,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha,
 struct rsp_que *rsp, void *pkt)
 			    "scsi(%ld): QUEUE FULL status detected "
 			    "0x%x-0x%x.\n", vha->host_no, comp_status,
 			    scsi_status));
-
-			/* Adjust queue depth for all luns on the port. */
-			if (!ql2xqfulltracking)
-				break;
-			fcport->last_queue_full = jiffies;
-			starget_for_each_device(cp->device->sdev_target,
-			    fcport, qla2x00_adjust_sdev_qdepth_down);
 			break;
 		}
drivers/scsi/qla2xxx/qla_isr.c +0 -11
 		if (lscsi_status != SS_CHECK_CONDITION)
@@ -1233,17 +1212,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha,
 struct rsp_que *rsp, void *pkt)
 				    "scsi(%ld): QUEUE FULL status detected "
 				    "0x%x-0x%x.\n", vha->host_no, comp_status,
 				    scsi_status));
-
-				/*
-				 * Adjust queue depth for all luns on the
-				 * port.
-				 */
-				if (!ql2xqfulltracking)
-					break;
-				fcport->last_queue_full = jiffies;
-				starget_for_each_device(
-				    cp->device->sdev_target, fcport,
-				    qla2x00_adjust_sdev_qdepth_down);
 				break;
 			}
drivers/scsi/qla2xxx/qla_isr.c +0 -0
 			if (lscsi_status != SS_CHECK_CONDITION)
drivers/scsi/qla2xxx/qla_os.c +27 -3
index c05c460..9652aac 100644
@@ -1222,12 +1222,36 @@ 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;
+
+	fcport->last_queue_full = jiffies;
+
+	if (!scsi_track_queue_full(sdev, qdepth))
+		return;
+
+	DEBUG2(qla_printk(KERN_INFO, fcport->vha->hw,
+		"scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n",
+		fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun,
+		sdev->queue_depth));
+}
+
 static int
 qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth, int
 reason)
 {
-	if (reason != SCSI_QDEPTH_DEFAULT)
-		return -EOPNOTSUPP;
-	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+	switch (reason) {
+	case SCSI_QDEPTH_DEFAULT:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev),
 qdepth);
+		break;
+	case SCSI_QDEPTH_QFULL:
+		if (!ql2xqfulltracking)
+			qla2x00_handle_queue_full(sdev, qdepth);
+		break;
+	default:
+		return EOPNOTSUPP;
+	}
+

return sdev->queue_depth;
}

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#8 lore raw

RE: [PATCH 04/10] drivers: convert fc drivers calling scsi_track_queue_full

Quoted 2 lines · On Fri, 2009-09-04 at 06:47 -0700, [email protected] wrote:

It looks like you moved the ramp up functionality into the scsi layer, but did not move the ramp up code from the lpfc driver in the

Correct.

Quoted 5 lines

lpfc_scsi_cmd_iocb_cmpl routine (just above the code that was removed
for the ramp down in this patch) to the new lpfc_change_queue_depth routine. I think that this new routine should handle both ramp up and ramp down but you have it only handling the ramp down case.

I agree all FC HBA should handle both ramp down and up as per added new change_queue_depth interface by this series. I did this for libfc/fcoe and Chrirstof did this for zfcp driver but lpfc & qla2xxx got only ramp down changes from Mike, now that Mike is busy with other stuff I don't know how to complete them in this series since I don't understand lpfc and qla2xxx enough and neither I have way to test changes to these drivers.

So I'm going to update this series to have just libfc and zfcp driver changes for now and lpfc and qla2xxx can be updated later by someone familiar lpfc and qla2xxx, their ramp down changes can be collect from this series post.

Thanks
Vasu

Quoted 317 lines

-Alex

Quoted 94 lines

-----Original Message-----
From: [email protected] [mailto:linux-scsi- [email protected]] On Behalf Of Vasu Dev
Sent: Thursday, September 03, 2009 6:23 PM
To: James Bottomley; [email protected]
Cc: Andrew Vasquez; Smart, James; Mike Christie; Robert Love; Christof Schmitt
Subject: [PATCH 04/10] drivers: convert fc drivers calling scsi_track_queue_full

From: Mike Christie <[email protected]>

This converts the fc drivers that were using scsi_track_queue_full to track the queue full from the change_queue_depth callback.

I have not yet tested the qla2xxx or lpfc parts.

--
Adds check to ignore SCSI_QDEPTH_QFULL in case the ql2xqfulltracking is not set.

---

 drivers/scsi/libfc/fc_fcp.c    |   26 +++++---------
 drivers/scsi/lpfc/lpfc_scsi.c  |   75 ++++++++++++++++++++++----------
--------
 drivers/scsi/qla2xxx/qla_isr.c |   32 -----------------
 drivers/scsi/qla2xxx/qla_os.c  |   30 ++++++++++++++--
 4 files changed, 77 insertions(+), 86 deletions(-)
drivers/scsi/libfc/fc_fcp.c +9 -17
index 20b88cd..d919c2a 100644
@@ -1814,21 +1814,6 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
 			sc_cmd->result = DID_OK << 16;
 			if (fsp->scsi_resid)
 				CMD_RESID_LEN(sc_cmd) = fsp->scsi_resid;
-		} else if (fsp->cdb_status == QUEUE_FULL) {
-			struct scsi_device *tmp_sdev;
-			struct scsi_device *sdev = sc_cmd->device;
-
-			shost_for_each_device(tmp_sdev, sdev->host) {
-				if (tmp_sdev->id != sdev->id)
-					continue;
-
-				if (tmp_sdev->queue_depth > 1) {
-					scsi_track_queue_full(tmp_sdev,
-							      tmp_sdev->
-							      queue_depth - 1);
-				}
-			}
-			sc_cmd->result = (DID_OK << 16) | fsp->cdb_status;
 		} else {
 			/*
 			 * transport level I/O was ok but scsi
@@ -2064,9 +2049,16 @@ EXPORT_SYMBOL(fc_slave_alloc);
 
 int fc_change_queue_depth(struct scsi_device *sdev, int qdepth, int
 reason)
 {
-	if (reason != SCSI_QDEPTH_DEFAULT)
+	switch (reason) {
+	case SCSI_QDEPTH_DEFAULT:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev),
 qdepth);
+		break;
+	case SCSI_QDEPTH_QFULL:
+		scsi_track_queue_full(sdev, qdepth);
+		break;
+	default:
 		return -EOPNOTSUPP;
-	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+	}
 	return sdev->queue_depth;

}
EXPORT_SYMBOL(fc_change_queue_depth);

drivers/scsi/lpfc/lpfc_scsi.c +0 -1
index 61d0897..2d39d84 100644
@@ -2189,7 +2189,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba,
 struct lpfc_iocbq *pIocbIn,
 	struct scsi_cmnd *cmd = lpfc_cmd->pCmd;
 	int result;
 	struct scsi_device *tmp_sdev;
-	int depth = 0;
 	unsigned long flags;
 	struct lpfc_fast_path_event *fast_path_evt;
drivers/scsi/lpfc/lpfc_scsi.c +0 -0
 	struct Scsi_Host *shost = cmd->device->host;

drivers/scsi/lpfc/lpfc_scsi.c lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, · line 2389

Quoted 3 lines
drivers/scsi/lpfc/lpfc_scsi.c +0 -0
@@ -2388,39 +2387,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba,
 struct lpfc_iocbq *pIocbIn,
 	}
 

The code just above this area should be moved into the lpfc_change_queue_depth routine.

Quoted 45 lines
drivers/scsi/lpfc/lpfc_scsi.c +0 -1
 	/*
-	 * Check for queue full.  If the lun is reporting queue full,

then

drivers/scsi/lpfc/lpfc_scsi.c +2 -32
-	 * back off the lun queue depth to prevent target overloads.
-	 */
-	if (result == SAM_STAT_TASK_SET_FULL && pnode &&
-	    NLP_CHK_NODE_ACT(pnode)) {
-		pnode->last_q_full_time = jiffies;
-
-		shost_for_each_device(tmp_sdev, shost) {
-			if (tmp_sdev->id != scsi_id)
-				continue;
-			depth = scsi_track_queue_full(tmp_sdev,
-					tmp_sdev->queue_depth - 1);
-		}
-		/*
-		 * The queue depth cannot be lowered any more.
-		 * Modify the returned error code to store
-		 * the final depth value set by
-		 * scsi_track_queue_full.
-		 */
-		if (depth == -1)
-			depth = shost->cmd_per_lun;
-
-		if (depth) {
-			lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
-					 "0711 detected queue full - lun queue "
-					 "depth adjusted to %d.\n", depth);
-			lpfc_send_sdev_queuedepth_change_event(phba, vport,
-				pnode, 0xFFFFFFFF,
-				depth+1, depth);
-		}
-	}
-
-	/*
 	 * If there is a thread waiting for command completion
 	 * wake up the thread.
 	 */
@@ -3551,6 +3517,45 @@ lpfc_slave_configure(struct scsi_device *sdev)
 	return 0;
 }
 
+static int lpfc_change_queue_depth(struct scsi_device *sdev, int
 queue_depth,
+				   int reason)

drivers/scsi/lpfc/lpfc_scsi.c lpfc_slave_configure(struct scsi_device *sdev) · line 3532

Quoted 10 lines
drivers/scsi/lpfc/lpfc_scsi.c +10 -0
+{
+	struct Scsi_Host *shost = sdev->host;
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba *phba = vport->phba;
+	struct lpfc_rport_data *rdata = sdev->hostdata;
+	struct lpfc_nodelist *pnode = rdata->pnode;
+	int depth;
+
+	if (reason != SCSI_QDEPTH_QFULL)
+		return -EOPNOTSUPP;

This should handle qfull(ramp up) and ramp down.

Quoted 157 lines
drivers/scsi/lpfc/lpfc_scsi.c +27 -0
+
+	if (!pnode || !NLP_CHK_NODE_ACT(pnode))
+		return -EINVAL;
+
+	pnode->last_q_full_time = jiffies;
+
+	depth = scsi_track_queue_full(sdev, queue_depth);
+	/*
+	 * The queue depth cannot be lowered any more.
+	 * Modify the returned error code to store
+	 * the final depth value set by
+	 * scsi_track_queue_full.
+	 */
+	if (depth == -1)
+		depth = shost->cmd_per_lun;
+
+	if (depth) {
+		lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
+				 "0711 detected queue full - lun queue "
+				 "depth adjusted to %d.\n", depth);
+		lpfc_send_sdev_queuedepth_change_event(phba, vport,
+						       pnode, 0xFFFFFFFF,
+						       depth + 1, depth);
+	}
+	return sdev->queue_depth;
+}
+
 /**
  * lpfc_slave_destroy - slave_destroy entry point of SHT data

structure
* @sdev: Pointer to scsi_device.

drivers/scsi/lpfc/lpfc_scsi.c +2 -0
@@ -3574,6 +3579,7 @@ struct scsi_host_template lpfc_template = {
 	.eh_device_reset_handler = lpfc_device_reset_handler,
 	.eh_target_reset_handler = lpfc_target_reset_handler,
 	.eh_bus_reset_handler	= lpfc_bus_reset_handler,
+	.change_queue_depth	= lpfc_change_queue_depth,
 	.slave_alloc		= lpfc_slave_alloc,
 	.slave_configure	= lpfc_slave_configure,
 	.slave_destroy		= lpfc_slave_destroy,
@@ -3596,6 +3602,7 @@ struct scsi_host_template lpfc_vport_template = {
 	.eh_device_reset_handler = lpfc_device_reset_handler,
 	.eh_target_reset_handler = lpfc_target_reset_handler,
 	.eh_bus_reset_handler	= lpfc_bus_reset_handler,
+	.change_queue_depth	= lpfc_change_queue_depth,
 	.slave_alloc		= lpfc_slave_alloc,
 	.slave_configure	= lpfc_slave_configure,
 	.slave_destroy		= lpfc_slave_destroy,
drivers/scsi/qla2xxx/qla_isr.c +0 -14
index 74fa6f9..66fda3a 100644
@@ -836,20 +836,6 @@ qla2x00_adjust_sdev_qdepth_up(struct scsi_device
 *sdev, void *data)
 	    sdev->queue_depth));
 }
 
-static void
-qla2x00_adjust_sdev_qdepth_down(struct scsi_device *sdev, void *data)
-{
-	fc_port_t *fcport = data;
-
-	if (!scsi_track_queue_full(sdev, sdev->queue_depth - 1))
-		return;
-
-	DEBUG2(qla_printk(KERN_INFO, fcport->vha->hw,
-	    "scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n",
-	    fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun,
-	    sdev->queue_depth));
-}
-
 static inline void
 qla2x00_ramp_up_queue_depth(scsi_qla_host_t *vha, struct req_que *req,
drivers/scsi/qla2xxx/qla_isr.c +0 -7
 								srb_t *sp)
@@ -1176,13 +1162,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha,
 struct rsp_que *rsp, void *pkt)
 			    "scsi(%ld): QUEUE FULL status detected "
 			    "0x%x-0x%x.\n", vha->host_no, comp_status,
 			    scsi_status));
-
-			/* Adjust queue depth for all luns on the port. */
-			if (!ql2xqfulltracking)
-				break;
-			fcport->last_queue_full = jiffies;
-			starget_for_each_device(cp->device->sdev_target,
-			    fcport, qla2x00_adjust_sdev_qdepth_down);
 			break;
 		}
drivers/scsi/qla2xxx/qla_isr.c +0 -11
 		if (lscsi_status != SS_CHECK_CONDITION)
@@ -1233,17 +1212,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha,
 struct rsp_que *rsp, void *pkt)
 				    "scsi(%ld): QUEUE FULL status detected "
 				    "0x%x-0x%x.\n", vha->host_no, comp_status,
 				    scsi_status));
-
-				/*
-				 * Adjust queue depth for all luns on the
-				 * port.
-				 */
-				if (!ql2xqfulltracking)
-					break;
-				fcport->last_queue_full = jiffies;
-				starget_for_each_device(
-				    cp->device->sdev_target, fcport,
-				    qla2x00_adjust_sdev_qdepth_down);
 				break;
 			}
drivers/scsi/qla2xxx/qla_isr.c +0 -0
 			if (lscsi_status != SS_CHECK_CONDITION)
drivers/scsi/qla2xxx/qla_os.c +27 -3
index c05c460..9652aac 100644
@@ -1222,12 +1222,36 @@ 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;
+
+	fcport->last_queue_full = jiffies;
+
+	if (!scsi_track_queue_full(sdev, qdepth))
+		return;
+
+	DEBUG2(qla_printk(KERN_INFO, fcport->vha->hw,
+		"scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n",
+		fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun,
+		sdev->queue_depth));
+}
+
 static int
 qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth, int
 reason)
 {
-	if (reason != SCSI_QDEPTH_DEFAULT)
-		return -EOPNOTSUPP;
-	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+	switch (reason) {
+	case SCSI_QDEPTH_DEFAULT:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev),
 qdepth);
+		break;
+	case SCSI_QDEPTH_QFULL:
+		if (!ql2xqfulltracking)
+			qla2x00_handle_queue_full(sdev, qdepth);
+		break;
+	default:
+		return EOPNOTSUPP;
+	}
+

return sdev->queue_depth;
}

Quoted 6 lines
Quoted 5 lines

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

NrybXǧv^)޺{.n+{"{ayʇڙ,jfhzw j:+vwjmzZ+ݢj"!

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#9 lore raw

Re: [PATCH 04/10] drivers: convert fc drivers calling scsi_track_queue_full

Quoted 20 lines · Vasu Dev
Quoted 2 lines · On Fri, 2009-09-04 at 06:47 -0700, [email protected] wrote:

It looks like you moved the ramp up functionality into the scsi layer, but did not move the ramp up code from the lpfc driver in the

Correct.

Quoted 5 lines

lpfc_scsi_cmd_iocb_cmpl routine (just above the code that was removed
for the ramp down in this patch) to the new lpfc_change_queue_depth routine. I think that this new routine should handle both ramp up and ramp down but you have it only handling the ramp down case.

I agree all FC HBA should handle both ramp down and up as per added new change_queue_depth interface by this series. I did this for libfc/fcoe and Chrirstof did this for zfcp driver but lpfc& qla2xxx got only ramp down changes from Mike, now that Mike is busy with other stuff I don't know how to complete them in this series since I don't understand lpfc and qla2xxx enough and neither I have way to test changes to these drivers.

Quoted 5 lines

So I'm going to update this series to have just libfc and zfcp driver changes for now and lpfc and qla2xxx can be updated later by someone familiar lpfc and qla2xxx, their ramp down changes can be collect from this series post.

I think it is fine not to convert a driver immediately and let the driver maintainer handle it. I normally like to take a stab at it to try and give the driver maintainer some more info on the how I think it should work.

I think at the very least you want to make sure your code will work for other drivers, so sometimes doing a pseudo patch is useful for another reason.

For the case of lpfc and rampup I think we need a little more code. It looks like lpfc will ramp down queues if it gets a reject on its port (when we get a IOSTAT_LOCAL_REJECT we call lpfc_rampdown_queue_depth). When it then tries to ramp up, it also takes that rampdown event into account. The common code being added by Vasu, only tracks rampdown events from QUEUE_FULLs.

You probably want to make a common fc class function which loops over vports and will ramp down queues. The fc LLD can then call this and that common fc function can make sure the common rampdown tracking is done so later on the ramp up code can take that into account.

Reviewing lpfc also brings up the question of why it was not doing the ramp up in the main IO path. It looks like it is done in a worker thread. The ramp down for a QUEUE_FULL is probably done in the main IO path because we are already getting errors and we want to prevent new ones. But for the ramp up, did Emulex experience performance hits when ramping up in the main IO path?

#10 lore raw

Re: [PATCH 04/10] drivers: convert fc drivers calling scsi_track_queue_full

Quoted 27 lines · Mike Christie
Quoted 20 lines · Vasu Dev
Quoted 2 lines · On Fri, 2009-09-04 at 06:47 -0700, [email protected] wrote:

It looks like you moved the ramp up functionality into the scsi layer, but did not move the ramp up code from the lpfc driver in the

Correct.

Quoted 5 lines

lpfc_scsi_cmd_iocb_cmpl routine (just above the code that was removed
for the ramp down in this patch) to the new lpfc_change_queue_depth routine. I think that this new routine should handle both ramp up and ramp down but you have it only handling the ramp down case.

I agree all FC HBA should handle both ramp down and up as per added new change_queue_depth interface by this series. I did this for libfc/fcoe and Chrirstof did this for zfcp driver but lpfc& qla2xxx got only ramp down changes from Mike, now that Mike is busy with other stuff I don't know how to complete them in this series since I don't understand lpfc and qla2xxx enough and neither I have way to test changes to these drivers.

Quoted 5 lines

So I'm going to update this series to have just libfc and zfcp driver changes for now and lpfc and qla2xxx can be updated later by someone familiar lpfc and qla2xxx, their ramp down changes can be collect from this series post.

Quoted 9 lines

I think it is fine not to convert a driver immediately and let the driver maintainer handle it. I normally like to take a stab at it to try and give the driver maintainer some more info on the how I think it should work.

I think at the very least you want to make sure your code will work for other drivers, so sometimes doing a pseudo patch is useful for another reason.

I'll try to come up with a compile tested code for lpfc and you already did that for qla2xx ramp up today. As you said "it is fine not to convert a driver immediately", so I'll provide this separately and will try to do it earliest possible.

Modified change_queue_depth interface changes by this series should be sufficient to later do lpfc and qla2xx changes.

Quoted 7 lines

For the case of lpfc and rampup I think we need a little more code. It looks like lpfc will ramp down queues if it gets a reject on its port (when we get a IOSTAT_LOCAL_REJECT we call lpfc_rampdown_queue_depth). When it then tries to ramp up, it also takes that rampdown event into account. The common code being added by Vasu, only tracks rampdown events from QUEUE_FULLs.

The qla2xx ramps down only on QUEUE_FULL beside added zfcp and lpfc doing same only on QUEUE_FULL condition, but still a HBAs could call their own change_queue_depth function for other conditions to ramp down e.g. lpfc for IOSTAT_LOCAL_REJECT.

The lpfc and qla2xxx both are calling ramp up code only after specified time interval since last ramp down/up on a successful IO completion, so does the added code does the same with tunable time interval. I chose least 120HZ from qla2xxx as default.

So added common code for ramp down/up is sufficient for majority of FC HBAs and lpfc specific additional criteria should be limited to only lpfc HBA code.

Quoted 5 lines

You probably want to make a common fc class function which loops over vports and will ramp down queues. The fc LLD can then call this and that common fc function can make sure the common rampdown tracking is done so later on the ramp up code can take that into account.

The qdepth should be adjusted for all luns of a target and doing so via scsi-ml struct is more common to all scsi transport classes. I think we need to limit qdepth adjustment to only all luns of a target/vport at a time as currently qla2xxx does and same is done by added common ramp up code.

Quoted 6 lines

Reviewing lpfc also brings up the question of why it was not doing the ramp up in the main IO path. It looks like it is done in a worker thread. The ramp down for a QUEUE_FULL is probably done in the main IO path because we are already getting errors and we want to prevent new ones. But for the ramp up, did Emulex experience performance hits when ramping up in the main IO path?

#11 lore raw

Re: [PATCH 04/10] drivers: convert fc drivers calling scsi_track_queue_full

Quoted 38 lines · Vasu Dev
Quoted 19 lines · Mike Christie
Quoted 18 lines · Vasu Dev
Quoted 2 lines · On Fri, 2009-09-04 at 06:47 -0700, [email protected] wrote:

It looks like you moved the ramp up functionality into the scsi layer, but did not move the ramp up code from the lpfc driver in the

Correct.

Quoted 5 lines

lpfc_scsi_cmd_iocb_cmpl routine (just above the code that was removed
for the ramp down in this patch) to the new lpfc_change_queue_depth routine. I think that this new routine should handle both ramp up and ramp down but you have it only handling the ramp down case.

I agree all FC HBA should handle both ramp down and up as per added new change_queue_depth interface by this series. I did this for libfc/fcoe and Chrirstof did this for zfcp driver but lpfc& qla2xxx got only ramp down changes from Mike, now that Mike is busy with other stuff I don't know how to complete them in this series since I don't understand lpfc and qla2xxx enough and neither I have way to test changes to these drivers.

Quoted 9 lines
Quoted 5 lines

So I'm going to update this series to have just libfc and zfcp driver changes for now and lpfc and qla2xxx can be updated later by someone familiar lpfc and qla2xxx, their ramp down changes can be collect from this series post.

I think it is fine not to convert a driver immediately and let the driver maintainer handle it. I normally like to take a stab at it to try and give the driver maintainer some more info on the how I think it should work.

I think at the very least you want to make sure your code will work for other drivers, so sometimes doing a pseudo patch is useful for another reason.

I'll try to come up with a compile tested code for lpfc and you already did that for qla2xx ramp up today. As you said "it is fine not to convert a driver immediately", so I'll provide this separately and will try to do it earliest possible.

Modified change_queue_depth interface changes by this series should be sufficient to later do lpfc and qla2xx changes.

Quoted 7 lines
Quoted 2 lines

For the case of lpfc and rampup I think we need a little more code. It looks like lpfc will ramp down queues if it gets a reject on its port (when we get a IOSTAT_LOCAL_REJECT we call lpfc_rampdown_queue_depth). When it then tries to ramp up, it also takes that rampdown event into account. The common code being added by Vasu, only tracks rampdown events from QUEUE_FULLs.

The qla2xx ramps down only on QUEUE_FULL beside added zfcp and lpfc doing same only on QUEUE_FULL condition, but still a HBAs could call their own change_queue_depth function for other conditions to ramp down e.g. lpfc for IOSTAT_LOCAL_REJECT.

If they do this will they have to duplicate the rampdown/up time tracking done by the common scsi_error code?

Quoted 9 lines

The lpfc and qla2xxx both are calling ramp up code only after specified time interval since last ramp down/up on a successful IO completion, so does the added code does the same with tunable time interval. I chose least 120HZ from qla2xxx as default.

So added common code for ramp down/up is sufficient for majority of FC HBAs and lpfc specific additional criteria should be limited to only lpfc HBA code.

Why should it only be limited to lpfc? Are you saying other drivers or hw do not have something like a local reject or out of hba port resources? Do you know this by just looking at the driver? A lot of times lpfc will add something then other drivers (myself included) will add it later when they have seen lpfc do it. Or are you saying you think other drivers are going to want to handle the problem in a different way?

A message that is not in the archive (sent off-list or not yet received): [email protected]

#13 lore raw

Re: [PATCH 04/10] drivers: convert fc drivers calling scsi_track_queue_full

Quoted 52 lines · Mike Christie
Quoted 51 lines · Vasu Dev
Quoted 24 lines · Mike Christie
Quoted 18 lines · Vasu Dev
Quoted 2 lines · On Fri, 2009-09-04 at 06:47 -0700, Alex.Iannicelli-iH1Dq9VlAzfQT0dZR+AlfA@publi…

It looks like you moved the ramp up functionality into the scsi layer, but did not move the ramp up code from the lpfc driver in the

Correct.

Quoted 5 lines

lpfc_scsi_cmd_iocb_cmpl routine (just above the code that was removed
for the ramp down in this patch) to the new lpfc_change_queue_depth routine. I think that this new routine should handle both ramp up and ramp down but you have it only handling the ramp down case.

I agree all FC HBA should handle both ramp down and up as per added new change_queue_depth interface by this series. I did this for libfc/fcoe and Chrirstof did this for zfcp driver but lpfc& qla2xxx got only ramp down changes from Mike, now that Mike is busy with other stuff I don't know how to complete them in this series since I don't understand lpfc and qla2xxx enough and neither I have way to test changes to these drivers.

Quoted 5 lines

So I'm going to update this series to have just libfc and zfcp driver changes for now and lpfc and qla2xxx can be updated later by someone familiar lpfc and qla2xxx, their ramp down changes can be collect from this series post.

Quoted 9 lines

I think it is fine not to convert a driver immediately and let the driver maintainer handle it. I normally like to take a stab at it to try and give the driver maintainer some more info on the how I think it should work.

I think at the very least you want to make sure your code will work for other drivers, so sometimes doing a pseudo patch is useful for another reason.

I'll try to come up with a compile tested code for lpfc and you already did that for qla2xx ramp up today. As you said "it is fine not to convert a driver immediately", so I'll provide this separately and will try to do it earliest possible.

Modified change_queue_depth interface changes by this series should be sufficient to later do lpfc and qla2xx changes.

Quoted 7 lines

For the case of lpfc and rampup I think we need a little more code. It looks like lpfc will ramp down queues if it gets a reject on its port (when we get a IOSTAT_LOCAL_REJECT we call lpfc_rampdown_queue_depth). When it then tries to ramp up, it also takes that rampdown event into account. The common code being added by Vasu, only tracks rampdown events from QUEUE_FULLs.

Quoted 8 lines
Quoted 4 lines

The qla2xx ramps down only on QUEUE_FULL beside added zfcp and lpfc doing same only on QUEUE_FULL condition, but still a HBAs could call their own change_queue_depth function for other conditions to ramp down e.g. lpfc for IOSTAT_LOCAL_REJECT.

If they do this will they have to duplicate the rampdown/up time tracking done by the common scsi_error code?

lpfc could still use same added common ramp up and ramp down code for lpfc specific IOSTAT_LOCAL_REJECT condition. This would just require exporting added scsi_handle_queue_full() and then have lpc call this for IOSTAT_LOCAL_REJECT condition. The lpfc change_queue_depth handler could make additional checks for IOSTAT_LOCAL_REJECT condition before final qdepth adjustment which would get called by added common code. So I don't see any duplicate code in that case while also limiting IOSTAT_LOCAL_REJECT code to only lpfc.

Quoted 10 lines
Quoted 9 lines

The lpfc and qla2xxx both are calling ramp up code only after specified time interval since last ramp down/up on a successful IO completion, so does the added code does the same with tunable time interval. I chose least 120HZ from qla2xxx as default.

So added common code for ramp down/up is sufficient for majority of FC HBAs and lpfc specific additional criteria should be limited to only lpfc HBA code.

Quoted 6 lines

Why should it only be limited to lpfc? Are you saying other drivers or hw do not have something like a local reject or out of hba port resources? Do you know this by just looking at the driver? A lot of times lpfc will add something then other drivers (myself included) will add it later when they have seen lpfc do it. Or are you saying you think other drivers are going to want to handle the problem in a different way?

Yes, I think adjusting can_queue will be more helpful in case of resource allocation failures instead queue_depth adjustment on all luns. In case of rport is gone, no use of queue_depth ramp down on luns of rport.

Regards
Vasu

Quoted 4 lines

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 1252968994.2231.16.camel-B2RhF0yJhE275v1z/[email protected]

#15 lore raw

Re: [PATCH 04/10] drivers: convert fc drivers calling scsi_track_queue_full

Quoted 59 lines · Vasu Dev
Quoted 50 lines · Mike Christie
Quoted 49 lines · Vasu Dev
Quoted 24 lines · Mike Christie
Quoted 18 lines · Vasu Dev
Quoted 2 lines · On Fri, 2009-09-04 at 06:47 -0700, Alex.Iannicelli-iH1Dq9VlAzfQT0dZR+AlfA@publi…

It looks like you moved the ramp up functionality into the scsi layer, but did not move the ramp up code from the lpfc driver in the

Correct.

Quoted 5 lines

lpfc_scsi_cmd_iocb_cmpl routine (just above the code that was removed
for the ramp down in this patch) to the new lpfc_change_queue_depth routine. I think that this new routine should handle both ramp up and ramp down but you have it only handling the ramp down case.

I agree all FC HBA should handle both ramp down and up as per added new change_queue_depth interface by this series. I did this for libfc/fcoe and Chrirstof did this for zfcp driver but lpfc& qla2xxx got only ramp down changes from Mike, now that Mike is busy with other stuff I don't know how to complete them in this series since I don't understand lpfc and qla2xxx enough and neither I have way to test changes to these drivers.

Quoted 5 lines

So I'm going to update this series to have just libfc and zfcp driver changes for now and lpfc and qla2xxx can be updated later by someone familiar lpfc and qla2xxx, their ramp down changes can be collect from this series post.

Quoted 9 lines

I think it is fine not to convert a driver immediately and let the driver maintainer handle it. I normally like to take a stab at it to try and give the driver maintainer some more info on the how I think it should work.

I think at the very least you want to make sure your code will work for other drivers, so sometimes doing a pseudo patch is useful for another reason.

I'll try to come up with a compile tested code for lpfc and you already did that for qla2xx ramp up today. As you said "it is fine not to convert a driver immediately", so I'll provide this separately and will try to do it earliest possible.

Modified change_queue_depth interface changes by this series should be sufficient to later do lpfc and qla2xx changes.

Quoted 7 lines

For the case of lpfc and rampup I think we need a little more code. It looks like lpfc will ramp down queues if it gets a reject on its port (when we get a IOSTAT_LOCAL_REJECT we call lpfc_rampdown_queue_depth). When it then tries to ramp up, it also takes that rampdown event into account. The common code being added by Vasu, only tracks rampdown events from QUEUE_FULLs.

Quoted 7 lines
Quoted 4 lines

The qla2xx ramps down only on QUEUE_FULL beside added zfcp and lpfc doing same only on QUEUE_FULL condition, but still a HBAs could call their own change_queue_depth function for other conditions to ramp down e.g. lpfc for IOSTAT_LOCAL_REJECT.

If they do this will they have to duplicate the rampdown/up time tracking done by the common scsi_error code?

Quoted 8 lines

lpfc could still use same added common ramp up and ramp down code for lpfc specific IOSTAT_LOCAL_REJECT condition. This would just require exporting added scsi_handle_queue_full() and then have lpc call this for IOSTAT_LOCAL_REJECT condition. The lpfc change_queue_depth handler could make additional checks for IOSTAT_LOCAL_REJECT condition before final qdepth adjustment which would get called by added common code. So I don't see any duplicate code in that case while also limiting IOSTAT_LOCAL_REJECT code to only lpfc.

Works for me.

Quoted 16 lines
Quoted 9 lines
Quoted 9 lines

The lpfc and qla2xxx both are calling ramp up code only after specified time interval since last ramp down/up on a successful IO completion, so does the added code does the same with tunable time interval. I chose least 120HZ from qla2xxx as default.

So added common code for ramp down/up is sufficient for majority of FC HBAs and lpfc specific additional criteria should be limited to only lpfc HBA code.

Quoted 6 lines

Why should it only be limited to lpfc? Are you saying other drivers or hw do not have something like a local reject or out of hba port resources? Do you know this by just looking at the driver? A lot of times lpfc will add something then other drivers (myself included) will add it later when they have seen lpfc do it. Or are you saying you think other drivers are going to want to handle the problem in a different way?

Quoted 4 lines

Yes, I think adjusting can_queue will be more helpful in case of resource allocation failures instead queue_depth adjustment on all luns. In case of rport is gone, no use of queue_depth ramp down on luns of rport.

Works for me.

#16 lore raw

Re: [PATCH 04/10] drivers: convert fc drivers calling scsi_track_queue_full

In reply to Vasu Dev
Quoted 7 lines · Vasu Dev

I agree all FC HBA should handle both ramp down and up as per added new change_queue_depth interface by this series. I did this for libfc/fcoe and Chrirstof did this for zfcp driver but lpfc& qla2xxx got only ramp down changes from Mike, now that Mike is busy with other stuff I don't know how to complete them in this series since I don't understand lpfc and qla2xxx enough and neither I have way to test changes to these drivers.

The qla2xxxx conversion seems a lot easier than lpfc (at least a lot closer to what is being done in the common code Vasu added). I am attaching a patch made over this patchset that converts it to use the common ramp up code. I have only compile tested it.

Andrew, could you have your guys give it a spin? Did you guys test out the rampdown/qfull handling?

From d8a94c82ce28837ce8a05349fc073b895813601d Mon Sep 17 00:00:00 2001
From: Mike Christie <[email protected]>
Date: Fri, 11 Sep 2009 11:43:40 -0500
Subject: [PATCH 1/1] qla2xxx: hook qla2xxx into common ramp up code

This hooks qla2xxx into the common ramp up code.

This q depth behavior should be the same as before. The only change should be that you use the common scsi device sysfs interface to set the ramp up period instead of using the qla2xxx mod param.

This patch was made over the rampdown/qfull handling patch. It is only compile tested.

---
 drivers/scsi/qla2xxx/qla_def.h |    3 --
 drivers/scsi/qla2xxx/qla_gbl.h |    2 -
 drivers/scsi/qla2xxx/qla_isr.c |   59 ----------------------------------------
 drivers/scsi/qla2xxx/qla_os.c  |   39 +++++++++++++++++++-------
 4 files changed, 29 insertions(+), 74 deletions(-)
drivers/scsi/qla2xxx/qla_def.h +0 -3
index d8ce310..8ead66e 100644
@@ -1570,9 +1570,6 @@ typedef struct fc_port {
 	struct fc_rport *rport, *drport;
 	u32 supported_classes;
 
-	unsigned long last_queue_full;
-	unsigned long last_ramp_up;
-
 	uint16_t vp_idx;
 } fc_port_t;
 
drivers/scsi/qla2xxx/qla_gbl.h +0 -2
index 14e0562..0ca5c54 100644
@@ -72,8 +72,6 @@ extern int ql2xloginretrycount;
 extern int ql2xfdmienable;
 extern int ql2xallocfwdump;
 extern int ql2xextended_error_logging;
-extern int ql2xqfullrampup;
-extern int ql2xqfulltracking;
 extern int ql2xiidmaenable;
 extern int ql2xmaxqueues;
 extern int ql2xmultique_tag;
drivers/scsi/qla2xxx/qla_isr.c +0 -59

71 lines not on this page · raw message

drivers/scsi/qla2xxx/qla_os.c +29 -10
index b24c7cc..72c2821 100644
@@ -78,7 +78,7 @@ module_param(ql2xmaxqdepth, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(ql2xmaxqdepth,
 		"Maximum queue depth to report for target devices.");
 
-int ql2xqfulltracking = 1;
+static int ql2xqfulltracking = 1;
 module_param(ql2xqfulltracking, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(ql2xqfulltracking,
 		"Controls whether the driver tracks queue full status "
@@ -86,13 +86,6 @@ MODULE_PARM_DESC(ql2xqfulltracking,
 		"depth.  Default is 1, perform tracking.  Set to 0 to "
 		"disable dynamic tracking and adjustment of queue depth.");
 
-int ql2xqfullrampup = 120;
-module_param(ql2xqfullrampup, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(ql2xqfullrampup,
-		"Number of seconds to wait to begin to ramp-up the queue "
-		"depth for a device after a queue-full condition has been "
-		"detected.  Default is 120 seconds.");
-
 int ql2xiidmaenable=1;
 module_param(ql2xiidmaenable, int, S_IRUGO|S_IRUSR);
 MODULE_PARM_DESC(ql2xiidmaenable,
@@ -1238,8 +1231,6 @@ static void qla2x00_handle_queue_full(struct scsi_device *sdev, int qdepth)
 {
 	fc_port_t *fcport = (struct fc_port *) sdev->hostdata;
 
-	fcport->last_queue_full = jiffies;
-
 	if (!scsi_track_queue_full(sdev, qdepth))
 		return;
 
@@ -1249,6 +1240,30 @@ static void qla2x00_handle_queue_full(struct scsi_device *sdev, int qdepth)
 		sdev->queue_depth));
 }
 
+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 qla_hw_data *ha = vha->hw;
+	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;
+
+	if (sdev->ordered_tags)
+		scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, qdepth);
+	else
+		scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, qdepth);
+
+	DEBUG2(qla_printk(KERN_INFO, ha,
+	       "scsi(%ld:%d:%d:%d): Queue depth adjusted-up to %d.\n",
+	       fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun,
+	       sdev->queue_depth));
+}
+
 static int
 qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 {
@@ -1260,6 +1275,10 @@ qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 		if (!ql2xqfulltracking)
 			qla2x00_handle_queue_full(sdev, qdepth);
 		break;
+	case SCSI_QDEPTH_RAMP_UP:
+		if (!ql2xqfulltracking)
+			qla2x00_adjust_sdev_qdepth_up(sdev, qdepth);
+		break;
 	default:
 		return EOPNOTSUPP;
 	}
Signature · 1 line
1.6.2.2
#17 lore raw

Re: [PATCH 04/10] drivers: convert fc drivers calling scsi_track_queue_full

Mike,

I am looking at the changes. Will get back to you.

-- Giridhar.M.B

Quoted 17 lines · Mike Christie
Quoted 7 lines · Vasu Dev

I agree all FC HBA should handle both ramp down and up as per added new change_queue_depth interface by this series. I did this for libfc/fcoe and Chrirstof did this for zfcp driver but lpfc& qla2xxx got only ramp down changes from Mike, now that Mike is busy with other stuff I don't know how to complete them in this series since I don't understand lpfc and qla2xxx enough and neither I have way to test changes to these drivers.

The qla2xxxx conversion seems a lot easier than lpfc (at least a lot closer to what is being done in the common code Vasu added). I am attaching a patch made over this patchset that converts it to use the common ramp up code. I have only compile tested it.

Andrew, could you have your guys give it a spin? Did you guys test out the rampdown/qfull handling? <0001-qla2xxx-hook-qla2xxx-into-common-ramp-up-code.patch>

author
#18 lore raw

PATCH v2 1/1 drivers: convert libfc calling scsi_track_queue_full

In reply to Vasu Dev

From: Mike Christie <[email protected]>

This converts the libfc using scsi_track_queue_full to track the queue full from the change_queue_depth callback.

---

 drivers/scsi/libfc/fc_fcp.c |   26 +++++++++-----------------
 1 files changed, 9 insertions(+), 17 deletions(-)
drivers/scsi/libfc/fc_fcp.c +9 -17
index d748e03..6c189be 100644
@@ -1814,21 +1814,6 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
 			sc_cmd->result = DID_OK << 16;
 			if (fsp->scsi_resid)
 				CMD_RESID_LEN(sc_cmd) = fsp->scsi_resid;
-		} else if (fsp->cdb_status == QUEUE_FULL) {
-			struct scsi_device *tmp_sdev;
-			struct scsi_device *sdev = sc_cmd->device;
-
-			shost_for_each_device(tmp_sdev, sdev->host) {
-				if (tmp_sdev->id != sdev->id)
-					continue;
-
-				if (tmp_sdev->queue_depth > 1) {
-					scsi_track_queue_full(tmp_sdev,
-							      tmp_sdev->
-							      queue_depth - 1);
-				}
-			}
-			sc_cmd->result = (DID_OK << 16) | fsp->cdb_status;
 		} else {
 			/*
 			 * transport level I/O was ok but scsi
@@ -2064,9 +2049,16 @@ EXPORT_SYMBOL(fc_slave_alloc);
 
 int fc_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 {
-	if (reason != SCSI_QDEPTH_DEFAULT)
+	switch (reason) {
+	case SCSI_QDEPTH_DEFAULT:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+		break;
+	case SCSI_QDEPTH_QFULL:
+		scsi_track_queue_full(sdev, qdepth);
+		break;
+	default:
 		return -EOPNOTSUPP;
-	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+	}
 	return sdev->queue_depth;
 }
 EXPORT_SYMBOL(fc_change_queue_depth);
author
#19 lore raw

PATCH 5/10 scsi: updates sdev to add queue_depth ramp up code

In reply to Vasu Dev

Current FC HBA queue_depth ramp up code depends on :-

1. last queue full time.
2. last queue ramp up time.
3. ramp up period (time interval)

The sdev already has last_queue_full_time field to track last queue full time but stored value is truncated by last four bits.

So this patch updates last_queue_full_time without truncating last 4 bits to store complete value and then updates its only current usages in scsi_track_queue_full to ignore last four bits to keep current usages same. This will allow same last_queue_full_time used by scsi_track_queue_full and queue_depth ramp up code.

Adds additional new sdev fields for above 2 and 3 items.

---

 drivers/scsi/scsi.c        |   10 ++++++++--
 include/scsi/scsi_device.h |    6 +++---
 2 files changed, 11 insertions(+), 5 deletions(-)
drivers/scsi/scsi.c +8 -2
index b6e0307..bffaa9c 100644
@@ -937,10 +937,16 @@ EXPORT_SYMBOL(scsi_adjust_queue_depth);
  */
 int scsi_track_queue_full(struct scsi_device *sdev, int depth)
 {
-	if ((jiffies >> 4) == sdev->last_queue_full_time)
+
+	/*
+	 * Don't let QUEUE_FULLs on the same
+	 * jiffies count, they could all be from
+	 * same event.
+	 */
+	if ((jiffies >> 4) == (sdev->last_queue_full_time >> 4))
 		return 0;
 
-	sdev->last_queue_full_time = (jiffies >> 4);
+	sdev->last_queue_full_time = jiffies;
 	if (sdev->last_queue_full_depth != depth) {
 		sdev->last_queue_full_count = 1;
 		sdev->last_queue_full_depth = depth;
include/scsi/scsi_device.h +3 -3
index 9af48cb..041d4f9 100644
@@ -83,9 +83,9 @@ struct scsi_device {
 	unsigned short queue_depth;	/* How deep of a queue we want */
 	unsigned short last_queue_full_depth; /* These two are used by */
 	unsigned short last_queue_full_count; /* scsi_track_queue_full() */
-	unsigned long last_queue_full_time;/* don't let QUEUE_FULLs on the same
-					   jiffie count on our counter, they
-					   could all be from the same event. */
+	unsigned long last_queue_full_time;	/* last queue full time */
+	unsigned long queue_ramp_up_period;	/* ramp up period in jiffies */
+	unsigned long last_queue_ramp_up;	/* last queue ramp up time */
 
 	unsigned int id, lun, channel;
 
author
#20 lore raw

PATCH 6/10 scsi: adds sdev->queue_ramp_up_period to sysfs

In reply to Vasu Dev

Adds sysfs functions to show or store sdev->queue_ramp_up_period.

Adds queue_ramp_up_period to sysfs if change_queue_depth is supported since ramp up is needed only in case the dynamic queue_depth change is supported first.

Initializes queue_ramp_up_period to 120HZ jiffies as initial default value, it is same as used in lpfc and qla2xxx.

---

 drivers/scsi/scsi_scan.c   |    1 +
 drivers/scsi/scsi_sysfs.c  |   38 ++++++++++++++++++++++++++++++++++++--
 include/scsi/scsi_device.h |    2 ++
 3 files changed, 39 insertions(+), 2 deletions(-)
drivers/scsi/scsi_scan.c +1 -0
index c447838..0e6db8b 100644
@@ -251,6 +251,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
 	sdev->model = scsi_null_device_strs;
 	sdev->rev = scsi_null_device_strs;
 	sdev->host = shost;
+	sdev->queue_ramp_up_period = SCSI_DEFAULT_RAMP_UP_PERIOD;
 	sdev->id = starget->id;
 	sdev->lun = lun;
 	sdev->channel = starget->channel;
drivers/scsi/scsi_sysfs.c +36 -2
index 4530626..9759349 100644
@@ -779,6 +779,36 @@ static struct device_attribute sdev_attr_queue_depth_rw =
 	       sdev_store_queue_depth_rw);
 
 static ssize_t
+sdev_show_queue_ramp_up_period(struct device *dev,
+			       struct device_attribute *attr,
+			       char *buf)
+{
+	struct scsi_device *sdev;
+	sdev = to_scsi_device(dev);
+	return snprintf(buf, 20, "%lu\n", sdev->queue_ramp_up_period);
+}
+
+static ssize_t
+sdev_store_queue_ramp_up_period(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	unsigned long period;
+
+	if (strict_strtoul(buf, 10, &period))
+		return -EINVAL;
+
+	sdev->queue_ramp_up_period = period;
+	return period;
+}
+
+static struct device_attribute sdev_attr_queue_ramp_up_period =
+	__ATTR(queue_ramp_up_period, S_IRUGO | S_IWUSR,
+	       sdev_show_queue_ramp_up_period,
+	       sdev_store_queue_ramp_up_period);
+
+static ssize_t
 sdev_store_queue_type_rw(struct device *dev, struct device_attribute *attr,
 			 const char *buf, size_t count)
 {
@@ -870,8 +900,12 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
 	get_device(&sdev->sdev_gendev);
 
 	/* create queue files, which may be writable, depending on the host */
-	if (sdev->host->hostt->change_queue_depth)
-		error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw);
+	if (sdev->host->hostt->change_queue_depth) {
+		error = device_create_file(&sdev->sdev_gendev,
+					   &sdev_attr_queue_depth_rw);
+		error = device_create_file(&sdev->sdev_gendev,
+					   &sdev_attr_queue_ramp_up_period);
+	}
 	else
 		error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth);
 	if (error) {
include/scsi/scsi_device.h +2 -0
index 041d4f9..899f501 100644
@@ -85,6 +85,8 @@ struct scsi_device {
 	unsigned short last_queue_full_count; /* scsi_track_queue_full() */
 	unsigned long last_queue_full_time;	/* last queue full time */
 	unsigned long queue_ramp_up_period;	/* ramp up period in jiffies */
+#define SCSI_DEFAULT_RAMP_UP_PERIOD	(120 * HZ)
+
 	unsigned long last_queue_ramp_up;	/* last queue ramp up time */
 
 	unsigned int id, lun, channel;
author
#21 lore raw

PATCH 7/10 scsi: add common queue_depth ramp up code

In reply to Vasu Dev

Adds scsi_handle_queue_ramp_up to ramp up queue_depth on successful completion of IO. The scsi_handle_queue_ramp_up will do ramp up on all luns of a target, just same as ramp down done on all luns on a target.

However ramp up is skipped if lapsed time since either last queue ramp up or down is less than LLD specified queue_ramp_up_period.

The ramp up is also skipped in case the change_queue_depth is not supported by LLD.

---

 drivers/scsi/scsi_error.c |   36 ++++++++++++++++++++++++++++++++++++
 1 files changed, 36 insertions(+), 0 deletions(-)
drivers/scsi/scsi_error.c +36 -0
index 7d1b862..c820ee7 100644
@@ -331,6 +331,40 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
 	}
 }
 
+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)
+		return;
+
+	if (time_before(jiffies,
+	    sdev->last_queue_ramp_up + sdev->queue_ramp_up_period))
+		return;
+
+	if (time_before(jiffies,
+	    sdev->last_queue_full_time + sdev->queue_ramp_up_period))
+		return;
+
+	/*
+	 * Walk all devices of a target and do
+	 * ramp up on them.
+	 */
+	shost_for_each_device(tmp_sdev, sdev->host) {
+		if ((tmp_sdev->channel != sdev->channel) ||
+		    (tmp_sdev->id != sdev->id))
+			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);
+		sdev->last_queue_ramp_up = jiffies;
+	}
+}
+
 static void scsi_handle_queue_full(struct scsi_device *sdev)
 {
 	struct scsi_host_template *sht = sdev->host->hostt;
@@ -392,6 +426,7 @@ static int scsi_eh_completed_normally(struct scsi_cmnd *scmd)
 	 */
 	switch (status_byte(scmd->result)) {
 	case GOOD:
+		scsi_handle_queue_ramp_up(scmd->device);
 	case COMMAND_TERMINATED:
 		return SUCCESS;
 	case CHECK_CONDITION:
@@ -1421,6 +1456,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
 		 */
 		return ADD_TO_MLQUEUE;
 	case GOOD:
+		scsi_handle_queue_ramp_up(scmd->device);
 	case COMMAND_TERMINATED:
 		return SUCCESS;
 	case TASK_ABORTED:
#22 lore raw

Re: [PATCH 07/10] scsi: add common queue_depth ramp up code

Quoted 40 lines · Vasu Dev

Adds scsi_handle_queue_ramp_up to ramp up queue_depth on successful completion of IO. The scsi_handle_queue_ramp_up will do ramp up on all luns of a target, just same as ramp down done on all luns on a target.

However ramp up is skipped if lapsed time since either last queue ramp up or down is less than LLD specified queue_ramp_up_period.

The ramp up is also skipped in case the change_queue_depth is not supported by LLD.

---

  drivers/scsi/scsi_error.c |   36 ++++++++++++++++++++++++++++++++++++
  1 files changed, 36 insertions(+), 0 deletions(-)
drivers/scsi/scsi_error.c +14 -0
index 7d1b862..c820ee7 100644
@@ -331,6 +331,40 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
  	}
  }
 
+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)
+		return;
+
+	if (time_before(jiffies,
+	    sdev->last_queue_ramp_up + sdev->queue_ramp_up_period))
+		return;
+
+	if (time_before(jiffies,
+	    sdev->last_queue_full_time + sdev->queue_ramp_up_period))

drivers/scsi/scsi_error.c static int scsi_check_sense(struct scsi_cmnd *scmd) · line 357

Quoted 10 lines
drivers/scsi/scsi_error.c +10 -0
+		return;
+
+	/*
+	 * Walk all devices of a target and do
+	 * ramp up on them.
+	 */
+	shost_for_each_device(tmp_sdev, sdev->host) {
+		if ((tmp_sdev->channel != sdev->channel) ||
+		    (tmp_sdev->id != sdev->id))
+			continue;

I just noticed that while on the ramp down we just check the id, but why on the ramp up do we check the channel and id?

Do we just want to adjust the devices on one specific target? If so is starget_for_each_device() better to use?

#23 lore raw

Re: [PATCH 07/10] scsi: add common queue_depth ramp up code

Quoted 9 lines · Mike Christie

drivers/scsi/scsi_error.c static int scsi_check_sense(struct scsi_cmnd *scmd) · line 357

Quoted 8 lines
drivers/scsi/scsi_error.c +8 -0
+     /*
+      * Walk all devices of a target and do
+      * ramp up on them.
+      */
+     shost_for_each_device(tmp_sdev, sdev->host) {
+             if ((tmp_sdev->channel != sdev->channel) ||
+                 (tmp_sdev->id != sdev->id))
+                     continue;
Quoted 4 lines

I just noticed that while on the ramp down we just check the id, but why
on the ramp up do we check the channel and id?

Currently qla2xxx does ramp down on all luns of a target using starget_for_each_device, so I added check for channel also just as starget_for_each_device does. The ramp down should be doing same, I'll add channel check to ramp down code also.

Quoted 2 lines

Do we just want to adjust the devices on one specific target? If so is starget_for_each_device() better to use?

I considered that but call back parameters in starget_for_each_device were not compatible with required parameters to change_queue_depth call back, later starget_for_each_device should be fixed to use it here also and that would be another API change.

Thanks
Vasu

author
#24 lore raw

PATCH 8/10 fcoe, libfc: fix an libfc issue with queue ramp down in libfc

In reply to Vasu Dev

The cmd_per_lun value is used by scsi-ml as fall back lowest queue_depth value but in case of libfc cmd_per_lun is set to same value as max queue_depth = 32.

So this patch reduces cmd_per_lun value to 3 and configures each lun with default max queue_depth 32 in fc_slave_alloc.

---

 drivers/scsi/fcoe/fcoe.c    |    2 +-
 drivers/scsi/libfc/fc_fcp.c |   14 ++++++--------
 2 files changed, 7 insertions(+), 9 deletions(-)
drivers/scsi/fcoe/fcoe.c +1 -1
index 757aa28..49dff32 100644
@@ -125,7 +125,7 @@ static struct scsi_host_template fcoe_shost_template = {
 	.change_queue_depth = fc_change_queue_depth,
 	.change_queue_type = fc_change_queue_type,
 	.this_id = -1,
-	.cmd_per_lun = 32,
+	.cmd_per_lun = 3,
 	.can_queue = FCOE_MAX_OUTSTANDING_COMMANDS,
 	.use_clustering = ENABLE_CLUSTERING,
 	.sg_tablesize = SG_ALL,
drivers/scsi/libfc/fc_fcp.c +6 -8
index d919c2a..b49f48b 100644
@@ -2031,18 +2031,16 @@ EXPORT_SYMBOL(fc_eh_host_reset);
 int fc_slave_alloc(struct scsi_device *sdev)
 {
 	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
-	int queue_depth;
 
 	if (!rport || fc_remote_port_chkready(rport))
 		return -ENXIO;
 
-	if (sdev->tagged_supported) {
-		if (sdev->host->hostt->cmd_per_lun)
-			queue_depth = sdev->host->hostt->cmd_per_lun;
-		else
-			queue_depth = FC_FCP_DFLT_QUEUE_DEPTH;
-		scsi_activate_tcq(sdev, queue_depth);
-	}
+	if (sdev->tagged_supported)
+		scsi_activate_tcq(sdev, FC_FCP_DFLT_QUEUE_DEPTH);
+	else
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev),
+					FC_FCP_DFLT_QUEUE_DEPTH);
+
 	return 0;
 }
 EXPORT_SYMBOL(fc_slave_alloc);
Acked-by on v1 8/10
#25 lore raw

Re: [PATCH 08/10] fcoe, libfc: fix an libfc issue with queue ramp down in libfc

Quoted 8 lines · Vasu

The cmd_per_lun value is used by scsi-ml as fall back lowest queue_depth value but in case of libfc cmd_per_lun is set to same value as max queue_depth = 32.

So this patch reduces cmd_per_lun value to 3 and configures each lun with default max queue_depth 32 in fc_slave_alloc.

author
#26 lore raw

PATCH 9/10 libfc: adds queue_depth ramp up to libfc

In reply to Vasu Dev

Increases queue_depth by one on fc_change_queue_depth call back with reason SCSI_QDEPTH_RAMP_UP.

---

 drivers/scsi/libfc/fc_fcp.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)
drivers/scsi/libfc/fc_fcp.c +5 -0
index b49f48b..71b49b0 100644
@@ -2054,6 +2054,11 @@ int fc_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 	case SCSI_QDEPTH_QFULL:
 		scsi_track_queue_full(sdev, qdepth);
 		break;
+	case SCSI_QDEPTH_RAMP_UP:
+		if (qdepth <= FC_FCP_DFLT_QUEUE_DEPTH)
+			scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev),
+						qdepth);
+		break;
 	default:
 		return -EOPNOTSUPP;
 	}
author
#28 lore raw

PATCH 10/10 zfcp: Adapt change_queue_depth for queue full tracking

In reply to Vasu Dev

From: Christof Schmitt <[email protected]>

Adapt the change_queue_depth callback in zfcp for the new reason parameter. Simply pass each call back to the SCSI midlayer, there are no resource adjustments necessary for zfcp.

---

 drivers/s390/scsi/zfcp_scsi.c |   16 ++++++++++++++--
 1 files changed, 14 insertions(+), 2 deletions(-)
drivers/s390/scsi/zfcp_scsi.c +14 -2
index bdff1bf..287ebb8 100644
@@ -31,9 +31,21 @@ char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *fcp_rsp_iu)
 static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth,
 					int reason)
 {
-	if (reason != SCSI_QDEPTH_DEFAULT)
+	switch (reason) {
+	case SCSI_QDEPTH_DEFAULT:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
+		break;
+	case SCSI_QDEPTH_QFULL:
+		scsi_track_queue_full(sdev, depth);
+		break;
+	case SCSI_QDEPTH_RAMP_UP:
+		if (depth <= default_depth)
+			scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev),
+						depth);
+		break;
+	default:
 		return -EOPNOTSUPP;
-	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
+	}
 	return sdev->queue_depth;
 }
 
maintainer
#29 lore raw
In reply to Vasu Dev
Quoted 17 lines · Vasu Dev

This patch series moves the QUEUE_FULL and then the ramp up code from drivers like qla2xxx and lpfc to scsi-ml. The change_queue_depth callback is used to allow the drivers to adjust the queue depth, so LLDs do not have to worry about parsing the sense, see some additional info on these changes in first RFC cover at:-

http://www.spinics.net/lists/linux-scsi/msg35959.html

I've tested this series with libfc/fcoe for queue_depth ramp down and up.

This series is based on scsi-misc -rc7 and also cleanly applies & works on top recently submitted 64 fcoe patches series by Rob "[PATCH 00/64] libfc, libfcoe and fcoe updates for scsi-misc"

Quoted 5 lines

I'm posting this series with Mike and Christof patches per this mail thread discussion
http://marc.info/?l=linux-scsi&m=125196587107768&w=2

OK, so this patch series isn't bisectable. If I just apply 1 it won't compile.

To get to bisectability it looks like patches 1,3,4 need combining. It also looks like 5,6,7 are all really the same change, so could be combined.

Could you repost with at least the bisectability fixed?

Thanks,

James

#30 lore raw
Quoted 5 lines · James Bottomley

OK, so this patch series isn't bisectable. If I just apply 1 it won't
compile.

To get to bisectability it looks like patches 1,3,4 need combining. It

Only 4 needs to be combined with 1 due to change_queue_depth() func params change in 1 and all impacted drivers by this change are modified later in patch 4 breaking patch 1. The patch 3 depended on 2, so 3 cannot be merged w/o 2, so I'll leave them as-is.

Quoted 3 lines

also looks like 5,6,7 are all really the same change, so could be combined.

Yes can be since all for added common ramp up code. I kept existing code changes separate in 5 and 6 to help in review. I'm combining them as well.

Also adding one more related change as max_queue_depth field per sdev to track max qdepth per sdev, so that ramp up won't exceed max_queue_depth which could be modified via sysfs to limit qdepth on a sdev.

Quoted 2 lines

Could you repost with at least the bisectability fixed?

I'm posting revised series with each bisectable patch on scsi-misc current top commit:-

	commit bfa27150c1ba70e2cb2d3b738025ec4803f4101e
	Author: Jing Huang <[email protected]>
	Date:   Fri Sep 25 12:29:54 2009 -0700
	[SCSI] bfa: fixed checkpatch errors for bfad files


	Thanks
	Vasu