From: Hannes Reinecke <hare@xxxxxxxx> Replace all hand-crafted command iterations with blk_mq_tagset_busy_iter(). Signed-off-by: Hannes Reinecke <hare@xxxxxxxx> --- drivers/scsi/hpsa.c | 117 +++++++++++++++++++++++++------------------- 1 file changed, 67 insertions(+), 50 deletions(-) diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index c14dd4b6e598..64ec0b2c647a 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -1807,30 +1807,26 @@ static int hpsa_add_device(struct ctlr_info *h, struct hpsa_scsi_dev_t *device) return rc; } -static int hpsa_find_outstanding_commands_for_dev(struct ctlr_info *h, - struct hpsa_scsi_dev_t *dev) -{ - int i; - int count = 0; - - for (i = 0; i < h->nr_cmds; i++) { - struct CommandList *c = h->cmd_pool + i; - int refcount = atomic_inc_return(&c->refcount); - - if (refcount > 1 && hpsa_cmd_dev_match(h, c, dev, - dev->scsi3addr)) { - unsigned long flags; +struct hpsa_command_iter_data { + struct ctlr_info *h; + struct hpsa_scsi_dev_t *dev; + unsigned char *scsi3addr; + int count; +}; - spin_lock_irqsave(&h->lock, flags); /* Implied MB */ - if (!hpsa_is_cmd_idle(c)) - ++count; - spin_unlock_irqrestore(&h->lock, flags); - } +static bool hpsa_find_outstanding_commands_iter(struct scsi_cmnd *sc, + void *data, bool reserved) +{ + struct hpsa_command_iter_data *iter_data = data; + struct ctlr_info *h = iter_data->h; + struct hpsa_scsi_dev_t *dev = iter_data->dev; + struct CommandList *c = h->cmd_pool + sc->request->tag; - cmd_free(h, c); + if (hpsa_cmd_dev_match(h, c, dev, dev->scsi3addr)) { + iter_data->count++; + return false; } - - return count; + return true; } #define NUM_WAIT 20 @@ -1840,13 +1836,20 @@ static void hpsa_wait_for_outstanding_commands_for_dev(struct ctlr_info *h, int cmds = 0; int waits = 0; int num_wait = NUM_WAIT; + struct hpsa_command_iter_data iter_data = { + .h = h, + .dev = device, + }; if (device->external) num_wait = HPSA_EH_PTRAID_TIMEOUT; while (1) { - cmds = hpsa_find_outstanding_commands_for_dev(h, device); - if (cmds == 0) + iter_data.count = 0; + scsi_host_tagset_busy_iter(h->scsi_host, + hpsa_find_outstanding_commands_iter, + &iter_data); + if (iter_data.count == 0) break; if (++waits > num_wait) break; @@ -8128,27 +8131,34 @@ static void hpsa_undo_allocations_after_kdump_soft_reset(struct ctlr_info *h) kfree(h); /* init_one 1 */ } +static bool fail_all_outstanding_cmds_iter(struct scsi_cmnd *sc, void *data, + bool reserved) +{ + struct hpsa_command_iter_data *iter_data = data; + struct ctlr_info *h = iter_data->h; + struct CommandList *c = h->cmd_pool + sc->request->tag; + + c->err_info->CommandStatus = CMD_CTLR_LOCKUP; + finish_cmd(c); + atomic_dec(&h->commands_outstanding); + iter_data->count++; + + return true; +} + /* Called when controller lockup detected. */ static void fail_all_outstanding_cmds(struct ctlr_info *h) { - int i, refcount; - struct CommandList *c; - int failcount = 0; + struct hpsa_command_iter_data iter_data = { + .h = h, + .count = 0, + }; flush_workqueue(h->resubmit_wq); /* ensure all cmds are fully built */ - for (i = 0; i < h->nr_cmds; i++) { - c = h->cmd_pool + i; - refcount = atomic_inc_return(&c->refcount); - if (refcount > 1) { - c->err_info->CommandStatus = CMD_CTLR_LOCKUP; - finish_cmd(c); - atomic_dec(&h->commands_outstanding); - failcount++; - } - cmd_free(h, c); - } + scsi_host_tagset_busy_iter(h->scsi_host, + fail_all_outstanding_cmds_iter, &iter_data); dev_warn(&h->pdev->dev, - "failed %d commands in fail_all\n", failcount); + "failed %d commands in fail_all\n", iter_data.count); } static void set_lockup_detected_for_all_cpus(struct ctlr_info *h, u32 value) @@ -9434,22 +9444,29 @@ static int is_accelerated_cmd(struct CommandList *c) return c->cmd_type == CMD_IOACCEL1 || c->cmd_type == CMD_IOACCEL2; } +static bool hpsa_drain_accel_commands_iter(struct scsi_cmnd *sc, void *data, + bool reserved) +{ + struct hpsa_command_iter_data *iter_data = data; + struct ctlr_info *h = iter_data->h; + struct CommandList *c = h->cmd_pool + sc->request->tag; + + iter_data->count += is_accelerated_cmd(c); + return true; +} + static void hpsa_drain_accel_commands(struct ctlr_info *h) { - struct CommandList *c = NULL; - int i, accel_cmds_out; - int refcount; + struct hpsa_command_iter_data iter_data = { + .h = h, + }; do { /* wait for all outstanding ioaccel commands to drain out */ - accel_cmds_out = 0; - for (i = 0; i < h->nr_cmds; i++) { - c = h->cmd_pool + i; - refcount = atomic_inc_return(&c->refcount); - if (refcount > 1) /* Command is allocated */ - accel_cmds_out += is_accelerated_cmd(c); - cmd_free(h, c); - } - if (accel_cmds_out <= 0) + iter_data.count = 0; + scsi_host_tagset_busy_iter(h->scsi_host, + hpsa_drain_accel_commands_iter, + &iter_data); + if (iter_data.count <= 0) break; msleep(100); } while (1); -- 2.17.1