From: Ranjan Kumar Date: Fri, 20 Mar 2026 09:03:25 +0000 (+0530) Subject: scsi: mpi3mr: Add queue-full tracking for operational request queues X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9d660e482071bf0bb51f8fe3937eec7448bc8f6a;p=thirdparty%2Fkernel%2Fstable.git scsi: mpi3mr: Add queue-full tracking for operational request queues Track queue-full conditions on operational request queues in the driver. Record the last host tag returned to the SCSI mid-layer and count I/Os affected by queue-full conditions. Signed-off-by: Ranjan Kumar Link: https://patch.msgid.link/20260320090326.47544-3-ranjan.kumar@broadcom.com Signed-off-by: Martin K. Petersen --- diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h index da141c185eef..631a48f7425d 100644 --- a/drivers/scsi/mpi3mr/mpi3mr.h +++ b/drivers/scsi/mpi3mr/mpi3mr.h @@ -429,6 +429,14 @@ struct segments { * @q_segments: Segment descriptor pointer * @q_segment_list: Segment list base virtual address * @q_segment_list_dma: Segment list base DMA address + * @last_full_host_tag: Hosttag of last IO returned to SML + * due to queue full + * @qfull_io_count: Number of IOs returned back to SML + * due to queue full + * @qfull_instances: Total queue full occurrences.One occurrence + * starts with queue full detection and ends + * with queue full breaks. + * */ struct op_req_qinfo { u16 ci; @@ -442,6 +450,10 @@ struct op_req_qinfo { struct segments *q_segments; void *q_segment_list; dma_addr_t q_segment_list_dma; + u16 last_full_host_tag; + u64 qfull_io_count; + u32 qfull_instances; + }; /** diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c index b1cd7e4cf40e..54debf16c2e6 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_fw.c +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c @@ -2362,6 +2362,9 @@ static int mpi3mr_create_op_req_q(struct mpi3mr_ioc *mrioc, u16 idx, op_req_q->ci = 0; op_req_q->pi = 0; op_req_q->reply_qid = reply_qid; + op_req_q->last_full_host_tag = MPI3MR_HOSTTAG_INVALID; + op_req_q->qfull_io_count = 0; + op_req_q->qfull_instances = 0; spin_lock_init(&op_req_q->q_lock); if (!op_req_q->q_segments) { @@ -2548,6 +2551,8 @@ int mpi3mr_op_request_post(struct mpi3mr_ioc *mrioc, u16 req_sz = mrioc->facts.op_req_sz; struct segments *segments = op_req_q->q_segments; struct op_reply_qinfo *op_reply_q = NULL; + struct mpi3_scsi_io_request *scsiio_req = + (struct mpi3_scsi_io_request *)req; reply_qidx = op_req_q->reply_qid - 1; op_reply_q = mrioc->op_reply_qinfo + reply_qidx; @@ -2565,11 +2570,21 @@ int mpi3mr_op_request_post(struct mpi3mr_ioc *mrioc, mpi3mr_process_op_reply_q(mrioc, mrioc->intr_info[midx].op_reply_q); if (mpi3mr_check_req_qfull(op_req_q)) { + + if (op_req_q->last_full_host_tag == + MPI3MR_HOSTTAG_INVALID) + op_req_q->qfull_instances++; + + op_req_q->last_full_host_tag = scsiio_req->host_tag; + op_req_q->qfull_io_count++; retval = -EAGAIN; goto out; } } + if (op_req_q->last_full_host_tag != MPI3MR_HOSTTAG_INVALID) + op_req_q->last_full_host_tag = MPI3MR_HOSTTAG_INVALID; + if (mrioc->reset_in_progress) { ioc_err(mrioc, "OpReqQ submit reset in progress\n"); retval = -EAGAIN; @@ -4827,6 +4842,7 @@ void mpi3mr_memset_buffers(struct mpi3mr_ioc *mrioc) mrioc->req_qinfo[i].qid = 0; mrioc->req_qinfo[i].reply_qid = 0; spin_lock_init(&mrioc->req_qinfo[i].q_lock); + mrioc->req_qinfo[i].last_full_host_tag = 0; mpi3mr_memset_op_req_q_buffers(mrioc, i); }