[PATCH RFC v2 19/24] aacraid: replace cmd_list with scsi_host_tagset_busy_iter()
From: John Garry
Date: Tue Mar 10 2020 - 12:31:09 EST
From: Hannes Reinecke <hare@xxxxxxxx>
As we're now using a common pool for handlng requests we can use
scsi_host_tagset_iter() to traverse commands and can drop the
legacy cmd_list usage.
Signed-off-by: Hannes Reinecke <hare@xxxxxxxx>
---
drivers/scsi/aacraid/aachba.c | 125 ++++++++++++++++++--------------
drivers/scsi/aacraid/comminit.c | 28 ++++---
drivers/scsi/aacraid/commsup.c | 38 ++++------
drivers/scsi/aacraid/linit.c | 98 +++++++++++++------------
4 files changed, 152 insertions(+), 137 deletions(-)
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 33dbc051bff9..bf2cde874303 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -809,7 +809,6 @@ int aac_probe_container(struct aac_dev *dev, int cid)
kfree(scsidev);
return -ENOMEM;
}
- scsicmd->list.next = NULL;
scsicmd->scsi_done = (void (*)(struct scsi_cmnd*))aac_probe_container_callback1;
scsicmd->device = scsidev;
@@ -2639,76 +2638,92 @@ static void synchronize_callback(void *context, struct fib *fibptr)
cmd->scsi_done(cmd);
}
+struct aac_synchronize_iter_data {
+ u64 lba;
+ u32 count;
+ int active;
+};
+
+static bool aac_synchronize_iter(struct scsi_cmnd *cmd, void *data,
+ bool reserved)
+{
+ struct aac_synchronize_iter_data *iter_data = data;
+ u64 cmnd_lba;
+ u32 cmnd_count;
+
+ if (cmd->SCp.phase != AAC_OWNER_FIRMWARE || reserved)
+ return true;
+
+ if (cmd->cmnd[0] == WRITE_6) {
+ cmnd_lba = ((cmd->cmnd[1] & 0x1F) << 16) |
+ (cmd->cmnd[2] << 8) |
+ cmd->cmnd[3];
+ cmnd_count = cmd->cmnd[4];
+ if (cmnd_count == 0)
+ cmnd_count = 256;
+ } else if (cmd->cmnd[0] == WRITE_16) {
+ cmnd_lba = ((u64)cmd->cmnd[2] << 56) |
+ ((u64)cmd->cmnd[3] << 48) |
+ ((u64)cmd->cmnd[4] << 40) |
+ ((u64)cmd->cmnd[5] << 32) |
+ ((u64)cmd->cmnd[6] << 24) |
+ (cmd->cmnd[7] << 16) |
+ (cmd->cmnd[8] << 8) |
+ cmd->cmnd[9];
+ cmnd_count = (cmd->cmnd[10] << 24) |
+ (cmd->cmnd[11] << 16) |
+ (cmd->cmnd[12] << 8) |
+ cmd->cmnd[13];
+ } else if (cmd->cmnd[0] == WRITE_12) {
+ cmnd_lba = ((u64)cmd->cmnd[2] << 24) |
+ (cmd->cmnd[3] << 16) |
+ (cmd->cmnd[4] << 8) |
+ cmd->cmnd[5];
+ cmnd_count = (cmd->cmnd[6] << 24) |
+ (cmd->cmnd[7] << 16) |
+ (cmd->cmnd[8] << 8) |
+ cmd->cmnd[9];
+ } else if (cmd->cmnd[0] == WRITE_10) {
+ cmnd_lba = ((u64)cmd->cmnd[2] << 24) |
+ (cmd->cmnd[3] << 16) |
+ (cmd->cmnd[4] << 8) |
+ cmd->cmnd[5];
+ cmnd_count = (cmd->cmnd[7] << 8) |
+ cmd->cmnd[8];
+ } else
+ return true;
+
+ if (((cmnd_lba + cmnd_count) < iter_data->lba) ||
+ (iter_data->count && ((iter_data->lba + iter_data->count) < cmnd_lba)))
+ return true;
+
+ ++iter_data->active;
+ return true;
+}
+
static int aac_synchronize(struct scsi_cmnd *scsicmd)
{
int status;
struct fib *cmd_fibcontext;
struct aac_synchronize *synchronizecmd;
- struct scsi_cmnd *cmd;
struct scsi_device *sdev = scsicmd->device;
int active = 0;
struct aac_dev *aac;
u64 lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) |
(scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
u32 count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
- unsigned long flags;
+ struct aac_synchronize_iter_data iter_data = {
+ .lba = lba,
+ .count = count,
+ .active = 0,
+ };
/*
* Wait for all outstanding queued commands to complete to this
* specific target (block).
*/
- spin_lock_irqsave(&sdev->list_lock, flags);
- list_for_each_entry(cmd, &sdev->cmd_list, list)
- if (cmd->SCp.phase == AAC_OWNER_FIRMWARE) {
- u64 cmnd_lba;
- u32 cmnd_count;
-
- if (cmd->cmnd[0] == WRITE_6) {
- cmnd_lba = ((cmd->cmnd[1] & 0x1F) << 16) |
- (cmd->cmnd[2] << 8) |
- cmd->cmnd[3];
- cmnd_count = cmd->cmnd[4];
- if (cmnd_count == 0)
- cmnd_count = 256;
- } else if (cmd->cmnd[0] == WRITE_16) {
- cmnd_lba = ((u64)cmd->cmnd[2] << 56) |
- ((u64)cmd->cmnd[3] << 48) |
- ((u64)cmd->cmnd[4] << 40) |
- ((u64)cmd->cmnd[5] << 32) |
- ((u64)cmd->cmnd[6] << 24) |
- (cmd->cmnd[7] << 16) |
- (cmd->cmnd[8] << 8) |
- cmd->cmnd[9];
- cmnd_count = (cmd->cmnd[10] << 24) |
- (cmd->cmnd[11] << 16) |
- (cmd->cmnd[12] << 8) |
- cmd->cmnd[13];
- } else if (cmd->cmnd[0] == WRITE_12) {
- cmnd_lba = ((u64)cmd->cmnd[2] << 24) |
- (cmd->cmnd[3] << 16) |
- (cmd->cmnd[4] << 8) |
- cmd->cmnd[5];
- cmnd_count = (cmd->cmnd[6] << 24) |
- (cmd->cmnd[7] << 16) |
- (cmd->cmnd[8] << 8) |
- cmd->cmnd[9];
- } else if (cmd->cmnd[0] == WRITE_10) {
- cmnd_lba = ((u64)cmd->cmnd[2] << 24) |
- (cmd->cmnd[3] << 16) |
- (cmd->cmnd[4] << 8) |
- cmd->cmnd[5];
- cmnd_count = (cmd->cmnd[7] << 8) |
- cmd->cmnd[8];
- } else
- continue;
- if (((cmnd_lba + cmnd_count) < lba) ||
- (count && ((lba + count) < cmnd_lba)))
- continue;
- ++active;
- break;
- }
-
- spin_unlock_irqrestore(&sdev->list_lock, flags);
+ scsi_host_tagset_busy_iter(sdev->host, aac_synchronize_iter,
+ &iter_data);
/*
* Yield the processor (requeue for later)
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index f75878d773cf..f84a2ca91e49 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -272,29 +272,27 @@ static void aac_queue_init(struct aac_dev * dev, struct aac_queue * q, u32 *mem,
q->entries = qsize;
}
+static bool aac_io_completion_iter(struct scsi_cmnd *command, void *data,
+ bool reserved)
+{
+ int *active = data;
+
+ if (!reserved && command->SCp.phase == AAC_OWNER_FIRMWARE)
+ (*active)++;
+ return true;
+}
+
static void aac_wait_for_io_completion(struct aac_dev *aac)
{
- unsigned long flagv = 0;
int i = 0;
+ struct Scsi_Host *shost = aac->scsi_host_ptr;
for (i = 60; i; --i) {
- struct scsi_device *dev;
- struct scsi_cmnd *command;
int active = 0;
- __shost_for_each_device(dev, aac->scsi_host_ptr) {
- spin_lock_irqsave(&dev->list_lock, flagv);
- list_for_each_entry(command, &dev->cmd_list, list) {
- if (command->SCp.phase == AAC_OWNER_FIRMWARE) {
- active++;
- break;
- }
- }
- spin_unlock_irqrestore(&dev->list_lock, flagv);
- if (active)
- break;
+ scsi_host_tagset_busy_iter(shost, aac_io_completion_iter,
+ &active);
- }
/*
* We can exit If all the commands are complete
*/
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 225d67b3177a..c0c2c87c4ae3 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -1459,14 +1459,26 @@ static void aac_schedule_bus_scan(struct aac_dev *aac)
aac_schedule_src_reinit_aif_worker(aac);
}
+static bool aac_reset_adapter_iter(struct scsi_cmnd *command, void *data,
+ bool reserved)
+{
+ if (!reserved && command->SCp.phase == AAC_OWNER_FIRMWARE) {
+ command->SCp.buffer = NULL;
+ command->result = DID_OK << 16
+ | COMMAND_COMPLETE << 8
+ | SAM_STAT_TASK_SET_FULL;
+ command->SCp.phase = AAC_OWNER_ERROR_HANDLER;
+ command->scsi_done(command);
+ }
+ return true;
+}
+
static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type)
{
int index, quirks;
int retval;
struct Scsi_Host *host;
struct scsi_device *dev;
- struct scsi_cmnd *command;
- struct scsi_cmnd *command_list;
int jafo = 0;
int bled;
u64 dmamask;
@@ -1594,26 +1606,8 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type)
* This is where the assumption that the Adapter is quiesced
* is important.
*/
- command_list = NULL;
- __shost_for_each_device(dev, host) {
- unsigned long flags;
- spin_lock_irqsave(&dev->list_lock, flags);
- list_for_each_entry(command, &dev->cmd_list, list)
- if (command->SCp.phase == AAC_OWNER_FIRMWARE) {
- command->SCp.buffer = (struct scatterlist *)command_list;
- command_list = command;
- }
- spin_unlock_irqrestore(&dev->list_lock, flags);
- }
- while ((command = command_list)) {
- command_list = (struct scsi_cmnd *)command->SCp.buffer;
- command->SCp.buffer = NULL;
- command->result = DID_OK << 16
- | COMMAND_COMPLETE << 8
- | SAM_STAT_TASK_SET_FULL;
- command->SCp.phase = AAC_OWNER_ERROR_HANDLER;
- command->scsi_done(command);
- }
+ scsi_host_tagset_busy_iter(host, aac_reset_adapter_iter, NULL);
+
/*
* Any Device that was already marked offline needs to be marked
* running
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index f027e91656c9..2da2f3bfcdc1 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -622,54 +622,63 @@ static int aac_ioctl(struct scsi_device *sdev, unsigned int cmd,
return aac_do_ioctl(dev, cmd, arg);
}
-static int get_num_of_incomplete_fibs(struct aac_dev *aac)
-{
+struct incomplete_fib_iter_data {
+ int fwcnt;
+ int ehcnt;
+ int llcnt;
+ int mlcnt;
+ int krlcnt;
+};
- unsigned long flags;
- struct scsi_device *sdev = NULL;
- struct Scsi_Host *shost = aac->scsi_host_ptr;
- struct scsi_cmnd *scmnd = NULL;
- struct device *ctrl_dev;
-
- int mlcnt = 0;
- int llcnt = 0;
- int ehcnt = 0;
- int fwcnt = 0;
- int krlcnt = 0;
-
- __shost_for_each_device(sdev, shost) {
- spin_lock_irqsave(&sdev->list_lock, flags);
- list_for_each_entry(scmnd, &sdev->cmd_list, list) {
- switch (scmnd->SCp.phase) {
- case AAC_OWNER_FIRMWARE:
- fwcnt++;
- break;
- case AAC_OWNER_ERROR_HANDLER:
- ehcnt++;
- break;
- case AAC_OWNER_LOWLEVEL:
- llcnt++;
- break;
- case AAC_OWNER_MIDLEVEL:
- mlcnt++;
- break;
- default:
- krlcnt++;
- break;
- }
- }
- spin_unlock_irqrestore(&sdev->list_lock, flags);
- }
+static bool aac_incomplete_fib_iter(struct scsi_cmnd *scmd, void *data,
+ bool reserved)
+{
+ struct incomplete_fib_iter_data *iter_data = data;
- ctrl_dev = &aac->pdev->dev;
+ if (reserved)
+ return true;
- dev_info(ctrl_dev, "outstanding cmd: midlevel-%d\n", mlcnt);
- dev_info(ctrl_dev, "outstanding cmd: lowlevel-%d\n", llcnt);
- dev_info(ctrl_dev, "outstanding cmd: error handler-%d\n", ehcnt);
- dev_info(ctrl_dev, "outstanding cmd: firmware-%d\n", fwcnt);
- dev_info(ctrl_dev, "outstanding cmd: kernel-%d\n", krlcnt);
+ switch (scmd->SCp.phase) {
+ case AAC_OWNER_FIRMWARE:
+ iter_data->fwcnt++;
+ break;
+ case AAC_OWNER_ERROR_HANDLER:
+ iter_data->ehcnt++;
+ break;
+ case AAC_OWNER_LOWLEVEL:
+ iter_data->llcnt++;
+ break;
+ case AAC_OWNER_MIDLEVEL:
+ iter_data->mlcnt++;
+ break;
+ default:
+ iter_data->krlcnt++;
+ break;
+ }
+ return true;
+}
- return mlcnt + llcnt + ehcnt + fwcnt;
+static int get_num_of_incomplete_fibs(struct aac_dev *aac)
+{
+ struct Scsi_Host *shost = aac->scsi_host_ptr;
+ struct device *ctrl_dev = &aac->pdev->dev;
+ struct incomplete_fib_iter_data iter_data = {
+ .mlcnt = 0,
+ .llcnt = 0,
+ .ehcnt = 0,
+ .fwcnt = 0,
+ .krlcnt = 0,
+ };
+
+ scsi_host_tagset_busy_iter(shost, aac_incomplete_fib_iter, &iter_data);
+
+ dev_info(ctrl_dev, "outstanding cmd: midlevel-%d\n", iter_data.mlcnt);
+ dev_info(ctrl_dev, "outstanding cmd: lowlevel-%d\n", iter_data.llcnt);
+ dev_info(ctrl_dev, "outstanding cmd: error handler-%d\n", iter_data.ehcnt);
+ dev_info(ctrl_dev, "outstanding cmd: firmware-%d\n", iter_data.fwcnt);
+ dev_info(ctrl_dev, "outstanding cmd: kernel-%d\n", iter_data.krlcnt);
+
+ return iter_data.mlcnt + iter_data.llcnt + iter_data.ehcnt + iter_data.fwcnt;
}
static int aac_eh_abort(struct scsi_cmnd* cmd)
@@ -1675,7 +1684,6 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
shost->irq = pdev->irq;
shost->unique_id = unique_id;
shost->max_cmd_len = 16;
- shost->use_cmd_list = 1;
shost->max_id = MAXIMUM_NUM_CONTAINERS;
shost->max_lun = AAC_MAX_LUN;
shost->nr_reserved_cmds = AAC_NUM_MGT_FIB;
--
2.17.1