scsi: pm80xx: Increase the number of outstanding I/O supported to 1024
authorViswas G <Viswas.G@microchip.com>
Mon, 5 Oct 2020 14:50:10 +0000 (20:20 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 8 Oct 2020 03:50:04 +0000 (23:50 -0400)
The pm80xx driver currently sets the controller queue depth to
256. Hoewver, the controller supports outstanding I/Os up 1024.

Increase the number of outstanding I/Os from 256 to 1024.  CCBs and tags
are allocated according to outstanding I/Os. Also update the can_queue
value (max_out_io - PM8001_RESERVE_SLOT) used by the SCSI midlayer.

[mkp: fixed zeroday complaint]

Link: https://lore.kernel.org/r/20201005145011.23674-4-Viswas.G@microchip.com.com
Reported-by: kernel test robot <lkp@intel.com>
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
Signed-off-by: Ruksar Devadi <Ruksar.devadi@microchip.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/pm8001/pm8001_defs.h
drivers/scsi/pm8001/pm8001_hwi.c
drivers/scsi/pm8001/pm8001_init.c
drivers/scsi/pm8001/pm8001_sas.h
drivers/scsi/pm8001/pm80xx_hwi.c

index 1bf1bcfaf0104e44b3ee16f079dbf41687341384..501b574239e8b1077e1e58e9690db00c46f8de9f 100644 (file)
@@ -75,7 +75,7 @@ enum port_type {
 };
 
 /* driver compile-time configuration */
-#define        PM8001_MAX_CCB           256    /* max ccbs supported */
+#define        PM8001_MAX_CCB           1024   /* max ccbs supported */
 #define PM8001_MPI_QUEUE         1024   /* maximum mpi queue entries */
 #define        PM8001_MAX_INB_NUM       64
 #define        PM8001_MAX_OUTB_NUM      64
@@ -90,9 +90,11 @@ enum port_type {
 #define        PM8001_MAX_PORTS         16     /* max. possible ports */
 #define        PM8001_MAX_DEVICES       2048   /* max supported device */
 #define        PM8001_MAX_MSIX_VEC      64     /* max msi-x int for spcv/ve */
+#define        PM8001_RESERVE_SLOT      8
 
 #define        CONFIG_SCSI_PM8001_MAX_DMA_SG   528
 #define PM8001_MAX_DMA_SG      CONFIG_SCSI_PM8001_MAX_DMA_SG
+
 enum memory_region_num {
        AAP1 = 0x0, /* application acceleration processor */
        IOP,        /* IO processor */
index e9106575a30fa7856c06d06a67e77453f0acae13..2b7b2954ec31a1fbcd3d0daea20ecec0cd0f51c2 100644 (file)
@@ -4375,8 +4375,7 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
        /* fill in PRD (scatter/gather) table, if any */
        if (task->num_scatter > 1) {
                pm8001_chip_make_sg(task->scatter, ccb->n_elem, ccb->buf_prd);
-               phys_addr = ccb->ccb_dma_handle +
-                               offsetof(struct pm8001_ccb_info, buf_prd[0]);
+               phys_addr = ccb->ccb_dma_handle;
                ssp_cmd.addr_low = cpu_to_le32(lower_32_bits(phys_addr));
                ssp_cmd.addr_high = cpu_to_le32(upper_32_bits(phys_addr));
                ssp_cmd.esgl = cpu_to_le32(1<<31);
@@ -4449,8 +4448,7 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
        /* fill in PRD (scatter/gather) table, if any */
        if (task->num_scatter > 1) {
                pm8001_chip_make_sg(task->scatter, ccb->n_elem, ccb->buf_prd);
-               phys_addr = ccb->ccb_dma_handle +
-                               offsetof(struct pm8001_ccb_info, buf_prd[0]);
+               phys_addr = ccb->ccb_dma_handle;
                sata_cmd.addr_low = lower_32_bits(phys_addr);
                sata_cmd.addr_high = upper_32_bits(phys_addr);
                sata_cmd.esgl = cpu_to_le32(1 << 31);
index 2117a3e818fda9be4b38ae4077ea6a8d20dbcf75..3cf3e58b6979907fc6018a6e30e57c8f25ebbaf5 100644 (file)
@@ -56,6 +56,7 @@ MODULE_PARM_DESC(link_rate, "Enable link rate.\n"
                " 8: Link rate 12.0G\n");
 
 static struct scsi_transport_template *pm8001_stt;
+static int pm8001_init_ccb_tag(struct pm8001_hba_info *, struct Scsi_Host *, struct pci_dev *);
 
 /*
  * chip info structure to identify chip key functionality as
@@ -302,9 +303,6 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha,
                INIT_LIST_HEAD(&pm8001_ha->port[i].list);
        }
 
-       pm8001_ha->tags = kzalloc(PM8001_MAX_CCB, GFP_KERNEL);
-       if (!pm8001_ha->tags)
-               goto err_out;
        /* MPI Memory region 1 for AAP Event Log for fw */
        pm8001_ha->memoryMap.region[AAP1].num_elements = 1;
        pm8001_ha->memoryMap.region[AAP1].element_size = PM8001_EVENT_LOG_SIZE;
@@ -416,29 +414,11 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha,
                pm8001_ha->devices[i].device_id = PM8001_MAX_DEVICES;
                pm8001_ha->devices[i].running_req = 0;
        }
-       /* Memory region for ccb_info*/
-       pm8001_ha->ccb_info = kzalloc(PM8001_MAX_CCB
-                               * sizeof(struct pm8001_ccb_info), GFP_KERNEL);
-       if (!pm8001_ha->ccb_info) {
-               rc = -ENOMEM;
-               goto err_out_noccb;
-       }
-       for (i = 0; i < PM8001_MAX_CCB; i++) {
-               pm8001_ha->ccb_info[i].ccb_dma_handle =
-                       virt_to_phys(pm8001_ha->ccb_info) +
-                       (i * sizeof(struct pm8001_ccb_info));
-               pm8001_ha->ccb_info[i].task = NULL;
-               pm8001_ha->ccb_info[i].ccb_tag = 0xffffffff;
-               pm8001_ha->ccb_info[i].device = NULL;
-               ++pm8001_ha->tags_num;
-       }
        pm8001_ha->flags = PM8001F_INIT_TIME;
        /* Initialize tags */
        pm8001_tag_init(pm8001_ha);
        return 0;
 
-err_out_noccb:
-       kfree(pm8001_ha->devices);
 err_out_shost:
        scsi_remove_host(pm8001_ha->shost);
 err_out_nodev:
@@ -1133,6 +1113,10 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
                goto err_out_ha_free;
        }
 
+       rc = pm8001_init_ccb_tag(pm8001_ha, shost, pdev);
+       if (rc)
+               goto err_out_enable;
+
        rc = scsi_add_host(shost, &pdev->dev);
        if (rc)
                goto err_out_ha_free;
@@ -1178,6 +1162,60 @@ err_out_enable:
        return rc;
 }
 
+/*
+ * pm8001_init_ccb_tag - allocate memory to CCB and tag.
+ * @pm8001_ha: our hba card information.
+ * @shost: scsi host which has been allocated outside.
+ */
+static int
+pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha, struct Scsi_Host *shost,
+                       struct pci_dev *pdev)
+{
+       int i = 0;
+       u32 max_out_io, ccb_count;
+       u32 can_queue;
+
+       max_out_io = pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_out_io;
+       ccb_count = min_t(int, PM8001_MAX_CCB, max_out_io);
+
+       /* Update to the scsi host*/
+       can_queue = ccb_count - PM8001_RESERVE_SLOT;
+       shost->can_queue = can_queue;
+
+       pm8001_ha->tags = kzalloc(ccb_count, GFP_KERNEL);
+       if (!pm8001_ha->tags)
+               goto err_out;
+
+       /* Memory region for ccb_info*/
+       pm8001_ha->ccb_info = (struct pm8001_ccb_info *)
+               kcalloc(ccb_count, sizeof(struct pm8001_ccb_info), GFP_KERNEL);
+       if (!pm8001_ha->ccb_info) {
+               PM8001_FAIL_DBG(pm8001_ha, pm8001_printk
+                       ("Unable to allocate memory for ccb\n"));
+               goto err_out_noccb;
+       }
+       for (i = 0; i < ccb_count; i++) {
+               pm8001_ha->ccb_info[i].buf_prd = pci_alloc_consistent(pdev,
+                               sizeof(struct pm8001_prd) * PM8001_MAX_DMA_SG,
+                               &pm8001_ha->ccb_info[i].ccb_dma_handle);
+               if (!pm8001_ha->ccb_info[i].buf_prd) {
+                       PM8001_FAIL_DBG(pm8001_ha, pm8001_printk
+                                       ("pm80xx: ccb prd memory allocation error\n"));
+                       goto err_out;
+               }
+               pm8001_ha->ccb_info[i].task = NULL;
+               pm8001_ha->ccb_info[i].ccb_tag = 0xffffffff;
+               pm8001_ha->ccb_info[i].device = NULL;
+               ++pm8001_ha->tags_num;
+       }
+       return 0;
+
+err_out_noccb:
+       kfree(pm8001_ha->devices);
+err_out:
+       return -ENOMEM;
+}
+
 static void pm8001_pci_remove(struct pci_dev *pdev)
 {
        struct sas_ha_struct *sha = pci_get_drvdata(pdev);
index bdfce3c3f6190bc911c776edb9d6da8f30c84c80..9d7796a74ed4d6b5500ccd38f0b1f3c05bd320cc 100644 (file)
@@ -315,7 +315,7 @@ struct pm8001_ccb_info {
        u32                     ccb_tag;
        dma_addr_t              ccb_dma_handle;
        struct pm8001_device    *device;
-       struct pm8001_prd       buf_prd[PM8001_MAX_DMA_SG];
+       struct pm8001_prd       *buf_prd;
        struct fw_control_ex    *fw_control_context;
        u8                      open_retry;
 };
index 26e9e887710703144ed0e465074265f9cb27fae7..7593f248afb2ca77c546c1e5176f261df77e4dcb 100644 (file)
@@ -4483,8 +4483,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
                if (task->num_scatter > 1) {
                        pm8001_chip_make_sg(task->scatter,
                                                ccb->n_elem, ccb->buf_prd);
-                       phys_addr = ccb->ccb_dma_handle +
-                               offsetof(struct pm8001_ccb_info, buf_prd[0]);
+                       phys_addr = ccb->ccb_dma_handle;
                        ssp_cmd.enc_addr_low =
                                cpu_to_le32(lower_32_bits(phys_addr));
                        ssp_cmd.enc_addr_high =
@@ -4513,9 +4512,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
                                                end_addr_high, end_addr_low));
                                pm8001_chip_make_sg(task->scatter, 1,
                                        ccb->buf_prd);
-                               phys_addr = ccb->ccb_dma_handle +
-                                       offsetof(struct pm8001_ccb_info,
-                                               buf_prd[0]);
+                               phys_addr = ccb->ccb_dma_handle;
                                ssp_cmd.enc_addr_low =
                                        cpu_to_le32(lower_32_bits(phys_addr));
                                ssp_cmd.enc_addr_high =
@@ -4543,8 +4540,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
                if (task->num_scatter > 1) {
                        pm8001_chip_make_sg(task->scatter, ccb->n_elem,
                                        ccb->buf_prd);
-                       phys_addr = ccb->ccb_dma_handle +
-                               offsetof(struct pm8001_ccb_info, buf_prd[0]);
+                       phys_addr = ccb->ccb_dma_handle;
                        ssp_cmd.addr_low =
                                cpu_to_le32(lower_32_bits(phys_addr));
                        ssp_cmd.addr_high =
@@ -4572,9 +4568,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
                                                 end_addr_high, end_addr_low));
                                pm8001_chip_make_sg(task->scatter, 1,
                                        ccb->buf_prd);
