git: 49445b54638f - main - mpi3mr: Block I/Os While Task Management is in Progress

From: Warner Losh <imp_at_FreeBSD.org>
Date: Mon, 28 Apr 2025 03:25:23 UTC
The branch main has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=49445b54638f7b2d45942edd61c70fe0baa28f37

commit 49445b54638f7b2d45942edd61c70fe0baa28f37
Author:     Chandrakanth patil <chandrakanth.patil@broadcom.com>
AuthorDate: 2025-04-27 23:39:43 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2025-04-28 03:22:56 +0000

    mpi3mr: Block I/Os While Task Management is in Progress
    
    The driver previously blocked I/Os only for OS-initiated task
    management commands. This patch extends the behavior to also
    block I/Os during application-initiated task management
    operations (excluding Task Abort).
    
    Before submitting such commands to the firmware, I/O
    submissions are paused for the respective device. Once the
    command completes, I/O operations are resumed.
    
    This ensures safe and consistent task management handling.
    
    [[ Note: Warner landed this with the pending suggestion
    since this change is good enough for 14.3, but chs' suggestion
    for better atomics needs to be implemented soon ]]
    
    Discussed with: imp, chs
    Differential Revision:  https://reviews.freebsd.org/D49749
---
 sys/dev/mpi3mr/mpi3mr_app.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/sys/dev/mpi3mr/mpi3mr_app.c b/sys/dev/mpi3mr/mpi3mr_app.c
index 7cd3f13e4117..3a8cf7044d26 100644
--- a/sys/dev/mpi3mr/mpi3mr_app.c
+++ b/sys/dev/mpi3mr/mpi3mr_app.c
@@ -797,6 +797,8 @@ mpi3mr_app_mptcmds(struct cdev *dev, u_long cmd, void *uarg,
 	struct mpi3mr_ioctl_mpt_dma_buffer *dma_buffers = NULL, *dma_buff = NULL;
 	struct mpi3mr_ioctl_mpirepbuf *mpirepbuf = NULL;
 	struct mpi3mr_ioctl_mptcmd *karg = (struct mpi3mr_ioctl_mptcmd *)uarg;
+	struct mpi3mr_target *tgtdev = NULL;
+	Mpi3SCSITaskMgmtRequest_t *tm_req = NULL;
 
 
 	sc = mpi3mr_app_get_adp_instance(karg->mrioc_id);
@@ -1060,6 +1062,18 @@ mpi3mr_app_mptcmds(struct cdev *dev, u_long cmd, void *uarg,
 		}
 	}
 
+	if (mpi_header->Function == MPI3_FUNCTION_SCSI_TASK_MGMT) {
+		tm_req = (Mpi3SCSITaskMgmtRequest_t *)mpi_request;
+		if (tm_req->TaskType != MPI3_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
+			tgtdev = mpi3mr_find_target_by_dev_handle(sc->cam_sc, tm_req->DevHandle);
+			if (!tgtdev) {
+				rval = ENODEV;
+				goto out;
+			}
+			mpi3mr_atomic_inc(&tgtdev->block_io);
+		}
+	}
+
 	sc->ioctl_cmds.state = MPI3MR_CMD_PENDING;
 	sc->ioctl_cmds.is_waiting = 1;
 	sc->ioctl_cmds.callback = NULL;
@@ -1178,6 +1192,9 @@ mpi3mr_app_mptcmds(struct cdev *dev, u_long cmd, void *uarg,
 		sc->mpi3mr_aen_triggered = 0;
 
 out_failed:
+	if (tgtdev)
+		mpi3mr_atomic_dec(&tgtdev->block_io);
+
 	sc->ioctl_cmds.is_senseprst = 0;
 	sc->ioctl_cmds.sensebuf = NULL;
 	sc->ioctl_cmds.state = MPI3MR_CMD_NOTUSED;