[PATCH V2 05/15] smartpqi: enhance reset logic

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Kevin Barnett <kevin.barnett@xxxxxxxxxxxxx>

Eliminated timeout from LUN reset logic.

Reviewed-by: Scott Teel <scott.teel@xxxxxxxxxxxxx>
Reviewed-by: Scott Benesh <scott.benesh@xxxxxxxxxxxxx>
Reviewed-by: Johannes Thumshirn <jthumshirn@xxxxxxx>
Reviewed-by: Tomas Henzl <thenzl@xxxxxxxxxx>
Signed-off-by: Kevin Barnett <kevin.barnett@xxxxxxxxxxxxx>
Signed-off-by: Don Brace <don.brace@xxxxxxxxxxxxx>
---
 drivers/scsi/smartpqi/smartpqi.h      |    2 -
 drivers/scsi/smartpqi/smartpqi_init.c |  101 +++++++++++----------------------
 2 files changed, 35 insertions(+), 68 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index dbcdb03..053be6b 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -370,7 +370,6 @@ struct pqi_task_management_request {
 };
 
 #define SOP_TASK_MANAGEMENT_LUN_RESET	0x8
-#define PQI_ABORT_TIMEOUT_MSECS		(20 * 1000)
 
 struct pqi_task_management_response {
 	struct pqi_iu_header header;
@@ -762,7 +761,6 @@ struct pqi_scsi_dev {
 
 	struct pqi_sas_port *sas_port;
 	struct scsi_device *sdev;
-	bool	reset_in_progress;
 
 	struct list_head scsi_device_list_entry;
 	struct list_head new_device_list_entry;
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 198a7c2..dbc8b40 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -4537,13 +4537,6 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost,
 	bool raid_bypassed;
 
 	device = scmd->device->hostdata;
-
-	if (device->reset_in_progress) {
-		set_host_byte(scmd, DID_RESET);
-		pqi_scsi_done(scmd);
-		return 0;
-	}
-
 	ctrl_info = shost_to_hba(shost);
 
 	if (pqi_ctrl_offline(ctrl_info)) {
@@ -4585,61 +4578,47 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost,
 	return rc;
 }
 
-static inline void pqi_complete_queued_requests_queue_group(
-	struct pqi_queue_group *queue_group,
-	struct pqi_scsi_dev *device_in_reset)
+static void pqi_lun_reset_complete(struct pqi_io_request *io_request,
+	void *context)
 {
-	unsigned int path;
-	unsigned long flags;
-	struct pqi_io_request *io_request;
-	struct pqi_io_request *next;
-	struct scsi_cmnd *scmd;
-	struct pqi_scsi_dev *device;
+	struct completion *waiting = context;
 
-	for (path = 0; path < 2; path++) {
-		spin_lock_irqsave(&queue_group->submit_lock[path], flags);
+	complete(waiting);
+}
 
-		list_for_each_entry_safe(io_request, next,
-			&queue_group->request_list[path],
-			request_list_entry) {
-			scmd = io_request->scmd;
-			if (!scmd)
-				continue;
-			device = scmd->device->hostdata;
-			if (device == device_in_reset) {
-				set_host_byte(scmd, DID_RESET);
-				pqi_scsi_done(scmd);
-				list_del(&io_request->
-					request_list_entry);
-			}
+#define PQI_LUN_RESET_TIMEOUT_SECS	10
+
+static int pqi_wait_for_lun_reset_completion(struct pqi_ctrl_info *ctrl_info,
+	struct pqi_scsi_dev *device, struct completion *wait)
+{
+	int rc;
+	unsigned int wait_secs = 0;
+
+	while (1) {
+		if (wait_for_completion_io_timeout(wait,
+			PQI_LUN_RESET_TIMEOUT_SECS * HZ)) {
+			rc = 0;
+			break;
 		}
 
-		spin_unlock_irqrestore(&queue_group->submit_lock[path], flags);
-	}
-}
+		pqi_check_ctrl_health(ctrl_info);
+		if (pqi_ctrl_offline(ctrl_info)) {
+			rc = -ETIMEDOUT;
+			break;
+		}
 
-static void pqi_complete_queued_requests(struct pqi_ctrl_info *ctrl_info,
-	struct pqi_scsi_dev *device_in_reset)
-{
-	unsigned int i;
-	struct pqi_queue_group *queue_group;
+		wait_secs += PQI_LUN_RESET_TIMEOUT_SECS;
 
-	for (i = 0; i < ctrl_info->num_queue_groups; i++) {
-		queue_group = &ctrl_info->queue_groups[i];
-		pqi_complete_queued_requests_queue_group(queue_group,
-			device_in_reset);
+		dev_err(&ctrl_info->pci_dev->dev,
+			"resetting scsi %d:%d:%d:%d - waiting %u seconds\n",
+			ctrl_info->scsi_host->host_no, device->bus,
+			device->target, device->lun, wait_secs);
 	}
-}
 
-static void pqi_reset_lun_complete(struct pqi_io_request *io_request,
-	void *context)
-{
-	struct completion *waiting = context;
-
-	complete(waiting);
+	return rc;
 }
 
-static int pqi_reset_lun(struct pqi_ctrl_info *ctrl_info,
+static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info,
 	struct pqi_scsi_dev *device)
 {
 	int rc;
@@ -4650,7 +4629,7 @@ static int pqi_reset_lun(struct pqi_ctrl_info *ctrl_info,
 	down(&ctrl_info->lun_reset_sem);
 
 	io_request = pqi_alloc_io_request(ctrl_info);
-	io_request->io_complete_callback = pqi_reset_lun_complete;
+	io_request->io_complete_callback = pqi_lun_reset_complete;
 	io_request->context = &wait;
 
 	request = io_request->iu;
@@ -4668,12 +4647,9 @@ static int pqi_reset_lun(struct pqi_ctrl_info *ctrl_info,
 		&ctrl_info->queue_groups[PQI_DEFAULT_QUEUE_GROUP], RAID_PATH,
 		io_request);
 
-	if (!wait_for_completion_io_timeout(&wait,
-		msecs_to_jiffies(PQI_ABORT_TIMEOUT_MSECS))) {
-		rc = -ETIMEDOUT;
-	} else {
+	rc = pqi_wait_for_lun_reset_completion(ctrl_info, device, &wait);
+	if (rc == 0)
 		rc = io_request->status;
-	}
 
 	pqi_free_io_request(io_request);
 	up(&ctrl_info->lun_reset_sem);
@@ -4692,15 +4668,9 @@ static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info,
 	if (pqi_ctrl_offline(ctrl_info))
 		return FAILED;
 
-	device->reset_in_progress = true;
-	pqi_complete_queued_requests(ctrl_info, device);
-	rc = pqi_reset_lun(ctrl_info, device);
-	device->reset_in_progress = false;
-
-	if (rc)
-		return FAILED;
+	rc = pqi_lun_reset(ctrl_info, device);
 
-	return SUCCESS;
+	return rc == 0 ? SUCCESS : FAILED;
 }
 
 static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd)
@@ -4710,7 +4680,6 @@ static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd)
 	struct pqi_scsi_dev *device;
 
 	ctrl_info = shost_to_hba(scmd->device->host);
-
 	device = scmd->device->hostdata;
 
 	dev_err(&ctrl_info->pci_dev->dev,

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



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux