scsi: lpfc: Fix scsi host template for SLI3 vports
authorJames Smart <jsmart2021@gmail.com>
Sun, 22 Mar 2020 18:12:56 +0000 (11:12 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 27 Mar 2020 03:15:08 +0000 (23:15 -0400)
SCSI layer sends driver IOs with more s/g segments than driver can handle.
This results in "Too many sg segments from dma_map_sg. Config 64, seg_cnt
219" error messages from the lpfc_scsi_prep_dma_buf_s3() routine.

The was due to use the driver using individual templates for pport and
vport, host reset enabled or not, nvme vs scsi, etc. In the end, there was
a combination for a vport that didn't match the pport.

Rather than enumerating more templates and more discretionary assignments,
revert to a base template that is copied to a template specific to the
pport/vport. Then, based on role, attributes and sli type, modify the
fields that are different for that port.  Added a log message to
lpfc_create_port to validate values.

Link: https://lore.kernel.org/r/20200322181304.37655-5-jsmart2021@gmail.com
Signed-off-by: James Smart <jsmart2021@gmail.com>
Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_crtn.h
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_scsi.c

index 357fdec..e940a49 100644 (file)
@@ -1225,6 +1225,11 @@ struct lpfc_hba {
 #define LPFC_POLL_SLOWPATH     1       /* called from slowpath */
 
        char os_host_name[MAXHOSTNAMELEN];
+
+       /* SCSI host template information - for physical port */
+       struct scsi_host_template port_template;
+       /* SCSI host template information - for all vports */
+       struct scsi_host_template vport_template;
 };
 
 static inline struct Scsi_Host *
index a450477..a0ef3ba 100644 (file)
@@ -404,9 +404,7 @@ void lpfc_free_sysfs_attr(struct lpfc_vport *);
 extern struct device_attribute *lpfc_hba_attrs[];
 extern struct device_attribute *lpfc_vport_attrs[];
 extern struct scsi_host_template lpfc_template;
-extern struct scsi_host_template lpfc_template_no_hr;
 extern struct scsi_host_template lpfc_template_nvme;
-extern struct scsi_host_template lpfc_vport_template;
 extern struct fc_function_template lpfc_transport_functions;
 extern struct fc_function_template lpfc_vport_transport_functions;
 
index 6eb3112..1dadf24 100644 (file)
@@ -4231,6 +4231,7 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
 {
        struct lpfc_vport *vport;
        struct Scsi_Host  *shost = NULL;
+       struct scsi_host_template *template;
        int error = 0;
        int i;
        uint64_t wwn;
@@ -4259,22 +4260,50 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
                }
        }
 
-       if (phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP) {
-               if (dev != &phba->pcidev->dev) {
-                       shost = scsi_host_alloc(&lpfc_vport_template,
-                                               sizeof(struct lpfc_vport));
+       /* Seed template for SCSI host registration */
+       if (dev == &phba->pcidev->dev) {
+               template = &phba->port_template;
+
+               if (phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP) {
+                       /* Seed physical port template */
+                       memcpy(template, &lpfc_template, sizeof(*template));
+
+                       if (use_no_reset_hba) {
+                               /* template is for a no reset SCSI Host */
+                               template->max_sectors = 0xffff;
+                               template->eh_host_reset_handler = NULL;
+                       }
+
+                       /* Template for all vports this physical port creates */
+                       memcpy(&phba->vport_template, &lpfc_template,
+                              sizeof(*template));
+                       phba->vport_template.max_sectors = 0xffff;
+                       phba->vport_template.shost_attrs = lpfc_vport_attrs;
+                       phba->vport_template.eh_bus_reset_handler = NULL;
+                       phba->vport_template.eh_host_reset_handler = NULL;
+                       phba->vport_template.vendor_id = 0;
+
+                       /* Initialize the host templates with updated value */
+                       if (phba->sli_rev == LPFC_SLI_REV4) {
+                               template->sg_tablesize = phba->cfg_scsi_seg_cnt;
+                               phba->vport_template.sg_tablesize =
+                                       phba->cfg_scsi_seg_cnt;
+                       } else {
+                               template->sg_tablesize = phba->cfg_sg_seg_cnt;
+                               phba->vport_template.sg_tablesize =
+                                       phba->cfg_sg_seg_cnt;
+                       }
+
                } else {
-                       if (!use_no_reset_hba)
-                               shost = scsi_host_alloc(&lpfc_template,
-                                               sizeof(struct lpfc_vport));
-                       else
-                               shost = scsi_host_alloc(&lpfc_template_no_hr,
-                                               sizeof(struct lpfc_vport));
+                       /* NVMET is for physical port only */
+                       memcpy(template, &lpfc_template_nvme,
+                              sizeof(*template));
                }
-       } else if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
-               shost = scsi_host_alloc(&lpfc_template_nvme,
-                                       sizeof(struct lpfc_vport));
+       } else {
+               template = &phba->vport_template;
        }
+
+       shost = scsi_host_alloc(template, sizeof(struct lpfc_vport));
        if (!shost)
                goto out;
 
@@ -4329,6 +4358,12 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
                vport->port_type = LPFC_PHYSICAL_PORT;
        }
 
