scsi: megaraid_sas: Enhance prints in OCR and TM path
authorShivasharan S <shivasharan.srikanteshwara@broadcom.com>
Tue, 7 May 2019 17:05:37 +0000 (10:05 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 18 Jun 2019 23:46:19 +0000 (19:46 -0400)
This patch enhances the existing debug prints in reset and task management
path.

These debug prints in adapter reset path helps with debugging issues
related to IO timeouts that are seen frequently in the field.  Add
additional debug prints to dump the pending command frames before
initiating an adapter reset.  Also, print FastPath IOs that are
outstanding.

Signed-off-by: Sumit Saxena <sumit.saxena@broadcom.com>
Signed-off-by: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/megaraid/megaraid_sas_base.c
drivers/scsi/megaraid/megaraid_sas_fusion.c

index 6be748f..27980d6 100644 (file)
@@ -1495,7 +1495,8 @@ struct megasas_ctrl_info {
 #define MEGASAS_FW_BUSY                                1
 
 /* Driver's internal Logging levels*/
-#define OCR_LOGS    (1 << 0)
+#define OCR_DEBUG    (1 << 0)
+#define TM_DEBUG     (1 << 1)
 
 #define SCAN_PD_CHANNEL        0x1
 #define SCAN_VD_CHANNEL        0x2
@@ -2647,4 +2648,5 @@ int megasas_adp_reset_wait_for_ready(struct megasas_instance *instance,
                                     bool do_adp_reset,
                                     int ocr_context);
 int megasas_irqpoll(struct irq_poll *irqpoll, int budget);
+void megasas_dump_fusion_io(struct scsi_cmnd *scmd);
 #endif                         /*LSI_MEGARAID_SAS_H */
index 6d2390b..9712afa 100644 (file)
@@ -55,6 +55,7 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_tcq.h>
+#include <scsi/scsi_dbg.h>
 #include "megaraid_sas_fusion.h"
 #include "megaraid_sas.h"
 
@@ -2832,23 +2833,63 @@ blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
 }
 
 /**
- * megasas_dump_frame -        This function will dump MPT/MFI frame
+ * megasas_dump -      This function will provide hexdump
+ * @ptr:               Pointer starting which memory should be dumped
+ * @size:              Size of memory to be dumped
  */
-static inline void
-megasas_dump_frame(void *mpi_request, int sz)
+inline void
+megasas_dump(void *ptr, int sz)
 {
        int i;
-       __le32 *mfp = (__le32 *)mpi_request;
+       __le32 *loc = (__le32 *)ptr;
 
-       printk(KERN_INFO "IO request frame:\n\t");
        for (i = 0; i < sz / sizeof(__le32); i++) {
                if (i && ((i % 8) == 0))
                        printk("\n\t");
-               printk("%08x ", le32_to_cpu(mfp[i]));
+               printk("%08x ", le32_to_cpu(loc[i]));
        }
        printk("\n");
 }
 
+/**
+ * megasas_dump_fusion_io -    This function will print key details
+ *                             of SCSI IO
+ * @scmd:                      SCSI command pointer of SCSI IO
+ */
+void
+megasas_dump_fusion_io(struct scsi_cmnd *scmd)
+{
+       struct megasas_cmd_fusion *cmd;
+       union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
+       struct megasas_instance *instance;
+
+       cmd = (struct megasas_cmd_fusion *)scmd->SCp.ptr;
+       instance = (struct megasas_instance *)scmd->device->host->hostdata;
+
+       scmd_printk(KERN_INFO, scmd,
+                   "scmd: (0x%p)  retries: 0x%x  allowed: 0x%x\n",
+                   scmd, scmd->retries, scmd->allowed);
+       scsi_print_command(scmd);
+
+       if (cmd) {
+               req_desc = (union MEGASAS_REQUEST_DESCRIPTOR_UNION *)cmd->request_desc;
+               scmd_printk(KERN_INFO, scmd, "Request descriptor details:\n");
+               scmd_printk(KERN_INFO, scmd,
+                           "RequestFlags:0x%x  MSIxIndex:0x%x  SMID:0x%x  LMID:0x%x  DevHandle:0x%x\n",
+                           req_desc->SCSIIO.RequestFlags,
+                           req_desc->SCSIIO.MSIxIndex, req_desc->SCSIIO.SMID,
+                           req_desc->SCSIIO.LMID, req_desc->SCSIIO.DevHandle);
+
+               printk(KERN_INFO "IO request frame:\n");
+               megasas_dump(cmd->io_request,
+                            MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE);
+               printk(KERN_INFO "Chain frame:\n");
+               megasas_dump(cmd->sg_frame,
+                            instance->max_chain_frame_sz);
+       }
+
+}
+
 /**
  * megasas_reset_bus_host -    Bus & host reset handler entry point
  */
@@ -2860,24 +2901,20 @@ static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
        instance = (struct megasas_instance *)scmd->device->host->hostdata;
 
        scmd_printk(KERN_INFO, scmd,
-               "Controller reset is requested due to IO timeout\n"
-               "SCSI command pointer: (%p)\t SCSI host state: %d\t"
-               " SCSI host busy: %d\t FW outstanding: %d\n",
-               scmd, scmd->device->host->shost_state,
+               "OCR is requested due to IO timeout!!\n");
+
+       scmd_printk(KERN_INFO, scmd,
+               "SCSI host state: %d  SCSI host busy: %d  FW outstanding: %d\n",
+               scmd->device->host->shost_state,
                scsi_host_busy(scmd->device->host),
                atomic_read(&instance->fw_outstanding));
-
        /*
         * First wait for all commands to complete
         */
        if (instance->adapter_type == MFI_SERIES) {
                ret = megasas_generic_reset(scmd);
        } else {
-               struct megasas_cmd_fusion *cmd;
-               cmd = (struct megasas_cmd_fusion *)scmd->SCp.ptr;
-               if (cmd)
-                       megasas_dump_frame(cmd->io_request,
-                               MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE);
+               megasas_dump_fusion_io(scmd);
                ret = megasas_reset_fusion(scmd->device->host,
                                SCSIIO_TIMEOUT_OCR);
        }
index 66306ff..7ee9d12 100644 (file)
@@ -122,7 +122,7 @@ megasas_adp_reset_wait_for_ready(struct megasas_instance *instance,
         * Block access to PCI config space from userspace
         * when diag reset is initiated from driver
         */
-       if (megasas_dbg_lvl & OCR_LOGS)
+       if (megasas_dbg_lvl & OCR_DEBUG)
                dev_info(&instance->pdev->dev,
                         "Block access to PCI config space %s %d\n",
                         __func__, __LINE__);
@@ -145,7 +145,7 @@ megasas_adp_reset_wait_for_ready(struct megasas_instance *instance,
 
        ret = SUCCESS;
 out:
-       if (megasas_dbg_lvl & OCR_LOGS)
+       if (megasas_dbg_lvl & OCR_DEBUG)
                dev_info(&instance->pdev->dev,
                         "Unlock access to PCI config space %s %d\n",
                         __func__, __LINE__);
@@ -4518,9 +4518,6 @@ int megasas_task_abort_fusion(struct scsi_cmnd *scmd)
 
        instance = (struct megasas_instance *)scmd->device->host->hostdata;
 
-       scmd_printk(KERN_INFO, scmd, "task abort called for scmd(%p)\n", scmd);
-       scsi_print_command(scmd);
-
        if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) {
                dev_err(&instance->pdev->dev, "Controller is not OPERATIONAL,"
                "SCSI host:%d\n", instance->host->host_no);
@@ -4563,7 +4560,7 @@ int megasas_task_abort_fusion(struct scsi_cmnd *scmd)
                goto out;
        }
        sdev_printk(KERN_INFO, scmd->device,
-               "attempting task abort! scmd(%p) tm_dev_handle 0x%x\n",
+               "attempting task abort! scmd(0x%p) tm_dev_handle 0x%x\n",
                scmd, devhandle);
 
        mr_device_priv_data->tm_busy = 1;
@@ -4574,9 +4571,12 @@ int megasas_task_abort_fusion(struct scsi_cmnd *scmd)
        mr_device_priv_data->tm_busy = 0;
 
        mutex_unlock(&instance->reset_mutex);
-out:
-       sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(%p)\n",
+       scmd_printk(KERN_INFO, scmd, "task abort %s!! scmd(0x%p)\n",
                        ((ret == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
+out:
+       scsi_print_command(scmd);
+       if (megasas_dbg_lvl & TM_DEBUG)
+               megasas_dump_fusion_io(scmd);
 
        return ret;
 }
@@ -4599,9 +4599,6 @@ int megasas_reset_target_fusion(struct scsi_cmnd *scmd)
 
        instance = (struct megasas_instance *)scmd->device->host->hostdata;
 
-       sdev_printk(KERN_INFO, scmd->device,
-                   "target reset called for scmd(%p)\n", scmd);
-
        if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) {
                dev_err(&instance->pdev->dev, "Controller is not OPERATIONAL,"
                "SCSI host:%d\n", instance->host->host_no);
@@ -4610,8 +4607,8 @@ int megasas_reset_target_fusion(struct scsi_cmnd *scmd)
        }
 
        if (!mr_device_priv_data) {
-               sdev_printk(KERN_INFO, scmd->device, "device been deleted! "
-                       "scmd(%p)\n", scmd);
+               sdev_printk(KERN_INFO, scmd->device,
+                           "device been deleted! scmd: (0x%p)\n", scmd);
                scmd->result = DID_NO_CONNECT << 16;
                ret = SUCCESS;
                goto out;
@@ -4634,7 +4631,7 @@ int megasas_reset_target_fusion(struct scsi_cmnd *scmd)
        }
 
        sdev_printk(KERN_INFO, scmd->device,
-               "attempting target reset! scmd(%p) tm_dev_handle 0x%x\n",
+               "attempting target reset! scmd(0x%p) tm_dev_handle: 0x%x\n",
                scmd, devhandle);
        mr_device_priv_data->tm_busy = 1;
        ret = megasas_issue_tm(instance, devhandle,
@@ -4643,10 +4640,10 @@ int megasas_reset_target_fusion(struct scsi_cmnd *scmd)
                        mr_device_priv_data);
        mr_device_priv_data->tm_busy = 0;
        mutex_unlock(&instance->reset_mutex);
-out:
-       scmd_printk(KERN_NOTICE, scmd, "megasas: target reset %s!!\n",
+       scmd_printk(KERN_NOTICE, scmd, "target reset %s!!\n",
                (ret == SUCCESS) ? "SUCCESS" : "FAILED");
 
+out:
        return ret;
 }
 
@@ -4691,7 +4688,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason)
        struct megasas_instance *instance;
        struct megasas_cmd_fusion *cmd_fusion, *r1_cmd;
        struct fusion_context *fusion;
-       u32 abs_state, status_reg, reset_adapter;
+       u32 abs_state, status_reg, reset_adapter, fpio_count = 0;
        u32 io_timeout_in_crash_mode = 0;
        struct scsi_cmnd *scmd_local = NULL;
        struct scsi_device *sdev;
@@ -4765,7 +4762,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason)
                if (convert)
                        reason = 0;
 
-               if (megasas_dbg_lvl & OCR_LOGS)
+               if (megasas_dbg_lvl & OCR_DEBUG)
                        dev_info(&instance->pdev->dev, "\nPending SCSI commands:\n");
 
                /* Now return commands back to the OS */
@@ -4778,13 +4775,17 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason)
                        }
                        scmd_local = cmd_fusion->scmd;
                        if (cmd_fusion->scmd) {
-                               if (megasas_dbg_lvl & OCR_LOGS) {
+                               if (megasas_dbg_lvl & OCR_DEBUG) {
                                        sdev_printk(KERN_INFO,
                                                cmd_fusion->scmd->device, "SMID: 0x%x\n",
                                                cmd_fusion->index);
-                                       scsi_print_command(cmd_fusion->scmd);
+                                       megasas_dump_fusion_io(cmd_fusion->scmd);
                                }
 
+                               if (cmd_fusion->io_request->Function ==
+                                       MPI2_FUNCTION_SCSI_IO_REQUEST)
+                                       fpio_count++;
+
                                scmd_local->result =
                                        megasas_check_mpio_paths(instance,
                                                        scmd_local);
@@ -4797,6 +4798,9 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason)
                        }
                }
 
+               dev_info(&instance->pdev->dev, "Outstanding fastpath IOs: %d\n",
+                       fpio_count);
+
                atomic_set(&instance->fw_outstanding, 0);
 
                status_reg = instance->instancet->read_fw_status_reg(instance);