]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
scsi: mpi3mr: Add queue-full tracking for operational request queues
authorRanjan Kumar <ranjan.kumar@broadcom.com>
Fri, 20 Mar 2026 09:03:25 +0000 (14:33 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 27 Mar 2026 21:09:01 +0000 (17:09 -0400)
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 <ranjan.kumar@broadcom.com>
Link: https://patch.msgid.link/20260320090326.47544-3-ranjan.kumar@broadcom.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/mpi3mr/mpi3mr.h
drivers/scsi/mpi3mr/mpi3mr_fw.c

index da141c185eef4f3ac9c8909aadd8f06cd043ccac..631a48f7425d937335a2bc0d9edc5a5ba696e92e 100644 (file)
@@ -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;
+
 };
 
 /**
index b1cd7e4cf40ebcb1fe2e9f69f91d1e5987ccab22..54debf16c2e6736cbe13b7d27949b79b3c4f44c8 100644 (file)
@@ -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);
        }