-                               phys_addr = ccb->ccb_dma_handle +
-                                       offsetof(struct pm8001_ccb_info,
-                                                buf_prd[0]);
+                               phys_addr = ccb->ccb_dma_handle;
                                ssp_cmd.addr_low =
                                        cpu_to_le32(lower_32_bits(phys_addr));
                                ssp_cmd.addr_high =
@@ -4666,8 +4660,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
                if (task->num_scatter > 1) {
                        pm8001_chip_make_sg(task->scatter,
                                                ccb->n_elem, ccb->buf_prd);
-                       phys_addr = ccb->ccb_dma_handle +
-                               offsetof(struct pm8001_ccb_info, buf_prd[0]);
+                       phys_addr = ccb->ccb_dma_handle;
                        sata_cmd.enc_addr_low = lower_32_bits(phys_addr);
                        sata_cmd.enc_addr_high = upper_32_bits(phys_addr);
                        sata_cmd.enc_esgl = cpu_to_le32(1 << 31);
@@ -4692,9 +4685,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
                                                end_addr_high, end_addr_low));
                                pm8001_chip_make_sg(task->scatter, 1,
                                        ccb->buf_prd);
-                               phys_addr = ccb->ccb_dma_handle +
-                                               offsetof(struct pm8001_ccb_info,
-                                               buf_prd[0]);
+                               phys_addr = ccb->ccb_dma_handle;
                                sata_cmd.enc_addr_low =
                                        lower_32_bits(phys_addr);
                                sata_cmd.enc_addr_high =
@@ -4732,8 +4723,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
                if (task->num_scatter > 1) {
                        pm8001_chip_make_sg(task->scatter,
                                        ccb->n_elem, ccb->buf_prd);
-                       phys_addr = ccb->ccb_dma_handle +
-                               offsetof(struct pm8001_ccb_info, buf_prd[0]);
+                       phys_addr = ccb->ccb_dma_handle;
                        sata_cmd.addr_low = lower_32_bits(phys_addr);
                        sata_cmd.addr_high = upper_32_bits(phys_addr);
                        sata_cmd.esgl = cpu_to_le32(1 << 31);
@@ -4758,9 +4748,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
                                                end_addr_high, end_addr_low));
                                pm8001_chip_make_sg(task->scatter, 1,
                                        ccb->buf_prd);
-                               phys_addr = ccb->ccb_dma_handle +
-                                       offsetof(struct pm8001_ccb_info,
-                                       buf_prd[0]);
+                               phys_addr = ccb->ccb_dma_handle;
                                sata_cmd.addr_low =
                                        lower_32_bits(phys_addr);
                                sata_cmd.addr_high =