+       lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_FCP,
+                       "9081 CreatePort TMPLATE type %x TBLsize %d "
+                       "SEGcnt %d/%d\n",
+                       vport->port_type, shost->sg_tablesize,
+                       phba->cfg_scsi_seg_cnt, phba->cfg_sg_seg_cnt);
+
        /* Initialize all internally managed lists. */
        INIT_LIST_HEAD(&vport->fc_nodes);
        INIT_LIST_HEAD(&vport->rcv_buffer_list);
@@ -6301,11 +6336,6 @@ lpfc_sli_driver_resource_setup(struct lpfc_hba *phba)
         * used to create the sg_dma_buf_pool must be dynamically calculated.
         */
 
-       /* Initialize the host templates the configured values. */
-       lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt;
-       lpfc_template_no_hr.sg_tablesize = phba->cfg_sg_seg_cnt;
-       lpfc_template.sg_tablesize = phba->cfg_sg_seg_cnt;
-
        if (phba->sli_rev == LPFC_SLI_REV4)
                entry_sz = sizeof(struct sli4_sge);
        else
@@ -6346,7 +6376,7 @@ lpfc_sli_driver_resource_setup(struct lpfc_hba *phba)
        }
 
        lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_FCP,
-                       "9088 sg_tablesize:%d dmabuf_size:%d total_bde:%d\n",
+                       "9088 INIT sg_tablesize:%d dmabuf_size:%d total_bde:%d\n",
                        phba->cfg_sg_seg_cnt, phba->cfg_sg_dma_buf_size,
                        phba->cfg_total_seg_cnt);
 
@@ -6816,11 +6846,6 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
                        phba->cfg_nvme_seg_cnt = phba->cfg_sg_seg_cnt;
        }
 
-       /* Initialize the host templates with the updated values. */
-       lpfc_vport_template.sg_tablesize = phba->cfg_scsi_seg_cnt;
-       lpfc_template.sg_tablesize = phba->cfg_scsi_seg_cnt;
-       lpfc_template_no_hr.sg_tablesize = phba->cfg_scsi_seg_cnt;
-
        lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_FCP,
                        "9087 sg_seg_cnt:%d dmabuf_size:%d "
                        "total:%d scsi:%d nvme:%d\n",
index 0fc9a24..be62795 100644 (file)
@@ -6023,31 +6023,6 @@ struct scsi_host_template lpfc_template_nvme = {
        .track_queue_depth      = 0,
 };
 
-struct scsi_host_template lpfc_template_no_hr = {
-       .module                 = THIS_MODULE,
-       .name                   = LPFC_DRIVER_NAME,
-       .proc_name              = LPFC_DRIVER_NAME,
-       .info                   = lpfc_info,
-       .queuecommand           = lpfc_queuecommand,
-       .eh_timed_out           = fc_eh_timed_out,
-       .eh_abort_handler       = lpfc_abort_handler,
-       .eh_device_reset_handler = lpfc_device_reset_handler,
-       .eh_target_reset_handler = lpfc_target_reset_handler,
-       .eh_bus_reset_handler   = lpfc_bus_reset_handler,
-       .slave_alloc            = lpfc_slave_alloc,
-       .slave_configure        = lpfc_slave_configure,
-       .slave_destroy          = lpfc_slave_destroy,
-       .scan_finished          = lpfc_scan_finished,
-       .this_id                = -1,
-       .sg_tablesize           = LPFC_DEFAULT_SG_SEG_CNT,
-       .cmd_per_lun            = LPFC_CMD_PER_LUN,
-       .shost_attrs            = lpfc_hba_attrs,
-       .max_sectors            = 0xFFFFFFFF,
-       .vendor_id              = LPFC_NL_VENDOR_ID,
-       .change_queue_depth     = scsi_change_queue_depth,
-       .track_queue_depth      = 1,
-};
-
 struct scsi_host_template lpfc_template = {
        .module                 = THIS_MODULE,
        .name                   = LPFC_DRIVER_NAME,
@@ -6073,26 +6048,3 @@ struct scsi_host_template lpfc_template = {
        .change_queue_depth     = scsi_change_queue_depth,
        .track_queue_depth      = 1,
 };
-
-struct scsi_host_template lpfc_vport_template = {
-       .module                 = THIS_MODULE,
-       .name                   = LPFC_DRIVER_NAME,
-       .proc_name              = LPFC_DRIVER_NAME,
-       .info                   = lpfc_info,
-       .queuecommand           = lpfc_queuecommand,
-       .eh_timed_out           = fc_eh_timed_out,
-       .eh_abort_handler       = lpfc_abort_handler,
-       .eh_device_reset_handler = lpfc_device_reset_handler,
-       .eh_target_reset_handler = lpfc_target_reset_handler,
-       .slave_alloc            = lpfc_slave_alloc,
-       .slave_configure        = lpfc_slave_configure,
-       .slave_destroy          = lpfc_slave_destroy,
-       .scan_finished          = lpfc_scan_finished,
-       .this_id                = -1,
-       .sg_tablesize           = LPFC_DEFAULT_SG_SEG_CNT,
-       .cmd_per_lun            = LPFC_CMD_PER_LUN,
-       .shost_attrs            = lpfc_vport_attrs,
-       .max_sectors            = 0xFFFF,
-       .change_queue_depth     = scsi_change_queue_depth,
-       .track_queue_depth      = 1,
-};