]> www.infradead.org Git - users/hch/misc.git/commitdiff
scsi: mpi3mr: Fix I/O failures during controller reset
authorChandrakanth Patil <chandrakanth.patil@broadcom.com>
Wed, 20 Aug 2025 08:41:35 +0000 (14:11 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 26 Aug 2025 01:39:37 +0000 (21:39 -0400)
I/Os can race with controller reset and fail.

Block requests at the mid layer when reset starts using
scsi_host_block(), and resume with scsi_host_unblock() after reset
completes.

Signed-off-by: Chandrakanth Patil <chandrakanth.patil@broadcom.com>
Link: https://lore.kernel.org/r/20250820084138.228471-4-chandrakanth.patil@broadcom.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/mpi3mr/mpi3mr_fw.c
drivers/scsi/mpi3mr/mpi3mr_os.c

index 124a0aa0ed9ed6ee018056f81d65fcdc8e4af124..8fe6e0bf342e25e0aa506e1daa2524477b872313 100644 (file)
@@ -5430,6 +5430,7 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
            mpi3mr_reset_rc_name(reset_reason));
 
        mrioc->device_refresh_on = 0;
+       scsi_block_requests(mrioc->shost);
        mrioc->reset_in_progress = 1;
        mrioc->stop_bsgs = 1;
        mrioc->prev_reset_result = -1;
@@ -5538,6 +5539,7 @@ out:
        if (!retval) {
                mrioc->diagsave_timeout = 0;
                mrioc->reset_in_progress = 0;
+               scsi_unblock_requests(mrioc->shost);
                mrioc->pel_abort_requested = 0;
                if (mrioc->pel_enabled) {
                        mrioc->pel_cmds.retry_count = 0;
@@ -5562,6 +5564,7 @@ out:
                mrioc->device_refresh_on = 0;
                mrioc->unrecoverable = 1;
                mrioc->reset_in_progress = 0;
+               scsi_unblock_requests(mrioc->shost);
                mrioc->stop_bsgs = 0;
                retval = -1;
                mpi3mr_flush_cmds_for_unrecovered_controller(mrioc);
index 1582cdbc663021fd4e0e281df9771d07c45380b1..5516ac62a506552a08d2bbab5461002cdfb2834c 100644 (file)
@@ -2866,12 +2866,14 @@ static void mpi3mr_preparereset_evt_th(struct mpi3mr_ioc *mrioc,
                    "prepare for reset event top half with rc=start\n");
                if (mrioc->prepare_for_reset)
                        return;
+               scsi_block_requests(mrioc->shost);
                mrioc->prepare_for_reset = 1;
                mrioc->prepare_for_reset_timeout_counter = 0;
        } else if (evtdata->reason_code == MPI3_EVENT_PREPARE_RESET_RC_ABORT) {
                dprint_event_th(mrioc,
                    "prepare for reset top half with rc=abort\n");
                mrioc->prepare_for_reset = 0;
+               scsi_unblock_requests(mrioc->shost);
                mrioc->prepare_for_reset_timeout_counter = 0;
        }
        if ((event_reply->msg_flags & MPI3_EVENT_NOTIFY_MSGFLAGS_ACK_MASK)