[PATCH] lpfc 8.1.3: Fix performance when using multiple SLI rings
authorJamie Wellnitz <Jamie.Wellnitz@emulex.com>
Wed, 1 Mar 2006 03:33:08 +0000 (22:33 -0500)
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>
Mon, 6 Mar 2006 15:46:57 +0000 (09:46 -0600)
Fix performance when using multiple SLI rings

Currently the driver allocates all of its SLI command and response ring
entries to one primary ring. Other rings get little, or no, resources.

Allow more resources to be given to ring 1

Signed-off-by: Jamie Wellnitz <Jamie.Wellnitz@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_sli.c

index c4cca9124f458d03fbca1e5b75ca6ddf8e36b2f7..2f67a8a9259996ef55ee8be63bb5c5a20645d57f 100644 (file)
@@ -293,6 +293,7 @@ struct lpfc_hba {
        uint32_t cfg_link_speed;
        uint32_t cfg_cr_delay;
        uint32_t cfg_cr_count;
+       uint32_t cfg_multi_ring_support;
        uint32_t cfg_fdmi_on;
        uint32_t cfg_discovery_threads;
        uint32_t cfg_max_luns;
index ab49379b6abec8c8d22360cb2f6b082b6e9edebf..2558156f064df282cb63ddb0722dbd5b4e7d65ae 100644 (file)
@@ -670,6 +670,14 @@ LPFC_ATTR_RW(cr_delay, 0, 0, 63, "A count of milliseconds after which an "
 LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an "
                "interrupt response is generated");
 
+/*
+# lpfc_multi_ring_support:  Determines how many rings to spread available
+# cmd/rsp IOCB entries across.
+# Value range is [1,2]. Default value is 1.
+*/
+LPFC_ATTR_R(multi_ring_support, 1, 1, 2, "Determines number of primary "
+               "SLI rings to spread IOCB entries across");
+
 /*
 # lpfc_fdmi_on: controls FDMI support.
 #       0 = no FDMI support
@@ -726,6 +734,7 @@ struct class_device_attribute *lpfc_host_attrs[] = {
        &class_device_attr_lpfc_link_speed,
        &class_device_attr_lpfc_cr_delay,
        &class_device_attr_lpfc_cr_count,
+       &class_device_attr_lpfc_multi_ring_support,
        &class_device_attr_lpfc_fdmi_on,
        &class_device_attr_lpfc_max_luns,
        &class_device_attr_nport_evt_cnt,
@@ -1440,6 +1449,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
        lpfc_log_verbose_init(phba, lpfc_log_verbose);
        lpfc_cr_delay_init(phba, lpfc_cr_delay);
        lpfc_cr_count_init(phba, lpfc_cr_count);
+       lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support);
        lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth);
        lpfc_fcp_class_init(phba, lpfc_fcp_class);
        lpfc_use_adisc_init(phba, lpfc_use_adisc);
index d6ffe26ae123076070b0838140679d5b5fd997fb..d08fd89dd44ff64966c11c1e589a7169ed76f8a2 100644 (file)
@@ -766,7 +766,9 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
        }
        /* unSolicited Responses */
        if (pring->prt[0].profile) {
-               (pring->prt[0].lpfc_sli_rcv_unsol_event) (phba, pring, saveq);
+               if (pring->prt[0].lpfc_sli_rcv_unsol_event)
+                       (pring->prt[0].lpfc_sli_rcv_unsol_event) (phba, pring,
+                                                                       saveq);
                match = 1;
        } else {
                /* We must search, based on rctl / type
@@ -777,8 +779,9 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                             Rctl)
                            && (pring->prt[i].
                                type == Type)) {
-                               (pring->prt[i].lpfc_sli_rcv_unsol_event)
-                                       (phba, pring, saveq);
+                               if (pring->prt[i].lpfc_sli_rcv_unsol_event)
+                                       (pring->prt[i].lpfc_sli_rcv_unsol_event)
+                                                       (phba, pring, saveq);
                                match = 1;
                                break;
                        }
@@ -2377,6 +2380,37 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
        return IOCB_BUSY;
 }
 
+static int
+lpfc_extra_ring_setup( struct lpfc_hba *phba)
+{
+       struct lpfc_sli *psli;
+       struct lpfc_sli_ring *pring;
+
+       psli = &phba->sli;
+
+       /* Adjust cmd/rsp ring iocb entries more evenly */
+       pring = &psli->ring[psli->fcp_ring];
+       pring->numCiocb -= SLI2_IOCB_CMD_R1XTRA_ENTRIES;
+       pring->numRiocb -= SLI2_IOCB_RSP_R1XTRA_ENTRIES;
+       pring->numCiocb -= SLI2_IOCB_CMD_R3XTRA_ENTRIES;
+       pring->numRiocb -= SLI2_IOCB_RSP_R3XTRA_ENTRIES;
+
+       pring = &psli->ring[1];
+       pring->numCiocb += SLI2_IOCB_CMD_R1XTRA_ENTRIES;
+       pring->numRiocb += SLI2_IOCB_RSP_R1XTRA_ENTRIES;
+       pring->numCiocb += SLI2_IOCB_CMD_R3XTRA_ENTRIES;
+       pring->numRiocb += SLI2_IOCB_RSP_R3XTRA_ENTRIES;
+
+       /* Setup default profile for this ring */
+       pring->iotag_max = 4096;
+       pring->num_mask = 1;
+       pring->prt[0].profile = 0;      /* Mask 0 */
+       pring->prt[0].rctl = FC_UNSOL_DATA;
+       pring->prt[0].type = 5;
+       pring->prt[0].lpfc_sli_rcv_unsol_event = NULL;
+       return 0;
+}
+
 int
 lpfc_sli_setup(struct lpfc_hba *phba)
 {
@@ -2460,6 +2494,8 @@ lpfc_sli_setup(struct lpfc_hba *phba)
                                "SLI2 SLIM Data: x%x x%x\n",
                                phba->brd_no, totiocb, MAX_SLI2_IOCB);
        }
+       if (phba->cfg_multi_ring_support == 2)
+               lpfc_extra_ring_setup(phba);
 
        return 0;
 }