diff options
author | Uma Krishnan <ukrishn@linux.vnet.ibm.com> | 2017-06-22 04:14:43 +0200 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-06-26 21:01:09 +0200 |
commit | a002bf830f5df3e622e32fdbde1756bcbb6aedad (patch) | |
tree | d65b122503a84526a3a3a0e2617a93ecbaab7e9f /drivers/scsi/cxlflash/main.c | |
parent | scsi: cxlflash: Handle AFU sync failures (diff) | |
download | linux-a002bf830f5df3e622e32fdbde1756bcbb6aedad.tar.xz linux-a002bf830f5df3e622e32fdbde1756bcbb6aedad.zip |
scsi: cxlflash: Track pending scsi commands in each hardware queue
Currently, there is no book keeping of the pending scsi commands in the
cxlflash driver. This lack of tracking in-flight requests is too
restrictive and requires a heavy-hammer reset each time an adapter error is
encountered. Additionally, it does not allow for commands to be properly
retried.
In order to avoid this problem and to better handle error path command
cleanup, introduce a linked list for each hardware queue that tracks
pending commands.
Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/cxlflash/main.c')
-rw-r--r-- | drivers/scsi/cxlflash/main.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 20c2c5e111b4..1446fabe4cf6 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -162,8 +162,13 @@ static void cmd_complete(struct afu_cmd *cmd) struct afu *afu = cmd->parent; struct cxlflash_cfg *cfg = afu->parent; struct device *dev = &cfg->dev->dev; + struct hwq *hwq = get_hwq(afu, cmd->hwq_index); bool cmd_is_tmf; + spin_lock_irqsave(&hwq->hsq_slock, lock_flags); + list_del(&cmd->list); + spin_unlock_irqrestore(&hwq->hsq_slock, lock_flags); + if (cmd->scp) { scp = cmd->scp; if (unlikely(cmd->sa.ioasc)) @@ -279,6 +284,7 @@ static int send_cmd_ioarrin(struct afu *afu, struct afu_cmd *cmd) hwq->room = room - 1; } + list_add(&cmd->list, &hwq->pending_cmds); writeq_be((u64)&cmd->rcb, &hwq->host_map->ioarrin); out: spin_unlock_irqrestore(&hwq->hsq_slock, lock_flags); @@ -319,6 +325,8 @@ static int send_cmd_sq(struct afu *afu, struct afu_cmd *cmd) hwq->hsq_curr++; else hwq->hsq_curr = hwq->hsq_start; + + list_add(&cmd->list, &hwq->pending_cmds); writeq_be((u64)hwq->hsq_curr, &hwq->host_map->sq_tail); spin_unlock_irqrestore(&hwq->hsq_slock, lock_flags); @@ -1840,6 +1848,7 @@ static int init_mc(struct cxlflash_cfg *cfg, u32 index) hwq->afu = cfg->afu; hwq->index = index; + INIT_LIST_HEAD(&hwq->pending_cmds); if (index == PRIMARY_HWQ) ctx = cxl_get_context(cfg->dev); |