* [PATCH 00/12] hpsa updates
@ 2017-04-07 20:05 Don Brace
2017-04-07 20:05 ` [PATCH 01/12] hpsa: update identify physical device structure Don Brace
` (11 more replies)
0 siblings, 12 replies; 18+ messages in thread
From: Don Brace @ 2017-04-07 20:05 UTC (permalink / raw)
To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
Justin.Lindley, scott.benesh, POSWALD
Cc: linux-scsi
These patches are based on Linus's tree
These patches are for:
- Multipath failover support in general.
The changes are:
- update identify physical device structure
- align with FW
- stop getting enclosure info for externals
- no BMIC support
- update reset handler
- update to match out of box driver
- do not reset enclosures
- reset can sometimes hang
- rescan later if reset in progress
- wait for devices to settle.
- correct resets on retried commands
- was not calling scsi_done on retried completion
- correct queue depth for externals
- Code not in correct function
- separate monitor events from heartbeat worker
- allows driver to check for changes more frequently
without affecting controller lockup detection.
- send ioaccel requests with 0 length down raid path
- avoid hang issues for customers running older FW.
- remove abort handler
- align driver with our out of box driver
- bump driver version
- align version with out of box driver for multi-path changes
---
Don Brace (11):
hpsa: update identify physical device structure
hpsa: do not get enclosure info for external devices
hpsa: update reset handler
hpsa: do not reset enclosures
hpsa: rescan later if reset in progress
hpsa: correct resets on retried commands
hpsa: cleanup reset handler
hpsa: correct queue depth for externals
hpsa: send ioaccel requests with 0 length down raid path
hpsa: remove abort handler
hpsa: bump driver version
Scott Teel (1):
hpsa: separate monitor events from heartbeat worker
drivers/scsi/hpsa.c | 790 +++++++++--------------------------------------
drivers/scsi/hpsa.h | 3
drivers/scsi/hpsa_cmd.h | 20 +
3 files changed, 164 insertions(+), 649 deletions(-)
--
Signature
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 01/12] hpsa: update identify physical device structure
2017-04-07 20:05 [PATCH 00/12] hpsa updates Don Brace
@ 2017-04-07 20:05 ` Don Brace
2017-04-07 20:05 ` [PATCH 02/12] hpsa: do not get enclosure info for external devices Don Brace
` (10 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Don Brace @ 2017-04-07 20:05 UTC (permalink / raw)
To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
Justin.Lindley, scott.benesh, POSWALD
Cc: linux-scsi
- align with latest spec.
- added __attribute((aligned(512)))
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
drivers/scsi/hpsa_cmd.h | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 5961705..078afe4 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -809,10 +809,7 @@ struct bmic_identify_physical_device {
u8 max_temperature_degreesC;
u8 logical_blocks_per_phys_block_exp; /* phyblocksize = 512*2^exp */
__le16 current_queue_depth_limit;
- u8 switch_name[10];
- __le16 switch_port;
- u8 alternate_paths_switch_name[40];
- u8 alternate_paths_switch_port[8];
+ u8 reserved_switch_stuff[60];
__le16 power_on_hours; /* valid only if gas gauge supported */
__le16 percent_endurance_used; /* valid only if gas gauge supported. */
#define BMIC_PHYS_DRIVE_SSD_WEAROUT(idphydrv) \
@@ -828,11 +825,22 @@ struct bmic_identify_physical_device {
(idphydrv->smart_carrier_authentication == 0x01)
u8 smart_carrier_app_fw_version;
u8 smart_carrier_bootloader_fw_version;
+ u8 sanitize_support_flags;
+ u8 drive_key_flags;
u8 encryption_key_name[64];
__le32 misc_drive_flags;
__le16 dek_index;
- u8 padding[112];
-};
+ __le16 hba_drive_encryption_flags;
+ __le16 max_overwrite_time;
+ __le16 max_block_erase_time;
+ __le16 max_crypto_erase_time;
+ u8 device_connector_info[5];
+ u8 connector_name[8][8];
+ u8 page_83_id[16];
+ u8 max_link_rate[256];
+ u8 neg_phys_link_rate[256];
+ u8 box_conn_name[8];
+} __attribute((aligned(512)));
struct bmic_sense_subsystem_info {
u8 primary_slot_number;
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 02/12] hpsa: do not get enclosure info for external devices
2017-04-07 20:05 [PATCH 00/12] hpsa updates Don Brace
2017-04-07 20:05 ` [PATCH 01/12] hpsa: update identify physical device structure Don Brace
@ 2017-04-07 20:05 ` Don Brace
2017-04-07 20:06 ` [PATCH 03/12] hpsa: update reset handler Don Brace
` (9 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Don Brace @ 2017-04-07 20:05 UTC (permalink / raw)
To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
Justin.Lindley, scott.benesh, POSWALD
Cc: linux-scsi
external shelves do not support BMICs.
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
drivers/scsi/hpsa.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 73daace..8e22aed 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3353,6 +3353,11 @@ static void hpsa_get_enclosure_info(struct ctlr_info *h,
bmic_device_index = GET_BMIC_DRIVE_NUMBER(&rle->lunid[0]);
+ if (encl_dev->target == -1 || encl_dev->lun == -1) {
+ rc = IO_OK;
+ goto out;
+ }
+
if (bmic_device_index == 0xFF00 || MASKED_DEVICE(&rle->lunid[0])) {
rc = IO_OK;
goto out;
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 03/12] hpsa: update reset handler
2017-04-07 20:05 [PATCH 00/12] hpsa updates Don Brace
2017-04-07 20:05 ` [PATCH 01/12] hpsa: update identify physical device structure Don Brace
2017-04-07 20:05 ` [PATCH 02/12] hpsa: do not get enclosure info for external devices Don Brace
@ 2017-04-07 20:06 ` Don Brace
2017-04-07 20:06 ` [PATCH 04/12] hpsa: do not reset enclosures Don Brace
` (8 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Don Brace @ 2017-04-07 20:06 UTC (permalink / raw)
To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
Justin.Lindley, scott.benesh, POSWALD
Cc: linux-scsi
Use the return from TUR as a check for the
device state.
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.tell@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
drivers/scsi/hpsa.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 8e22aed..9fb30c4 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3090,7 +3090,7 @@ static int hpsa_do_reset(struct ctlr_info *h, struct hpsa_scsi_dev_t *dev,
if (unlikely(rc))
atomic_set(&dev->reset_cmds_out, 0);
else
- wait_for_device_to_become_ready(h, scsi3addr, 0);
+ rc = wait_for_device_to_become_ready(h, scsi3addr, 0);
mutex_unlock(&h->reset_mutex);
return rc;
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 04/12] hpsa: do not reset enclosures
2017-04-07 20:05 [PATCH 00/12] hpsa updates Don Brace
` (2 preceding siblings ...)
2017-04-07 20:06 ` [PATCH 03/12] hpsa: update reset handler Don Brace
@ 2017-04-07 20:06 ` Don Brace
2017-04-07 20:06 ` [PATCH 05/12] hpsa: rescan later if reset in progress Don Brace
` (7 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Don Brace @ 2017-04-07 20:06 UTC (permalink / raw)
To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
Justin.Lindley, scott.benesh, POSWALD
Cc: linux-scsi
Prevent enclosure resets.
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.tell@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
drivers/scsi/hpsa.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 9fb30c4..2990897 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -5853,6 +5853,9 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
return FAILED;
}
+ if (dev->devtype == TYPE_ENCLOSURE)
+ return SUCCESS;
+
/* if controller locked up, we can guarantee command won't complete */
if (lockup_detected(h)) {
snprintf(msg, sizeof(msg),
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 05/12] hpsa: rescan later if reset in progress
2017-04-07 20:05 [PATCH 00/12] hpsa updates Don Brace
` (3 preceding siblings ...)
2017-04-07 20:06 ` [PATCH 04/12] hpsa: do not reset enclosures Don Brace
@ 2017-04-07 20:06 ` Don Brace
2017-04-07 20:06 ` [PATCH 06/12] hpsa: correct resets on retried commands Don Brace
` (6 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Don Brace @ 2017-04-07 20:06 UTC (permalink / raw)
To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
Justin.Lindley, scott.benesh, POSWALD
Cc: linux-scsi
- schedule another scan.
- mark current scan as completed
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
drivers/scsi/hpsa.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 2990897..53a4f34 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -5620,6 +5620,7 @@ static void hpsa_scan_start(struct Scsi_Host *sh)
*/
if (h->reset_in_progress) {
h->drv_req_rescan = 1;
+ hpsa_scan_complete(h);
return;
}
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 06/12] hpsa: correct resets on retried commands
2017-04-07 20:05 [PATCH 00/12] hpsa updates Don Brace
` (4 preceding siblings ...)
2017-04-07 20:06 ` [PATCH 05/12] hpsa: rescan later if reset in progress Don Brace
@ 2017-04-07 20:06 ` Don Brace
2017-04-07 20:06 ` [PATCH 07/12] hpsa: cleanup reset handler Don Brace
` (5 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Don Brace @ 2017-04-07 20:06 UTC (permalink / raw)
To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
Justin.Lindley, scott.benesh, POSWALD
Cc: linux-scsi
- call scsi_done when the command completes.
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
drivers/scsi/hpsa.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 53a4f34..a2852da 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -5465,7 +5465,7 @@ static void hpsa_command_resubmit_worker(struct work_struct *work)
return hpsa_cmd_free_and_done(c->h, c, cmd);
}
if (c->reset_pending)
- return hpsa_cmd_resolve_and_free(c->h, c);
+ return hpsa_cmd_free_and_done(c->h, c, cmd);
if (c->abort_pending)
return hpsa_cmd_abort_and_free(c->h, c, cmd);
if (c->cmd_type == CMD_IOACCEL2) {
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 07/12] hpsa: cleanup reset handler
2017-04-07 20:05 [PATCH 00/12] hpsa updates Don Brace
` (5 preceding siblings ...)
2017-04-07 20:06 ` [PATCH 06/12] hpsa: correct resets on retried commands Don Brace
@ 2017-04-07 20:06 ` Don Brace
2017-04-11 12:35 ` Martin Wilck
2017-04-07 20:06 ` [PATCH 08/12] hpsa: correct queue depth for externals Don Brace
` (4 subsequent siblings)
11 siblings, 1 reply; 18+ messages in thread
From: Don Brace @ 2017-04-07 20:06 UTC (permalink / raw)
To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
Justin.Lindley, scott.benesh, POSWALD
Cc: linux-scsi
- mark device state sooner.
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
drivers/scsi/hpsa.c | 44 ++++++++++++++++++++++++++++++--------------
1 file changed, 30 insertions(+), 14 deletions(-)
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index a2852da..a6a37e0 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -5834,7 +5834,7 @@ static int wait_for_device_to_become_ready(struct ctlr_info *h,
*/
static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
{
- int rc;
+ int rc = SUCCESS;
struct ctlr_info *h;
struct hpsa_scsi_dev_t *dev;
u8 reset_type;
@@ -5845,17 +5845,24 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
if (h == NULL) /* paranoia */
return FAILED;
- if (lockup_detected(h))
- return FAILED;
+ h->reset_in_progress = 1;
+
+ if (lockup_detected(h)) {
+ rc = FAILED;
+ goto return_reset_status;
+ }
dev = scsicmd->device->hostdata;
if (!dev) {
dev_err(&h->pdev->dev, "%s: device lookup failed\n", __func__);
- return FAILED;
+ rc = FAILED;
+ goto return_reset_status;
}
- if (dev->devtype == TYPE_ENCLOSURE)
- return SUCCESS;
+ if (dev->devtype == TYPE_ENCLOSURE) {
+ rc = SUCCESS;
+ goto return_reset_status;
+ }
/* if controller locked up, we can guarantee command won't complete */
if (lockup_detected(h)) {
@@ -5863,7 +5870,8 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
"cmd %d RESET FAILED, lockup detected",
hpsa_get_cmd_index(scsicmd));
hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
- return FAILED;
+ rc = FAILED;
+ goto return_reset_status;
}
/* this reset request might be the result of a lockup; check */
@@ -5872,12 +5880,15 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
"cmd %d RESET FAILED, new lockup detected",
hpsa_get_cmd_index(scsicmd));
hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
- return FAILED;
+ rc = FAILED;
+ goto return_reset_status;
}
/* Do not attempt on controller */
- if (is_hba_lunid(dev->scsi3addr))
- return SUCCESS;
+ if (is_hba_lunid(dev->scsi3addr)) {
+ rc = SUCCESS;
+ goto return_reset_status;
+ }
if (is_logical_dev_addr_mode(dev->scsi3addr))
reset_type = HPSA_DEVICE_RESET_MSG;
@@ -5888,17 +5899,22 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ");
hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
- h->reset_in_progress = 1;
-
/* send a reset to the SCSI LUN which the command was sent to */
rc = hpsa_do_reset(h, dev, dev->scsi3addr, reset_type,
DEFAULT_REPLY_QUEUE);
+ if (rc == 0)
+ rc = SUCCESS;
+ else
+ rc = FAILED;
+
sprintf(msg, "reset %s %s",
reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ",
- rc == 0 ? "completed successfully" : "failed");
+ rc == SUCCESS ? "completed successfully" : "failed");
hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
+
+return_reset_status:
h->reset_in_progress = 0;
- return rc == 0 ? SUCCESS : FAILED;
+ return rc;
}
static void swizzle_abort_tag(u8 *tag)
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 08/12] hpsa: correct queue depth for externals
2017-04-07 20:05 [PATCH 00/12] hpsa updates Don Brace
` (6 preceding siblings ...)
2017-04-07 20:06 ` [PATCH 07/12] hpsa: cleanup reset handler Don Brace
@ 2017-04-07 20:06 ` Don Brace
2017-04-07 20:06 ` [PATCH 09/12] hpsa: separate monitor events from heartbeat worker Don Brace
` (3 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Don Brace @ 2017-04-07 20:06 UTC (permalink / raw)
To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
Justin.Lindley, scott.benesh, POSWALD
Cc: linux-scsi
- queue depth assignment not in correct place, had no effect.
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
drivers/scsi/hpsa.c | 22 ++++++++++------------
drivers/scsi/hpsa.h | 1 +
2 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index a6a37e0..40a87f9 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -2066,10 +2066,13 @@ static int hpsa_slave_configure(struct scsi_device *sdev)
sd = sdev->hostdata;
sdev->no_uld_attach = !sd || !sd->expose_device;
- if (sd)
- queue_depth = sd->queue_depth != 0 ?
- sd->queue_depth : sdev->host->can_queue;
- else
+ if (sd) {
+ if (sd->external)
+ queue_depth = EXTERNAL_QD;
+ else
+ queue_depth = sd->queue_depth != 0 ?
+ sd->queue_depth : sdev->host->can_queue;
+ } else
queue_depth = sdev->host->can_queue;
scsi_change_queue_depth(sdev, queue_depth);
@@ -3912,6 +3915,9 @@ static int hpsa_update_device_info(struct ctlr_info *h,
this_device->queue_depth = h->nr_cmds;
}
+ if (this_device->external)
+ this_device->queue_depth = EXTERNAL_QD;
+
if (is_OBDR_device) {
/* See if this is a One-Button-Disaster-Recovery device
* by looking for "$DR-10" at offset 43 in inquiry data.
@@ -4120,14 +4126,6 @@ static void hpsa_get_ioaccel_drive_info(struct ctlr_info *h,
int rc;
struct ext_report_lun_entry *rle;
- /*
- * external targets don't support BMIC
- */
- if (dev->external) {
- dev->queue_depth = 7;
- return;
- }
-
rle = &rlep->LUN[rle_index];
dev->ioaccel_handle = rle->ioaccel_handle;
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 6f04f2a..99539c0 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -57,6 +57,7 @@ struct hpsa_sas_phy {
bool added_to_port;
};
+#define EXTERNAL_QD 7
struct hpsa_scsi_dev_t {
unsigned int devtype;
int bus, target, lun; /* as presented to the OS */
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 09/12] hpsa: separate monitor events from heartbeat worker
2017-04-07 20:05 [PATCH 00/12] hpsa updates Don Brace
` (7 preceding siblings ...)
2017-04-07 20:06 ` [PATCH 08/12] hpsa: correct queue depth for externals Don Brace
@ 2017-04-07 20:06 ` Don Brace
2017-04-11 12:18 ` Martin Wilck
2017-04-07 20:06 ` [PATCH 10/12] hpsa: send ioaccel requests with 0 length down raid path Don Brace
` (2 subsequent siblings)
11 siblings, 1 reply; 18+ messages in thread
From: Don Brace @ 2017-04-07 20:06 UTC (permalink / raw)
To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
Justin.Lindley, scott.benesh, POSWALD
Cc: linux-scsi
From: Scott Teel <scott.teel@microsemi.com>
create new worker thread to monitor controller events
- detect controller events more frequently.
- leave heartbeat check at 30 seconds.
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
drivers/scsi/hpsa.c | 32 ++++++++++++++++++++++++++++++--
drivers/scsi/hpsa.h | 1 +
2 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 40a87f9..50f7c09 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1110,6 +1110,7 @@ static int is_firmware_flash_cmd(u8 *cdb)
*/
#define HEARTBEAT_SAMPLE_INTERVAL_DURING_FLASH (240 * HZ)
#define HEARTBEAT_SAMPLE_INTERVAL (30 * HZ)
+#define HPSA_EVENT_MONITOR_INTERVAL (15 * HZ)
static void dial_down_lockup_detection_during_fw_flash(struct ctlr_info *h,
struct CommandList *c)
{
@@ -8650,6 +8651,29 @@ static int hpsa_luns_changed(struct ctlr_info *h)
return rc;
}
+/*
+ * watch for controller events
+ */
+static void hpsa_event_monitor_worker(struct work_struct *work)
+{
+ struct ctlr_info *h = container_of(to_delayed_work(work),
+ struct ctlr_info, event_monitor_work);
+
+ if (h->remove_in_progress)
+ return;
+
+ if (hpsa_ctlr_needs_rescan(h)) {
+ scsi_host_get(h->scsi_host);
+ hpsa_ack_ctlr_events(h);
+ hpsa_scan_start(h->scsi_host);
+ scsi_host_put(h->scsi_host);
+ }
+
+ if (!h->remove_in_progress)
+ schedule_delayed_work(&h->event_monitor_work,
+ HPSA_EVENT_MONITOR_INTERVAL);
+}
+
static void hpsa_rescan_ctlr_worker(struct work_struct *work)
{
unsigned long flags;
@@ -8668,9 +8692,9 @@ static void hpsa_rescan_ctlr_worker(struct work_struct *work)
return;
}
- if (hpsa_ctlr_needs_rescan(h) || hpsa_offline_devices_ready(h)) {
+ if (h->drv_req_rescan || hpsa_offline_devices_ready(h)) {
+ h->drv_req_rescan = 0;
scsi_host_get(h->scsi_host);
- hpsa_ack_ctlr_events(h);
hpsa_scan_start(h->scsi_host);
scsi_host_put(h->scsi_host);
} else if (h->discovery_polling) {
@@ -8949,6 +8973,9 @@ static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
INIT_DELAYED_WORK(&h->rescan_ctlr_work, hpsa_rescan_ctlr_worker);
queue_delayed_work(h->rescan_ctlr_wq, &h->rescan_ctlr_work,
h->heartbeat_sample_interval);
+ INIT_DELAYED_WORK(&h->event_monitor_work, hpsa_event_monitor_worker);
+ schedule_delayed_work(&h->event_monitor_work,
+ HPSA_EVENT_MONITOR_INTERVAL);
return 0;
clean7: /* perf, sg, cmd, irq, shost, pci, lu, aer/h */
@@ -9117,6 +9144,7 @@ static void hpsa_remove_one(struct pci_dev *pdev)
spin_unlock_irqrestore(&h->lock, flags);
cancel_delayed_work_sync(&h->monitor_ctlr_work);
cancel_delayed_work_sync(&h->rescan_ctlr_work);
+ cancel_delayed_work_sync(&h->event_monitor_work);
destroy_workqueue(h->rescan_ctlr_wq);
destroy_workqueue(h->resubmit_wq);
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 99539c0..3c22ac1 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -245,6 +245,7 @@ struct ctlr_info {
u32 __percpu *lockup_detected;
struct delayed_work monitor_ctlr_work;
struct delayed_work rescan_ctlr_work;
+ struct delayed_work event_monitor_work;
int remove_in_progress;
/* Address of h->q[x] is passed to intr handler to know which queue */
u8 q[MAX_REPLY_QUEUES];
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 10/12] hpsa: send ioaccel requests with 0 length down raid path
2017-04-07 20:05 [PATCH 00/12] hpsa updates Don Brace
` (8 preceding siblings ...)
2017-04-07 20:06 ` [PATCH 09/12] hpsa: separate monitor events from heartbeat worker Don Brace
@ 2017-04-07 20:06 ` Don Brace
2017-04-07 20:06 ` [PATCH 11/12] hpsa: remove abort handler Don Brace
2017-04-07 20:06 ` [PATCH 12/12] hpsa: bump driver version Don Brace
11 siblings, 0 replies; 18+ messages in thread
From: Don Brace @ 2017-04-07 20:06 UTC (permalink / raw)
To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
Justin.Lindley, scott.benesh, POSWALD
Cc: linux-scsi
- Block I/O requests with 0 length transfers which go down
the ioaccel path. This causes lockup issues down in the basecode.
- These issues have been fixed, but there are customers who are
experiencing the issues when running older firmware.
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
drivers/scsi/hpsa.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 61 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 50f7c09..68d020a 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -4588,7 +4588,55 @@ static int hpsa_scatter_gather(struct ctlr_info *h,
return 0;
}
-#define IO_ACCEL_INELIGIBLE (1)
+#define BUFLEN 128
+static inline void warn_zero_length_transfer(struct ctlr_info *h,
+ u8 *cdb, int cdb_len,
+ const char *func)
+{
+ char buf[BUFLEN];
+ int outlen;
+ int i;
+
+ outlen = scnprintf(buf, BUFLEN,
+ "%s: Blocking zero-length request: CDB:", func);
+ for (i = 0; i < cdb_len; i++)
+ outlen += scnprintf(buf+outlen, BUFLEN - outlen,
+ "%02hhx", cdb[i]);
+ dev_warn(&h->pdev->dev, "%s\n", buf);
+}
+
+#define IO_ACCEL_INELIGIBLE 1
+/* zero-length transfers trigger hardware errors. */
+static bool is_zero_length_transfer(u8 *cdb)
+{
+ u32 block_cnt;
+
+ /* Block zero-length transfer sizes on certain commands. */
+ switch (cdb[0]) {
+ case READ_10:
+ case WRITE_10:
+ case VERIFY: /* 0x2F */
+ case WRITE_VERIFY: /* 0x2E */
+ block_cnt = get_unaligned_be16(&cdb[7]);
+ break;
+ case READ_12:
+ case WRITE_12:
+ case VERIFY_12: /* 0xAF */
+ case WRITE_VERIFY_12: /* 0xAE */
+ block_cnt = get_unaligned_be32(&cdb[6]);
+ break;
+ case READ_16:
+ case WRITE_16:
+ case VERIFY_16: /* 0x8F */
+ block_cnt = get_unaligned_be32(&cdb[10]);
+ break;
+ default:
+ return false;
+ }
+
+ return block_cnt == 0;
+}
+
static int fixup_ioaccel_cdb(u8 *cdb, int *cdb_len)
{
int is_write = 0;
@@ -4655,6 +4703,12 @@ static int hpsa_scsi_ioaccel1_queue_command(struct ctlr_info *h,
BUG_ON(cmd->cmd_len > IOACCEL1_IOFLAGS_CDBLEN_MAX);
+ if (is_zero_length_transfer(cdb)) {
+ warn_zero_length_transfer(h, cdb, cdb_len, __func__);
+ atomic_dec(&phys_disk->ioaccel_cmds_out);
+ return IO_ACCEL_INELIGIBLE;
+ }
+
if (fixup_ioaccel_cdb(cdb, &cdb_len)) {
atomic_dec(&phys_disk->ioaccel_cmds_out);
return IO_ACCEL_INELIGIBLE;
@@ -4819,6 +4873,12 @@ static int hpsa_scsi_ioaccel2_queue_command(struct ctlr_info *h,
BUG_ON(scsi_sg_count(cmd) > h->maxsgentries);
+ if (is_zero_length_transfer(cdb)) {
+ warn_zero_length_transfer(h, cdb, cdb_len, __func__);
+ atomic_dec(&phys_disk->ioaccel_cmds_out);
+ return IO_ACCEL_INELIGIBLE;
+ }
+
if (fixup_ioaccel_cdb(cdb, &cdb_len)) {
atomic_dec(&phys_disk->ioaccel_cmds_out);
return IO_ACCEL_INELIGIBLE;
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 11/12] hpsa: remove abort handler
2017-04-07 20:05 [PATCH 00/12] hpsa updates Don Brace
` (9 preceding siblings ...)
2017-04-07 20:06 ` [PATCH 10/12] hpsa: send ioaccel requests with 0 length down raid path Don Brace
@ 2017-04-07 20:06 ` Don Brace
2017-04-07 20:06 ` [PATCH 12/12] hpsa: bump driver version Don Brace
11 siblings, 0 replies; 18+ messages in thread
From: Don Brace @ 2017-04-07 20:06 UTC (permalink / raw)
To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
Justin.Lindley, scott.benesh, POSWALD
Cc: linux-scsi
- simplify the driver
- there are a lot of quirky racy conditions not handled
- causes more aborts/resets when the number of commands to
be aborted is large, such as in multi-path fail-overs.
- has been turned off in our internal driver since 8/31/2015
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
drivers/scsi/hpsa.c | 621 +--------------------------------------------------
drivers/scsi/hpsa.h | 1
2 files changed, 8 insertions(+), 614 deletions(-)
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 68d020a..33db581 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -258,7 +258,6 @@ static int hpsa_scan_finished(struct Scsi_Host *sh,
static int hpsa_change_queue_depth(struct scsi_device *sdev, int qdepth);
static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd);
-static int hpsa_eh_abort_handler(struct scsi_cmnd *scsicmd);
static int hpsa_slave_alloc(struct scsi_device *sdev);
static int hpsa_slave_configure(struct scsi_device *sdev);
static void hpsa_slave_destroy(struct scsi_device *sdev);
@@ -326,7 +325,7 @@ static inline bool hpsa_is_cmd_idle(struct CommandList *c)
static inline bool hpsa_is_pending_event(struct CommandList *c)
{
- return c->abort_pending || c->reset_pending;
+ return c->reset_pending;
}
/* extract sense key, asc, and ascq from sense data. -1 means invalid. */
@@ -581,12 +580,6 @@ static u32 soft_unresettable_controller[] = {
0x409D0E11, /* Smart Array 6400 EM */
};
-static u32 needs_abort_tags_swizzled[] = {
- 0x323D103C, /* Smart Array P700m */
- 0x324a103C, /* Smart Array P712m */
- 0x324b103C, /* SmartArray P711m */
-};
-
static int board_id_in_array(u32 a[], int nelems, u32 board_id)
{
int i;
@@ -615,12 +608,6 @@ static int ctlr_is_resettable(u32 board_id)
ctlr_is_soft_resettable(board_id);
}
-static int ctlr_needs_abort_tags_swizzled(u32 board_id)
-{
- return board_id_in_array(needs_abort_tags_swizzled,
- ARRAY_SIZE(needs_abort_tags_swizzled), board_id);
-}
-
static ssize_t host_show_resettable(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -928,8 +915,8 @@ static struct device_attribute *hpsa_shost_attrs[] = {
NULL,
};
-#define HPSA_NRESERVED_CMDS (HPSA_CMDS_RESERVED_FOR_ABORTS + \
- HPSA_CMDS_RESERVED_FOR_DRIVER + HPSA_MAX_CONCURRENT_PASSTHRUS)
+#define HPSA_NRESERVED_CMDS (HPSA_CMDS_RESERVED_FOR_DRIVER +\
+ HPSA_MAX_CONCURRENT_PASSTHRUS)
static struct scsi_host_template hpsa_driver_template = {
.module = THIS_MODULE,
@@ -941,7 +928,6 @@ static struct scsi_host_template hpsa_driver_template = {
.change_queue_depth = hpsa_change_queue_depth,
.this_id = -1,
.use_clustering = ENABLE_CLUSTERING,
- .eh_abort_handler = hpsa_eh_abort_handler,
.eh_device_reset_handler = hpsa_eh_device_reset_handler,
.ioctl = hpsa_ioctl,
.slave_alloc = hpsa_slave_alloc,
@@ -2358,26 +2344,12 @@ static void hpsa_cmd_resolve_events(struct ctlr_info *h,
bool do_wake = false;
/*
- * Prevent the following race in the abort handler:
- *
- * 1. LLD is requested to abort a SCSI command
- * 2. The SCSI command completes
- * 3. The struct CommandList associated with step 2 is made available
- * 4. New I/O request to LLD to another LUN re-uses struct CommandList
- * 5. Abort handler follows scsi_cmnd->host_scribble and
- * finds struct CommandList and tries to aborts it
- * Now we have aborted the wrong command.
- *
- * Reset c->scsi_cmd here so that the abort or reset handler will know
+ * Reset c->scsi_cmd here so that the reset handler will know
* this command has completed. Then, check to see if the handler is
* waiting for this command, and, if so, wake it.
*/
c->scsi_cmd = SCSI_CMD_IDLE;
mb(); /* Declare command idle before checking for pending events. */
- if (c->abort_pending) {
- do_wake = true;
- c->abort_pending = false;
- }
if (c->reset_pending) {
unsigned long flags;
struct hpsa_scsi_dev_t *dev;
@@ -2420,20 +2392,6 @@ static void hpsa_retry_cmd(struct ctlr_info *h, struct CommandList *c)
queue_work_on(raw_smp_processor_id(), h->resubmit_wq, &c->work);
}
-static void hpsa_set_scsi_cmd_aborted(struct scsi_cmnd *cmd)
-{
- cmd->result = DID_ABORT << 16;
-}
-
-static void hpsa_cmd_abort_and_free(struct ctlr_info *h, struct CommandList *c,
- struct scsi_cmnd *cmd)
-{
- hpsa_set_scsi_cmd_aborted(cmd);
- dev_warn(&h->pdev->dev, "CDB %16phN was aborted with status 0x%x\n",
- c->Request.CDB, c->err_info->ScsiStatus);
- hpsa_cmd_resolve_and_free(h, c);
-}
-
static void process_ioaccel2_completion(struct ctlr_info *h,
struct CommandList *c, struct scsi_cmnd *cmd,
struct hpsa_scsi_dev_t *dev)
@@ -2558,12 +2516,9 @@ static void complete_scsi_command(struct CommandList *cp)
return hpsa_cmd_free_and_done(h, cp, cmd);
}
- if ((unlikely(hpsa_is_pending_event(cp)))) {
+ if ((unlikely(hpsa_is_pending_event(cp))))
if (cp->reset_pending)
return hpsa_cmd_free_and_done(h, cp, cmd);
- if (cp->abort_pending)
- return hpsa_cmd_abort_and_free(h, cp, cmd);
- }
if (cp->cmd_type == CMD_IOACCEL2)
return process_ioaccel2_completion(h, cp, cmd, dev);
@@ -2683,8 +2638,8 @@ static void complete_scsi_command(struct CommandList *cp)
cp->Request.CDB);
break;
case CMD_ABORTED:
- /* Return now to avoid calling scsi_done(). */
- return hpsa_cmd_abort_and_free(h, cp, cmd);
+ cmd->result = DID_ABORT << 16;
+ break;
case CMD_ABORT_FAILED:
cmd->result = DID_ERROR << 16;
dev_warn(&h->pdev->dev, "CDB %16phN : abort failed\n",
@@ -3790,53 +3745,6 @@ static unsigned char hpsa_volume_offline(struct ctlr_info *h,
return HPSA_LV_OK;
}
-/*
- * Find out if a logical device supports aborts by simply trying one.
- * Smart Array may claim not to support aborts on logical drives, but
- * if a MSA2000 * is connected, the drives on that will be presented
- * by the Smart Array as logical drives, and aborts may be sent to
- * those devices successfully. So the simplest way to find out is
- * to simply try an abort and see how the device responds.
- */
-static int hpsa_device_supports_aborts(struct ctlr_info *h,
- unsigned char *scsi3addr)
-{
- struct CommandList *c;
- struct ErrorInfo *ei;
- int rc = 0;
-
- u64 tag = (u64) -1; /* bogus tag */
-
- /* Assume that physical devices support aborts */
- if (!is_logical_dev_addr_mode(scsi3addr))
- return 1;
-
- c = cmd_alloc(h);
-
- (void) fill_cmd(c, HPSA_ABORT_MSG, h, &tag, 0, 0, scsi3addr, TYPE_MSG);
- (void) hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE,
- DEFAULT_TIMEOUT);
- /* no unmap needed here because no data xfer. */
- ei = c->err_info;
- switch (ei->CommandStatus) {
- case CMD_INVALID:
- rc = 0;
- break;
- case CMD_UNABORTABLE:
- case CMD_ABORT_FAILED:
- rc = 1;
- break;
- case CMD_TMF_STATUS:
- rc = hpsa_evaluate_tmf_status(h, c);
- break;
- default:
- rc = 0;
- break;
- }
- cmd_free(h, c);
- return rc;
-}
-
static int hpsa_update_device_info(struct ctlr_info *h,
unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device,
unsigned char *is_OBDR_device)
@@ -3936,31 +3844,6 @@ static int hpsa_update_device_info(struct ctlr_info *h,
return rc;
}
-static void hpsa_update_device_supports_aborts(struct ctlr_info *h,
- struct hpsa_scsi_dev_t *dev, u8 *scsi3addr)
-{
- unsigned long flags;
- int rc, entry;
- /*
- * See if this device supports aborts. If we already know
- * the device, we already know if it supports aborts, otherwise
- * we have to find out if it supports aborts by trying one.
- */
- spin_lock_irqsave(&h->devlock, flags);
- rc = hpsa_scsi_find_entry(dev, h->dev, h->ndevices, &entry);
- if ((rc == DEVICE_SAME || rc == DEVICE_UPDATED) &&
- entry >= 0 && entry < h->ndevices) {
- dev->supports_aborts = h->dev[entry]->supports_aborts;
- spin_unlock_irqrestore(&h->devlock, flags);
- } else {
- spin_unlock_irqrestore(&h->devlock, flags);
- dev->supports_aborts =
- hpsa_device_supports_aborts(h, scsi3addr);
- if (dev->supports_aborts < 0)
- dev->supports_aborts = 0;
- }
-}
-
/*
* Helper function to assign bus, target, lun mapping of devices.
* Logical drive target and lun are assigned at this time, but
@@ -3998,35 +3881,6 @@ static void figure_bus_target_lun(struct ctlr_info *h,
0, lunid & 0x3fff);
}
-
-/*
- * Get address of physical disk used for an ioaccel2 mode command:
- * 1. Extract ioaccel2 handle from the command.
- * 2. Find a matching ioaccel2 handle from list of physical disks.
- * 3. Return:
- * 1 and set scsi3addr to address of matching physical
- * 0 if no matching physical disk was found.
- */
-static int hpsa_get_pdisk_of_ioaccel2(struct ctlr_info *h,
- struct CommandList *ioaccel2_cmd_to_abort, unsigned char *scsi3addr)
-{
- struct io_accel2_cmd *c2 =
- &h->ioaccel2_cmd_pool[ioaccel2_cmd_to_abort->cmdindex];
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&h->devlock, flags);
- for (i = 0; i < h->ndevices; i++)
- if (h->dev[i]->ioaccel_handle == le32_to_cpu(c2->scsi_nexus)) {
- memcpy(scsi3addr, h->dev[i]->scsi3addr,
- sizeof(h->dev[i]->scsi3addr));
- spin_unlock_irqrestore(&h->devlock, flags);
- return 1;
- }
- spin_unlock_irqrestore(&h->devlock, flags);
- return 0;
-}
-
static int figure_external_status(struct ctlr_info *h, int raid_ctlr_position,
int i, int nphysicals, int nlocal_logicals)
{
@@ -4391,7 +4245,6 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h)
}
figure_bus_target_lun(h, lunaddrbytes, tmpdevice);
- hpsa_update_device_supports_aborts(h, tmpdevice, lunaddrbytes);
this_device = currentsd[ncurrent];
/* Turn on discovery_polling if there are ext target devices.
@@ -5525,8 +5378,6 @@ static void hpsa_command_resubmit_worker(struct work_struct *work)
}
if (c->reset_pending)
return hpsa_cmd_free_and_done(c->h, c, cmd);
- if (c->abort_pending)
- return hpsa_cmd_abort_and_free(c->h, c, cmd);
if (c->cmd_type == CMD_IOACCEL2) {
struct ctlr_info *h = c->h;
struct io_accel2_cmd *c2 = &h->ioaccel2_cmd_pool[c->cmdindex];
@@ -5976,433 +5827,6 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
return rc;
}
-static void swizzle_abort_tag(u8 *tag)
-{
- u8 original_tag[8];
-
- memcpy(original_tag, tag, 8);
- tag[0] = original_tag[3];
- tag[1] = original_tag[2];
- tag[2] = original_tag[1];
- tag[3] = original_tag[0];
- tag[4] = original_tag[7];
- tag[5] = original_tag[6];
- tag[6] = original_tag[5];
- tag[7] = original_tag[4];
-}
-
-static void hpsa_get_tag(struct ctlr_info *h,
- struct CommandList *c, __le32 *taglower, __le32 *tagupper)
-{
- u64 tag;
- if (c->cmd_type == CMD_IOACCEL1) {
- struct io_accel1_cmd *cm1 = (struct io_accel1_cmd *)
- &h->ioaccel_cmd_pool[c->cmdindex];
- tag = le64_to_cpu(cm1->tag);
- *tagupper = cpu_to_le32(tag >> 32);
- *taglower = cpu_to_le32(tag);
- return;
- }
- if (c->cmd_type == CMD_IOACCEL2) {
- struct io_accel2_cmd *cm2 = (struct io_accel2_cmd *)
- &h->ioaccel2_cmd_pool[c->cmdindex];
- /* upper tag not used in ioaccel2 mode */
- memset(tagupper, 0, sizeof(*tagupper));
- *taglower = cm2->Tag;
- return;
- }
- tag = le64_to_cpu(c->Header.tag);
- *tagupper = cpu_to_le32(tag >> 32);
- *taglower = cpu_to_le32(tag);
-}
-
-static int hpsa_send_abort(struct ctlr_info *h, unsigned char *scsi3addr,
- struct CommandList *abort, int reply_queue)
-{
- int rc = IO_OK;
- struct CommandList *c;
- struct ErrorInfo *ei;
- __le32 tagupper, taglower;
-
- c = cmd_alloc(h);
-
- /* fill_cmd can't fail here, no buffer to map */
- (void) fill_cmd(c, HPSA_ABORT_MSG, h, &abort->Header.tag,
- 0, 0, scsi3addr, TYPE_MSG);
- if (h->needs_abort_tags_swizzled)
- swizzle_abort_tag(&c->Request.CDB[4]);
- (void) hpsa_scsi_do_simple_cmd(h, c, reply_queue, DEFAULT_TIMEOUT);
- hpsa_get_tag(h, abort, &taglower, &tagupper);
- dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: do_simple_cmd(abort) completed.\n",
- __func__, tagupper, taglower);
- /* no unmap needed here because no data xfer. */
-
- ei = c->err_info;
- switch (ei->CommandStatus) {
- case CMD_SUCCESS:
- break;
- case CMD_TMF_STATUS:
- rc = hpsa_evaluate_tmf_status(h, c);
- break;
- case CMD_UNABORTABLE: /* Very common, don't make noise. */
- rc = -1;
- break;
- default:
- dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: interpreting error.\n",
- __func__, tagupper, taglower);
- hpsa_scsi_interpret_error(h, c);
- rc = -1;
- break;
- }
- cmd_free(h, c);
- dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: Finished.\n",
- __func__, tagupper, taglower);
- return rc;
-}
-
-static void setup_ioaccel2_abort_cmd(struct CommandList *c, struct ctlr_info *h,
- struct CommandList *command_to_abort, int reply_queue)
-{
- struct io_accel2_cmd *c2 = &h->ioaccel2_cmd_pool[c->cmdindex];
- struct hpsa_tmf_struct *ac = (struct hpsa_tmf_struct *) c2;
- struct io_accel2_cmd *c2a =
- &h->ioaccel2_cmd_pool[command_to_abort->cmdindex];
- struct scsi_cmnd *scmd = command_to_abort->scsi_cmd;
- struct hpsa_scsi_dev_t *dev = scmd->device->hostdata;
-
- if (!dev)
- return;
-
- /*
- * We're overlaying struct hpsa_tmf_struct on top of something which
- * was allocated as a struct io_accel2_cmd, so we better be sure it
- * actually fits, and doesn't overrun the error info space.
- */
- BUILD_BUG_ON(sizeof(struct hpsa_tmf_struct) >
- sizeof(struct io_accel2_cmd));
- BUG_ON(offsetof(struct io_accel2_cmd, error_data) <
- offsetof(struct hpsa_tmf_struct, error_len) +
- sizeof(ac->error_len));
-
- c->cmd_type = IOACCEL2_TMF;
- c->scsi_cmd = SCSI_CMD_BUSY;
-
- /* Adjust the DMA address to point to the accelerated command buffer */
- c->busaddr = (u32) h->ioaccel2_cmd_pool_dhandle +
- (c->cmdindex * sizeof(struct io_accel2_cmd));
- BUG_ON(c->busaddr & 0x0000007F);
-
- memset(ac, 0, sizeof(*c2)); /* yes this is correct */
- ac->iu_type = IOACCEL2_IU_TMF_TYPE;
- ac->reply_queue = reply_queue;
- ac->tmf = IOACCEL2_TMF_ABORT;
- ac->it_nexus = cpu_to_le32(dev->ioaccel_handle);
- memset(ac->lun_id, 0, sizeof(ac->lun_id));
- ac->tag = cpu_to_le64(c->cmdindex << DIRECT_LOOKUP_SHIFT);
- ac->abort_tag = cpu_to_le64(le32_to_cpu(c2a->Tag));
- ac->error_ptr = cpu_to_le64(c->busaddr +
- offsetof(struct io_accel2_cmd, error_data));
- ac->error_len = cpu_to_le32(sizeof(c2->error_data));
-}
-
-/* ioaccel2 path firmware cannot handle abort task requests.
- * Change abort requests to physical target reset, and send to the
- * address of the physical disk used for the ioaccel 2 command.
- * Return 0 on success (IO_OK)
- * -1 on failure
- */
-
-static int hpsa_send_reset_as_abort_ioaccel2(struct ctlr_info *h,
- unsigned char *scsi3addr, struct CommandList *abort, int reply_queue)
-{
- int rc = IO_OK;
- struct scsi_cmnd *scmd; /* scsi command within request being aborted */
- struct hpsa_scsi_dev_t *dev; /* device to which scsi cmd was sent */
- unsigned char phys_scsi3addr[8]; /* addr of phys disk with volume */
- unsigned char *psa = &phys_scsi3addr[0];
-
- /* Get a pointer to the hpsa logical device. */
- scmd = abort->scsi_cmd;
- dev = (struct hpsa_scsi_dev_t *)(scmd->device->hostdata);
- if (dev == NULL) {
- dev_warn(&h->pdev->dev,
- "Cannot abort: no device pointer for command.\n");
- return -1; /* not abortable */
- }
-
- if (h->raid_offload_debug > 0)
- dev_info(&h->pdev->dev,
- "scsi %d:%d:%d:%d %s scsi3addr 0x%8phN\n",
- h->scsi_host->host_no, dev->bus, dev->target, dev->lun,
- "Reset as abort", scsi3addr);
-
- if (!dev->offload_enabled) {
- dev_warn(&h->pdev->dev,
- "Can't abort: device is not operating in HP SSD Smart Path mode.\n");
- return -1; /* not abortable */
- }
-
- /* Incoming scsi3addr is logical addr. We need physical disk addr. */
- if (!hpsa_get_pdisk_of_ioaccel2(h, abort, psa)) {
- dev_warn(&h->pdev->dev, "Can't abort: Failed lookup of physical address.\n");
- return -1; /* not abortable */
- }
-
- /* send the reset */
- if (h->raid_offload_debug > 0)
- dev_info(&h->pdev->dev,
- "Reset as abort: Resetting physical device at scsi3addr 0x%8phN\n",
- psa);
- rc = hpsa_do_reset(h, dev, psa, HPSA_PHYS_TARGET_RESET, reply_queue);
- if (rc != 0) {
- dev_warn(&h->pdev->dev,
- "Reset as abort: Failed on physical device at scsi3addr 0x%8phN\n",
- psa);
- return rc; /* failed to reset */
- }
-
- /* wait for device to recover */
- if (wait_for_device_to_become_ready(h, psa, reply_queue) != 0) {
- dev_warn(&h->pdev->dev,
- "Reset as abort: Failed: Device never recovered from reset: 0x%8phN\n",
- psa);
- return -1; /* failed to recover */
- }
-
- /* device recovered */
- dev_info(&h->pdev->dev,
- "Reset as abort: Device recovered from reset: scsi3addr 0x%8phN\n",
- psa);
-
- return rc; /* success */
-}
-
-static int hpsa_send_abort_ioaccel2(struct ctlr_info *h,
- struct CommandList *abort, int reply_queue)
-{
- int rc = IO_OK;
- struct CommandList *c;
- __le32 taglower, tagupper;
- struct hpsa_scsi_dev_t *dev;
- struct io_accel2_cmd *c2;
-
- dev = abort->scsi_cmd->device->hostdata;
- if (!dev)
- return -1;
-
- if (!dev->offload_enabled && !dev->hba_ioaccel_enabled)
- return -1;
-
- c = cmd_alloc(h);
- setup_ioaccel2_abort_cmd(c, h, abort, reply_queue);
- c2 = &h->ioaccel2_cmd_pool[c->cmdindex];
- (void) hpsa_scsi_do_simple_cmd(h, c, reply_queue, DEFAULT_TIMEOUT);
- hpsa_get_tag(h, abort, &taglower, &tagupper);
- dev_dbg(&h->pdev->dev,
- "%s: Tag:0x%08x:%08x: do_simple_cmd(ioaccel2 abort) completed.\n",
- __func__, tagupper, taglower);
- /* no unmap needed here because no data xfer. */
-
- dev_dbg(&h->pdev->dev,
- "%s: Tag:0x%08x:%08x: abort service response = 0x%02x.\n",
- __func__, tagupper, taglower, c2->error_data.serv_response);
- switch (c2->error_data.serv_response) {
- case IOACCEL2_SERV_RESPONSE_TMF_COMPLETE:
- case IOACCEL2_SERV_RESPONSE_TMF_SUCCESS:
- rc = 0;
- break;
- case IOACCEL2_SERV_RESPONSE_TMF_REJECTED:
- case IOACCEL2_SERV_RESPONSE_FAILURE:
- case IOACCEL2_SERV_RESPONSE_TMF_WRONG_LUN:
- rc = -1;
- break;
- default:
- dev_warn(&h->pdev->dev,
- "%s: Tag:0x%08x:%08x: unknown abort service response 0x%02x\n",
- __func__, tagupper, taglower,
- c2->error_data.serv_response);
- rc = -1;
- }
- cmd_free(h, c);
- dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: Finished.\n", __func__,
- tagupper, taglower);
- return rc;
-}
-
-static int hpsa_send_abort_both_ways(struct ctlr_info *h,
- struct hpsa_scsi_dev_t *dev, struct CommandList *abort, int reply_queue)
-{
- /*
- * ioccelerator mode 2 commands should be aborted via the
- * accelerated path, since RAID path is unaware of these commands,
- * but not all underlying firmware can handle abort TMF.
- * Change abort to physical device reset when abort TMF is unsupported.
- */
- if (abort->cmd_type == CMD_IOACCEL2) {
- if ((HPSATMF_IOACCEL_ENABLED & h->TMFSupportFlags) ||
- dev->physical_device)
- return hpsa_send_abort_ioaccel2(h, abort,
- reply_queue);
- else
- return hpsa_send_reset_as_abort_ioaccel2(h,
- dev->scsi3addr,
- abort, reply_queue);
- }
- return hpsa_send_abort(h, dev->scsi3addr, abort, reply_queue);
-}
-
-/* Find out which reply queue a command was meant to return on */
-static int hpsa_extract_reply_queue(struct ctlr_info *h,
- struct CommandList *c)
-{
- if (c->cmd_type == CMD_IOACCEL2)
- return h->ioaccel2_cmd_pool[c->cmdindex].reply_queue;
- return c->Header.ReplyQueue;
-}
-
-/*
- * Limit concurrency of abort commands to prevent
- * over-subscription of commands
- */
-static inline int wait_for_available_abort_cmd(struct ctlr_info *h)
-{
-#define ABORT_CMD_WAIT_MSECS 5000
- return !wait_event_timeout(h->abort_cmd_wait_queue,
- atomic_dec_if_positive(&h->abort_cmds_available) >= 0,
- msecs_to_jiffies(ABORT_CMD_WAIT_MSECS));
-}
-
-/* Send an abort for the specified command.
- * If the device and controller support it,
- * send a task abort request.
- */
-static int hpsa_eh_abort_handler(struct scsi_cmnd *sc)
-{
-
- int rc;
- struct ctlr_info *h;
- struct hpsa_scsi_dev_t *dev;
- struct CommandList *abort; /* pointer to command to be aborted */
- struct scsi_cmnd *as; /* ptr to scsi cmd inside aborted command. */
- char msg[256]; /* For debug messaging. */
- int ml = 0;
- __le32 tagupper, taglower;
- int refcount, reply_queue;
-
- if (sc == NULL)
- return FAILED;
-
- if (sc->device == NULL)
- return FAILED;
-
- /* Find the controller of the command to be aborted */
- h = sdev_to_hba(sc->device);
- if (h == NULL)
- return FAILED;
-
- /* Find the device of the command to be aborted */
- dev = sc->device->hostdata;
- if (!dev) {
- dev_err(&h->pdev->dev, "%s FAILED, Device lookup failed.\n",
- msg);
- return FAILED;
- }
-
- /* If controller locked up, we can guarantee command won't complete */
- if (lockup_detected(h)) {
- hpsa_show_dev_msg(KERN_WARNING, h, dev,
- "ABORT FAILED, lockup detected");
- return FAILED;
- }
-
- /* This is a good time to check if controller lockup has occurred */
- if (detect_controller_lockup(h)) {
- hpsa_show_dev_msg(KERN_WARNING, h, dev,
- "ABORT FAILED, new lockup detected");
- return FAILED;
- }
-
- /* Check that controller supports some kind of task abort */
- if (!(HPSATMF_PHYS_TASK_ABORT & h->TMFSupportFlags) &&
- !(HPSATMF_LOG_TASK_ABORT & h->TMFSupportFlags))
- return FAILED;
-
- memset(msg, 0, sizeof(msg));
- ml += sprintf(msg+ml, "scsi %d:%d:%d:%llu %s %p",
- h->scsi_host->host_no, sc->device->channel,
- sc->device->id, sc->device->lun,
- "Aborting command", sc);
-
- /* Get SCSI command to be aborted */
- abort = (struct CommandList *) sc->host_scribble;
- if (abort == NULL) {
- /* This can happen if the command already completed. */
- return SUCCESS;
- }
- refcount = atomic_inc_return(&abort->refcount);
- if (refcount == 1) { /* Command is done already. */
- cmd_free(h, abort);
- return SUCCESS;
- }
-
- /* Don't bother trying the abort if we know it won't work. */
- if (abort->cmd_type != CMD_IOACCEL2 &&
- abort->cmd_type != CMD_IOACCEL1 && !dev->supports_aborts) {
- cmd_free(h, abort);
- return FAILED;
- }
-
- /*
- * Check that we're aborting the right command.
- * It's possible the CommandList already completed and got re-used.
- */
- if (abort->scsi_cmd != sc) {
- cmd_free(h, abort);
- return SUCCESS;
- }
-
- abort->abort_pending = true;
- hpsa_get_tag(h, abort, &taglower, &tagupper);
- reply_queue = hpsa_extract_reply_queue(h, abort);
- ml += sprintf(msg+ml, "Tag:0x%08x:%08x ", tagupper, taglower);
- as = abort->scsi_cmd;
- if (as != NULL)
- ml += sprintf(msg+ml,
- "CDBLen: %d CDB: 0x%02x%02x... SN: 0x%lx ",
- as->cmd_len, as->cmnd[0], as->cmnd[1],
- as->serial_number);
- dev_warn(&h->pdev->dev, "%s BEING SENT\n", msg);
- hpsa_show_dev_msg(KERN_WARNING, h, dev, "Aborting command");
-
- /*
- * Command is in flight, or possibly already completed
- * by the firmware (but not to the scsi mid layer) but we can't
- * distinguish which. Send the abort down.
- */
- if (wait_for_available_abort_cmd(h)) {
- dev_warn(&h->pdev->dev,
- "%s FAILED, timeout waiting for an abort command to become available.\n",
- msg);
- cmd_free(h, abort);
- return FAILED;
- }
- rc = hpsa_send_abort_both_ways(h, dev, abort, reply_queue);
- atomic_inc(&h->abort_cmds_available);
- wake_up_all(&h->abort_cmd_wait_queue);
- if (rc != 0) {
- dev_warn(&h->pdev->dev, "%s SENT, FAILED\n", msg);
- hpsa_show_dev_msg(KERN_WARNING, h, dev,
- "FAILED to abort command");
- cmd_free(h, abort);
- return FAILED;
- }
- dev_info(&h->pdev->dev, "%s SENT, SUCCESS\n", msg);
- wait_event(h->event_sync_wait_queue,
- abort->scsi_cmd != sc || lockup_detected(h));
- cmd_free(h, abort);
- return !lockup_detected(h) ? SUCCESS : FAILED;
-}
-
/*
* For operations with an associated SCSI command, a command block is allocated
* at init, and managed by cmd_tagged_alloc() and cmd_tagged_free() using the
@@ -6448,9 +5872,7 @@ static void cmd_tagged_free(struct ctlr_info *h, struct CommandList *c)
{
/*
* Release our reference to the block. We don't need to do anything
- * else to free it, because it is accessed by index. (There's no point
- * in checking the result of the decrement, since we cannot guarantee
- * that there isn't a concurrent abort which is also accessing it.)
+ * else to free it, because it is accessed by index.
*/
(void)atomic_dec(&c->refcount);
}
@@ -6989,7 +6411,6 @@ static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
int cmd_type)
{
int pci_dir = XFER_NONE;
- u64 tag; /* for commands to be aborted */
c->cmd_type = CMD_IOCTL_PEND;
c->scsi_cmd = SCSI_CMD_BUSY;
@@ -7173,27 +6594,6 @@ static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
c->Request.CDB[6] = 0x00;
c->Request.CDB[7] = 0x00;
break;
- case HPSA_ABORT_MSG:
- memcpy(&tag, buff, sizeof(tag));
- dev_dbg(&h->pdev->dev,
- "Abort Tag:0x%016llx using rqst Tag:0x%016llx",
- tag, c->Header.tag);
- c->Request.CDBLen = 16;
- c->Request.type_attr_dir =
- TYPE_ATTR_DIR(cmd_type,
- ATTR_SIMPLE, XFER_WRITE);
- c->Request.Timeout = 0; /* Don't time out */
- c->Request.CDB[0] = HPSA_TASK_MANAGEMENT;
- c->Request.CDB[1] = HPSA_TMF_ABORT_TASK;
- c->Request.CDB[2] = 0x00; /* reserved */
- c->Request.CDB[3] = 0x00; /* reserved */
- /* Tag to abort goes in CDB[4]-CDB[11] */
- memcpy(&c->Request.CDB[4], &tag, sizeof(tag));
- c->Request.CDB[12] = 0x00; /* reserved */
- c->Request.CDB[13] = 0x00; /* reserved */
- c->Request.CDB[14] = 0x00; /* reserved */
- c->Request.CDB[15] = 0x00; /* reserved */
- break;
default:
dev_warn(&h->pdev->dev, "unknown message type %d\n",
cmd);
@@ -8151,9 +7551,6 @@ static int hpsa_pci_init(struct ctlr_info *h)
h->product_name = products[prod_index].product_name;
h->access = *(products[prod_index].access);
- h->needs_abort_tags_swizzled =
- ctlr_needs_abort_tags_swizzled(h->board_id);
-
pci_disable_link_state(h->pdev, PCIE_LINK_STATE_L0S |
PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM);
@@ -8858,7 +8255,6 @@ static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
spin_lock_init(&h->offline_device_lock);
spin_lock_init(&h->scan_lock);
atomic_set(&h->passthru_cmds_avail, HPSA_MAX_CONCURRENT_PASSTHRUS);
- atomic_set(&h->abort_cmds_available, HPSA_CMDS_RESERVED_FOR_ABORTS);
/* Allocate and clear per-cpu variable lockup_detected */
h->lockup_detected = alloc_percpu(u32);
@@ -8910,7 +8306,6 @@ static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
goto clean5; /* cmd, irq, shost, pci, lu, aer/h */
init_waitqueue_head(&h->scan_wait_queue);
- init_waitqueue_head(&h->abort_cmd_wait_queue);
init_waitqueue_head(&h->event_sync_wait_queue);
mutex_init(&h->reset_mutex);
h->scan_finished = 1; /* no scan currently in progress */
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 3c22ac1..182b78a 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -298,7 +298,6 @@ struct ctlr_info {
struct workqueue_struct *resubmit_wq;
struct workqueue_struct *rescan_ctlr_wq;
atomic_t abort_cmds_available;
- wait_queue_head_t abort_cmd_wait_queue;
wait_queue_head_t event_sync_wait_queue;
struct mutex reset_mutex;
u8 reset_in_progress;
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 12/12] hpsa: bump driver version
2017-04-07 20:05 [PATCH 00/12] hpsa updates Don Brace
` (10 preceding siblings ...)
2017-04-07 20:06 ` [PATCH 11/12] hpsa: remove abort handler Don Brace
@ 2017-04-07 20:06 ` Don Brace
11 siblings, 0 replies; 18+ messages in thread
From: Don Brace @ 2017-04-07 20:06 UTC (permalink / raw)
To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
Justin.Lindley, scott.benesh, POSWALD
Cc: linux-scsi
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
drivers/scsi/hpsa.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 33db581..42047f0 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -60,7 +60,7 @@
* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.'
* with an optional trailing '-' followed by a byte value (0-255).
*/
-#define HPSA_DRIVER_VERSION "3.4.18-0"
+#define HPSA_DRIVER_VERSION "3.4.20-0"
#define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")"
#define HPSA "hpsa"
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH 09/12] hpsa: separate monitor events from heartbeat worker
2017-04-07 20:06 ` [PATCH 09/12] hpsa: separate monitor events from heartbeat worker Don Brace
@ 2017-04-11 12:18 ` Martin Wilck
2017-04-27 21:10 ` Don Brace
0 siblings, 1 reply; 18+ messages in thread
From: Martin Wilck @ 2017-04-11 12:18 UTC (permalink / raw)
To: Don Brace, joseph.szczypek, gerry.morong, john.hall, jejb,
Kevin.Barnett, Mahesh.Rajashekhara, bader.alisaleh, hch,
scott.teel, Viswas.G, Justin.Lindley, scott.benesh, POSWALD
Cc: linux-scsi
On Fri, 2017-04-07 at 15:06 -0500, Don Brace wrote:
> From: Scott Teel <scott.teel@microsemi.com>
>
> create new worker thread to monitor controller events
> - detect controller events more frequently.
> - leave heartbeat check at 30 seconds.
>
> Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
> Reviewed-by: Scott Teel <scott.teel@microsemi.com>
> Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
> Signed-off-by: Don Brace <don.brace@microsemi.com>
> ---
> drivers/scsi/hpsa.c | 32 ++++++++++++++++++++++++++++++--
> drivers/scsi/hpsa.h | 1 +
> 2 files changed, 31 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
> index 40a87f9..50f7c09 100644
> --- a/drivers/scsi/hpsa.c
> +++ b/drivers/scsi/hpsa.c
> @@ -1110,6 +1110,7 @@ static int is_firmware_flash_cmd(u8 *cdb)
> */
> #define HEARTBEAT_SAMPLE_INTERVAL_DURING_FLASH (240 * HZ)
> #define HEARTBEAT_SAMPLE_INTERVAL (30 * HZ)
> +#define HPSA_EVENT_MONITOR_INTERVAL (15 * HZ)
> static void dial_down_lockup_detection_during_fw_flash(struct
> ctlr_info *h,
> struct CommandList *c)
> {
> @@ -8650,6 +8651,29 @@ static int hpsa_luns_changed(struct ctlr_info
> *h)
> return rc;
> }
>
> +/*
> + * watch for controller events
> + */
> +static void hpsa_event_monitor_worker(struct work_struct *work)
> +{
> + struct ctlr_info *h = container_of(to_delayed_work(work),
> + struct ctlr_info, event_monitor_work);
> +
> + if (h->remove_in_progress)
> + return;
> +
> + if (hpsa_ctlr_needs_rescan(h)) {
> + scsi_host_get(h->scsi_host);
> + hpsa_ack_ctlr_events(h);
> + hpsa_scan_start(h->scsi_host);
> + scsi_host_put(h->scsi_host);
> + }
> +
> + if (!h->remove_in_progress)
> + schedule_delayed_work(&h->event_monitor_work,
> + HPSA_EVENT_MONITOR_INTERVAL)
> ;
> +}
> +
> static void hpsa_rescan_ctlr_worker(struct work_struct *work)
> {
> unsigned long flags;
> @@ -8668,9 +8692,9 @@ static void hpsa_rescan_ctlr_worker(struct
> work_struct *work)
> return;
> }
>
> - if (hpsa_ctlr_needs_rescan(h) ||
> hpsa_offline_devices_ready(h)) {
> + if (h->drv_req_rescan || hpsa_offline_devices_ready(h)) {
> + h->drv_req_rescan = 0;
> scsi_host_get(h->scsi_host);
> - hpsa_ack_ctlr_events(h);
> hpsa_scan_start(h->scsi_host);
> scsi_host_put(h->scsi_host);
> } else if (h->discovery_polling) {
> @@ -8949,6 +8973,9 @@ static int hpsa_init_one(struct pci_dev *pdev,
> const struct pci_device_id *ent)
> INIT_DELAYED_WORK(&h->rescan_ctlr_work,
> hpsa_rescan_ctlr_worker);
> queue_delayed_work(h->rescan_ctlr_wq, &h->rescan_ctlr_work,
> h->heartbeat_sample_interval);
> + INIT_DELAYED_WORK(&h->event_monitor_work,
> hpsa_event_monitor_worker);
> + schedule_delayed_work(&h->event_monitor_work,
> + HPSA_EVENT_MONITOR_INTERVAL);
> return 0;
>
> clean7: /* perf, sg, cmd, irq, shost, pci, lu, aer/h */
> @@ -9117,6 +9144,7 @@ static void hpsa_remove_one(struct pci_dev
> *pdev)
> spin_unlock_irqrestore(&h->lock, flags);
> cancel_delayed_work_sync(&h->monitor_ctlr_work);
> cancel_delayed_work_sync(&h->rescan_ctlr_work);
> + cancel_delayed_work_sync(&h->event_monitor_work);
> destroy_workqueue(h->rescan_ctlr_wq);
> destroy_workqueue(h->resubmit_wq);
>
> diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
> index 99539c0..3c22ac1 100644
> --- a/drivers/scsi/hpsa.h
> +++ b/drivers/scsi/hpsa.h
> @@ -245,6 +245,7 @@ struct ctlr_info {
> u32 __percpu *lockup_detected;
> struct delayed_work monitor_ctlr_work;
> struct delayed_work rescan_ctlr_work;
> + struct delayed_work event_monitor_work;
> int remove_in_progress;
> /* Address of h->q[x] is passed to intr handler to know
> which queue */
> u8 q[MAX_REPLY_QUEUES];
The new worker thread duplicates code from hpsa_rescan_ctlr_worker. I
find this a bit irritating. Could you maybe use just a single worker,
and just check using time stamps whether the "big" heartbeat needs to
be performed?
Regards
Martin
--
Dr. Martin Wilck <mwilck@suse.com>, Tel. +49 (0)911 74053 2107
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 07/12] hpsa: cleanup reset handler
2017-04-07 20:06 ` [PATCH 07/12] hpsa: cleanup reset handler Don Brace
@ 2017-04-11 12:35 ` Martin Wilck
2017-04-26 19:01 ` Don Brace
0 siblings, 1 reply; 18+ messages in thread
From: Martin Wilck @ 2017-04-11 12:35 UTC (permalink / raw)
To: Don Brace, joseph.szczypek, gerry.morong, john.hall, jejb,
Kevin.Barnett, Mahesh.Rajashekhara, bader.alisaleh, hch,
scott.teel, Viswas.G, Justin.Lindley, scott.benesh, POSWALD
Cc: linux-scsi
On Fri, 2017-04-07 at 15:06 -0500, Don Brace wrote:
> - mark device state sooner.
>
> Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
> Reviewed-by: Scott Teel <scott.teel@microsemi.com>
> Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
> Signed-off-by: Don Brace <don.brace@microsemi.com>
> ---
> drivers/scsi/hpsa.c | 44 ++++++++++++++++++++++++++++++-----------
> ---
> 1 file changed, 30 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
> index a2852da..a6a37e0 100644
> --- a/drivers/scsi/hpsa.c
> +++ b/drivers/scsi/hpsa.c
> @@ -5834,7 +5834,7 @@ static int
> wait_for_device_to_become_ready(struct ctlr_info *h,
> */
> static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
> {
> - int rc;
> + int rc = SUCCESS;
> struct ctlr_info *h;
> struct hpsa_scsi_dev_t *dev;
> u8 reset_type;
> @@ -5845,17 +5845,24 @@ static int
> hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
> if (h == NULL) /* paranoia */
> return FAILED;
>
> - if (lockup_detected(h))
> - return FAILED;
> + h->reset_in_progress = 1;
> +
> + if (lockup_detected(h)) {
> + rc = FAILED;
> + goto return_reset_status;
> + }
if this is meant to communicate host state to other threads, maybe you
should use an atomic type for h->reset_in_progress, or locking of some
sort?
Regards,
Martin
--
Dr. Martin Wilck <mwilck@suse.com>, Tel. +49 (0)911 74053 2107
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
^ permalink raw reply [flat|nested] 18+ messages in thread
* RE: [PATCH 07/12] hpsa: cleanup reset handler
2017-04-11 12:35 ` Martin Wilck
@ 2017-04-26 19:01 ` Don Brace
0 siblings, 0 replies; 18+ messages in thread
From: Don Brace @ 2017-04-26 19:01 UTC (permalink / raw)
To: Martin Wilck, joseph.szczypek@hpe.com, Gerry Morong, John Hall,
jejb@linux.vnet.ibm.com, Kevin Barnett, Mahesh Rajashekhara,
Bader Ali - Saleh, hch@infradead.org, Scott Teel, Viswas G,
Justin Lindley, Scott Benesh, POSWALD@suse.com
Cc: linux-scsi@vger.kernel.org
> -----Original Message-----
> From: Martin Wilck [mailto:mwilck@suse.com]
> Sent: Tuesday, April 11, 2017 7:36 AM
> To: Don Brace <don.brace@microsemi.com>; joseph.szczypek@hpe.com;
> Gerry Morong <gerry.morong@microsemi.com>; John Hall
> <John.Hall@microsemi.com>; jejb@linux.vnet.ibm.com; Kevin Barnett
> <kevin.barnett@microsemi.com>; Mahesh Rajashekhara
> <mahesh.rajashekhara@microsemi.com>; Bader Ali - Saleh
> <bader.alisaleh@microsemi.com>; hch@infradead.org; Scott Teel
> <scott.teel@microsemi.com>; Viswas G <viswas.g@microsemi.com>; Justin
> Lindley <justin.lindley@microsemi.com>; Scott Benesh
> <scott.benesh@microsemi.com>; POSWALD@suse.com
> Cc: linux-scsi@vger.kernel.org
> Subject: Re: [PATCH 07/12] hpsa: cleanup reset handler
>
> EXTERNAL EMAIL
>
>
> On Fri, 2017-04-07 at 15:06 -0500, Don Brace wrote:
> > - mark device state sooner.
> >
> > Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
> > Reviewed-by: Scott Teel <scott.teel@microsemi.com>
> > Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
> > Signed-off-by: Don Brace <don.brace@microsemi.com>
> > ---
> > drivers/scsi/hpsa.c | 44 ++++++++++++++++++++++++++++++-----------
> > ---
> > 1 file changed, 30 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
> > index a2852da..a6a37e0 100644
> > --- a/drivers/scsi/hpsa.c
> > +++ b/drivers/scsi/hpsa.c
> > @@ -5834,7 +5834,7 @@ static int
> > wait_for_device_to_become_ready(struct ctlr_info *h,
> > */
> > static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
> > {
> > - int rc;
> > + int rc = SUCCESS;
> > struct ctlr_info *h;
> > struct hpsa_scsi_dev_t *dev;
> > u8 reset_type;
> > @@ -5845,17 +5845,24 @@ static int
> > hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
> > if (h == NULL) /* paranoia */
> > return FAILED;
> >
> > - if (lockup_detected(h))
> > - return FAILED;
> > + h->reset_in_progress = 1;
> > +
> > + if (lockup_detected(h)) {
> > + rc = FAILED;
> > + goto return_reset_status;
> > + }
>
> if this is meant to communicate host state to other threads, maybe you
> should use an atomic type for h->reset_in_progress, or locking of some
> sort?
>
> Regards,
> Martin
>
Agreed.
Thanks for your review. It has actually helped out...a lot.
Thanks,
Don Brace
ESC - Smart Storage
Microsemi Corporation
> --
> Dr. Martin Wilck <mwilck@suse.com>, Tel. +49 (0)911 74053 2107
> SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton
> HRB 21284 (AG Nürnberg)
^ permalink raw reply [flat|nested] 18+ messages in thread
* RE: [PATCH 09/12] hpsa: separate monitor events from heartbeat worker
2017-04-11 12:18 ` Martin Wilck
@ 2017-04-27 21:10 ` Don Brace
2017-04-28 7:06 ` Martin Wilck
0 siblings, 1 reply; 18+ messages in thread
From: Don Brace @ 2017-04-27 21:10 UTC (permalink / raw)
To: Martin Wilck, joseph.szczypek@hpe.com, Gerry Morong, John Hall,
jejb@linux.vnet.ibm.com, Kevin Barnett, Mahesh Rajashekhara,
Bader Ali - Saleh, hch@infradead.org, Scott Teel, Viswas G,
Justin Lindley, Scott Benesh, POSWALD@suse.com
Cc: linux-scsi@vger.kernel.org
> -----Original Message-----
> From: linux-scsi-owner@vger.kernel.org [mailto:linux-scsi-
> owner@vger.kernel.org] On Behalf Of Martin Wilck
> Sent: Tuesday, April 11, 2017 7:19 AM
> To: Don Brace <don.brace@microsemi.com>; joseph.szczypek@hpe.com;
> Gerry Morong <gerry.morong@microsemi.com>; John Hall
> <John.Hall@microsemi.com>; jejb@linux.vnet.ibm.com; Kevin Barnett
> <kevin.barnett@microsemi.com>; Mahesh Rajashekhara
> <mahesh.rajashekhara@microsemi.com>; Bader Ali - Saleh
> <bader.alisaleh@microsemi.com>; hch@infradead.org; Scott Teel
> <scott.teel@microsemi.com>; Viswas G <viswas.g@microsemi.com>; Justin
> Lindley <justin.lindley@microsemi.com>; Scott Benesh
> <scott.benesh@microsemi.com>; POSWALD@suse.com
> Cc: linux-scsi@vger.kernel.org
> Subject: Re: [PATCH 09/12] hpsa: separate monitor events from heartbeat
> worker
>
> > +/*
> > + * watch for controller events
> > + */
> > +static void hpsa_event_monitor_worker(struct work_struct *work)
> > +{
> > + struct ctlr_info *h = container_of(to_delayed_work(work),
> > + struct ctlr_info, event_monitor_work);
> > +
> > + if (h->remove_in_progress)
> > + return;
> > +
> > + if (hpsa_ctlr_needs_rescan(h)) {
> > + scsi_host_get(h->scsi_host);
> > + hpsa_ack_ctlr_events(h);
> > + hpsa_scan_start(h->scsi_host);
> > + scsi_host_put(h->scsi_host);
> > + }
> > +
> > + if (!h->remove_in_progress)
> > + schedule_delayed_work(&h->event_monitor_work,
> > + HPSA_EVENT_MONITOR_INTERVAL)
> > ;
> > +}
> > +
>
> The new worker thread duplicates code from hpsa_rescan_ctlr_worker. I
> find this a bit irritating. Could you maybe use just a single worker,
> and just check using time stamps whether the "big" heartbeat needs to
> be performed?
>
> Regards
> Martin
>
> --
> Dr. Martin Wilck <mwilck@suse.com>, Tel. +49 (0)911 74053 2107
> SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton
> HRB 21284 (AG Nürnberg)
We thought about that, but we want to separate controller events
from the rescan worker.
Both can cause a rescan to occur however for multipath we have
found that we need to respond faster than the normal scheduled rescan
interval for path fail-overs.
Getting controller events only involves reading a register, but
the rescan worker can obtain an updated LUN list when there
is a PTRAID device present.
However, I did refactor the patch to move common code to
a separate function.
Would this be more acceptable?
Thanks,
Don Brace
ESC - Smart Storage
Microsemi Corporation
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 09/12] hpsa: separate monitor events from heartbeat worker
2017-04-27 21:10 ` Don Brace
@ 2017-04-28 7:06 ` Martin Wilck
0 siblings, 0 replies; 18+ messages in thread
From: Martin Wilck @ 2017-04-28 7:06 UTC (permalink / raw)
To: Don Brace, joseph.szczypek@hpe.com, Gerry Morong, John Hall,
jejb@linux.vnet.ibm.com, Kevin Barnett, Mahesh Rajashekhara,
Bader Ali - Saleh, hch@infradead.org, Scott Teel, Viswas G,
Justin Lindley, Scott Benesh, POSWALD@suse.com
Cc: linux-scsi@vger.kernel.org
On Thu, 2017-04-27 at 21:10 +0000, Don Brace wrote:
> > -
> > The new worker thread duplicates code from hpsa_rescan_ctlr_worker.
> > I
> > find this a bit irritating. Could you maybe use just a single
> > worker,
> > and just check using time stamps whether the "big" heartbeat needs
> > to
> > be performed?
> >
> > Regards
> > Martin
> >
> > --
> > Dr. Martin Wilck <mwilck@suse.com>, Tel. +49 (0)911 74053 2107
> > SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham
> > Norton
> > HRB 21284 (AG Nürnberg)
>
> We thought about that, but we want to separate controller events
> from the rescan worker.
>
> Both can cause a rescan to occur however for multipath we have
> found that we need to respond faster than the normal scheduled rescan
> interval for path fail-overs.
>
> Getting controller events only involves reading a register, but
> the rescan worker can obtain an updated LUN list when there
> is a PTRAID device present.
>
> However, I did refactor the patch to move common code to
> a separate function.
>
> Would this be more acceptable?
Sounds good, yes. I'd also appreciate if you'd add these additional
comments to the commit message.
Regards
Martin
--
Dr. Martin Wilck <mwilck@suse.com>, Tel. +49 (0)911 74053 2107
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2017-04-28 7:06 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-04-07 20:05 [PATCH 00/12] hpsa updates Don Brace
2017-04-07 20:05 ` [PATCH 01/12] hpsa: update identify physical device structure Don Brace
2017-04-07 20:05 ` [PATCH 02/12] hpsa: do not get enclosure info for external devices Don Brace
2017-04-07 20:06 ` [PATCH 03/12] hpsa: update reset handler Don Brace
2017-04-07 20:06 ` [PATCH 04/12] hpsa: do not reset enclosures Don Brace
2017-04-07 20:06 ` [PATCH 05/12] hpsa: rescan later if reset in progress Don Brace
2017-04-07 20:06 ` [PATCH 06/12] hpsa: correct resets on retried commands Don Brace
2017-04-07 20:06 ` [PATCH 07/12] hpsa: cleanup reset handler Don Brace
2017-04-11 12:35 ` Martin Wilck
2017-04-26 19:01 ` Don Brace
2017-04-07 20:06 ` [PATCH 08/12] hpsa: correct queue depth for externals Don Brace
2017-04-07 20:06 ` [PATCH 09/12] hpsa: separate monitor events from heartbeat worker Don Brace
2017-04-11 12:18 ` Martin Wilck
2017-04-27 21:10 ` Don Brace
2017-04-28 7:06 ` Martin Wilck
2017-04-07 20:06 ` [PATCH 10/12] hpsa: send ioaccel requests with 0 length down raid path Don Brace
2017-04-07 20:06 ` [PATCH 11/12] hpsa: remove abort handler Don Brace
2017-04-07 20:06 ` [PATCH 12/12] hpsa: bump driver version Don Brace
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).