]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
scsi: mpi3mr: Fix cmnd getting marked as in use forever
authorSreekanth Reddy <sreekanth.reddy@broadcom.com>
Thu, 10 Feb 2022 09:58:13 +0000 (15:28 +0530)
committerStefan Bader <stefan.bader@canonical.com>
Wed, 27 Apr 2022 10:00:31 +0000 (12:00 +0200)
BugLink: https://bugs.launchpad.net/bugs/1967116
When a driver command which requires the driver to issue a follow up
command using the same command frame is outstanding and a soft reset
operation occurs, then that driver command frame is getting marked as in
use permanently and won't be reused again.

Clear the driver command frames while flushing out the outstanding commands
and avoid issuing any new requests using these command frames while soft
reset is going on.

Link: https://lore.kernel.org/r/20220210095817.22828-6-sreekanth.reddy@broadcom.com
Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
(cherry picked from commit b3911ab3a76e216cd97c6fdc05132e57c3e6941c linux-next)
Signed-off-by: Jeff Lane <jeffrey.lane@canonical.com>
Acked-by: Tim Gardner <tim.gardner@canonical.com>
Acked-by: Paolo Pisati <paolo.pisati@canonical.com>
Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
drivers/scsi/mpi3mr/mpi3mr_os.c

index acae7660f62bc206f5f6ef88bca255bc4c2a94f7..7a86114ce6d2aeb5b6c89a902e4d28c6864310c2 100644 (file)
@@ -1583,6 +1583,9 @@ static void mpi3mr_dev_rmhs_complete_iou(struct mpi3mr_ioc *mrioc,
        u16 cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_DEVRMCMD_MIN;
        struct delayed_dev_rmhs_node *delayed_dev_rmhs = NULL;
 
+       if (drv_cmd->state & MPI3MR_CMD_RESET)
+               goto clear_drv_cmd;
+
        ioc_info(mrioc,
            "%s :dev_rmhs_iouctrl_complete:handle(0x%04x), ioc_status(0x%04x), loginfo(0x%08x)\n",
            __func__, drv_cmd->dev_handle, drv_cmd->ioc_status,
@@ -1623,6 +1626,8 @@ static void mpi3mr_dev_rmhs_complete_iou(struct mpi3mr_ioc *mrioc,
                kfree(delayed_dev_rmhs);
                return;
        }
+
+clear_drv_cmd:
        drv_cmd->state = MPI3MR_CMD_NOTUSED;
        drv_cmd->callback = NULL;
        drv_cmd->retry_count = 0;
@@ -1649,6 +1654,9 @@ static void mpi3mr_dev_rmhs_complete_tm(struct mpi3mr_ioc *mrioc,
        struct mpi3_scsi_task_mgmt_reply *tm_reply = NULL;
        int retval;
 
+       if (drv_cmd->state & MPI3MR_CMD_RESET)
+               goto clear_drv_cmd;
+
        if (drv_cmd->state & MPI3MR_CMD_REPLY_VALID)
                tm_reply = (struct mpi3_scsi_task_mgmt_reply *)drv_cmd->reply;
 
@@ -1677,11 +1685,11 @@ static void mpi3mr_dev_rmhs_complete_tm(struct mpi3mr_ioc *mrioc,
        if (retval) {
                pr_err(IOCNAME "Issue DevRmHsTMIOUCTL: Admin post failed\n",
                    mrioc->name);
-               goto out_failed;
+               goto clear_drv_cmd;
        }
 
        return;
-out_failed:
+clear_drv_cmd:
        drv_cmd->state = MPI3MR_CMD_NOTUSED;
        drv_cmd->callback = NULL;
        drv_cmd->dev_handle = MPI3MR_INVALID_DEV_HANDLE;
@@ -1796,6 +1804,9 @@ static void mpi3mr_complete_evt_ack(struct mpi3mr_ioc *mrioc,
        u16 cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_EVTACKCMD_MIN;
        struct delayed_evt_ack_node *delayed_evtack = NULL;
 
+       if (drv_cmd->state & MPI3MR_CMD_RESET)
+               goto clear_drv_cmd;
+
        if (drv_cmd->ioc_status != MPI3_IOCSTATUS_SUCCESS) {
                dprint_event_th(mrioc,
                    "immediate event ack failed with ioc_status(0x%04x) log_info(0x%08x)\n",
@@ -1813,6 +1824,7 @@ static void mpi3mr_complete_evt_ack(struct mpi3mr_ioc *mrioc,
                kfree(delayed_evtack);
                return;
        }
+clear_drv_cmd:
        drv_cmd->state = MPI3MR_CMD_NOTUSED;
        drv_cmd->callback = NULL;
        clear_bit(cmd_idx, mrioc->evtack_cmds_bitmap);