scsi: mpi3mr: Print pending host I/Os for debugging
authorKashyap Desai <kashyap.desai@broadcom.com>
Thu, 20 May 2021 15:25:40 +0000 (20:55 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 2 Jun 2021 04:56:17 +0000 (00:56 -0400)
Link: https://lore.kernel.org/r/20210520152545.2710479-20-kashyap.desai@broadcom.com
Cc: sathya.prakash@broadcom.com
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/mpi3mr/mpi3mr_os.c

index 8dd8fb72448729837cef5dfbf34e3c4a8084e6d0..e36a5020190879dff28994b43d91c9505c667f26 100644 (file)
@@ -333,6 +333,37 @@ void mpi3mr_invalidate_devhandles(struct mpi3mr_ioc *mrioc)
        }
 }
 
+/**
+ * mpi3mr_print_scmd - print individual SCSI command
+ * @rq: Block request
+ * @data: Adapter instance reference
+ * @reserved: N/A. Currently not used
+ *
+ * Print the SCSI command details if it is in LLD scope.
+ *
+ * Return: true always.
+ */
+static bool mpi3mr_print_scmd(struct request *rq,
+       void *data, bool reserved)
+{
+       struct mpi3mr_ioc *mrioc = (struct mpi3mr_ioc *)data;
+       struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(rq);
+       struct scmd_priv *priv = NULL;
+
+       if (scmd) {
+               priv = scsi_cmd_priv(scmd);
+               if (!priv->in_lld_scope)
+                       goto out;
+
+               ioc_info(mrioc, "%s :Host Tag = %d, qid = %d\n",
+                   __func__, priv->host_tag, priv->req_q_idx + 1);
+               scsi_print_command(scmd);
+       }
+
+out:
+       return(true);
+}
+
 /**
  * mpi3mr_flush_scmd - Flush individual SCSI command
  * @rq: Block request
@@ -2341,6 +2372,43 @@ static int mpi3mr_map_queues(struct Scsi_Host *shost)
            mrioc->pdev, mrioc->op_reply_q_offset);
 }
 
+/**
+ * mpi3mr_get_fw_pending_ios - Calculate pending I/O count
+ * @mrioc: Adapter instance reference
+ *
+ * Calculate the pending I/Os for the controller and return.
+ *
+ * Return: Number of pending I/Os
+ */
+static inline int mpi3mr_get_fw_pending_ios(struct mpi3mr_ioc *mrioc)
+{
+       u16 i;
+       uint pend_ios = 0;
+
+       for (i = 0; i < mrioc->num_op_reply_q; i++)
+               pend_ios += atomic_read(&mrioc->op_reply_qinfo[i].pend_ios);
+       return pend_ios;
+}
+
+/**
+ * mpi3mr_print_pending_host_io - print pending I/Os
+ * @mrioc: Adapter instance reference
+ *
+ * Print number of pending I/Os and each I/O details prior to
+ * reset for debug purpose.
+ *
+ * Return: Nothing
+ */
+static void mpi3mr_print_pending_host_io(struct mpi3mr_ioc *mrioc)
+{
+       struct Scsi_Host *shost = mrioc->shost;
+
+       ioc_info(mrioc, "%s :Pending commands prior to reset: %d\n",
+           __func__, mpi3mr_get_fw_pending_ios(mrioc));
+       blk_mq_tagset_busy_iter(&shost->tag_set,
+           mpi3mr_print_scmd, (void *)mrioc);
+}
+
 /**
  * mpi3mr_eh_host_reset - Host reset error handling callback
  * @scmd: SCSI command reference
@@ -2357,6 +2425,7 @@ static int mpi3mr_eh_host_reset(struct scsi_cmnd *scmd)
        struct mpi3mr_ioc *mrioc = shost_priv(scmd->device->host);
        int retval = FAILED, ret;
 
+       mpi3mr_print_pending_host_io(mrioc);
        ret = mpi3mr_soft_reset_handler(mrioc,
            MPI3MR_RESET_FROM_EH_HOS, 1);
        if (ret)