Message ID | 20200925061605.31628-4-Viswas.G@microchip.com.com |
---|---|
State | Superseded |
Headers | show |
Series | pm80xx updates | expand |
Hi Viswas, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on mkp-scsi/for-next] [also build test WARNING on scsi/for-next v5.9-rc6 next-20200924] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Viswas-G/pm80xx-updates/20200925-141508 base: https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git for-next config: xtensa-allyesconfig (attached as .config) compiler: xtensa-linux-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/417584937b14cc5369025f0d5cd9882674b8a2f8 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Viswas-G/pm80xx-updates/20200925-141508 git checkout 417584937b14cc5369025f0d5cd9882674b8a2f8 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=xtensa If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): drivers/scsi/pm8001/pm8001_init.c: In function 'pm8001_init_ccb_tag': >> drivers/scsi/pm8001/pm8001_init.c:1174:9: warning: variable 'ret' set but not used [-Wunused-but-set-variable] 1174 | int i, ret = 0; | ^~~ vim +/ret +1174 drivers/scsi/pm8001/pm8001_init.c 1164 1165 /* 1166 * pm8001_init_ccb_tag - allocate memory to CCB and tag. 1167 * @pm8001_ha: our hba card information. 1168 * @shost: scsi host which has been allocated outside. 1169 */ 1170 static int 1171 pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha, struct Scsi_Host *shost, 1172 struct pci_dev *pdev) 1173 { > 1174 int i, ret = 0; 1175 u32 max_out_io, ccb_count; 1176 u32 can_queue; 1177 1178 max_out_io = pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_out_io; 1179 ccb_count = min_t(int, PM8001_MAX_CCB, max_out_io); 1180 1181 /*Update to the scsi host*/ 1182 can_queue = ccb_count - PM8001_RESERVE_SLOT; 1183 shost->can_queue = can_queue; 1184 1185 pm8001_ha->tags = kzalloc(ccb_count, GFP_KERNEL); 1186 if (!pm8001_ha->tags) 1187 goto err_out; 1188 1189 /* Memory region for ccb_info*/ 1190 pm8001_ha->ccb_info = (struct pm8001_ccb_info *) 1191 kcalloc(ccb_count, sizeof(struct pm8001_ccb_info), GFP_KERNEL); 1192 if (!pm8001_ha->ccb_info) { 1193 ret = -ENOMEM; 1194 goto err_out_noccb; 1195 } 1196 for (i = 0; i < ccb_count; i++) { 1197 pm8001_ha->ccb_info[i].buf_prd = pci_alloc_consistent(pdev, 1198 sizeof(struct pm8001_prd) * PM8001_MAX_DMA_SG, 1199 &pm8001_ha->ccb_info[i].ccb_dma_handle); 1200 if (!pm8001_ha->ccb_info[i].buf_prd) { 1201 PM8001_FAIL_DBG(pm8001_ha, pm8001_printk 1202 (KERN_ERR "pm80xx: ccb prd memory allocation error\n")); 1203 goto err_out; 1204 } 1205 pm8001_ha->ccb_info[i].task = NULL; 1206 pm8001_ha->ccb_info[i].ccb_tag = 0xffffffff; 1207 pm8001_ha->ccb_info[i].device = NULL; 1208 ++pm8001_ha->tags_num; 1209 } 1210 return 0; 1211 1212 err_out_noccb: 1213 kfree(pm8001_ha->devices); 1214 err_out: 1215 return -ENOMEM; 1216 } 1217 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
On 25/09/2020 07:16, Viswas G wrote: > From: Viswas G<Viswas.G@microchip.com> > > Increasing the number of Outstanding IOs from 256 to 1024. > CCB and tag are allocated according to outstanding IOs. > Also updating the can_queue value (max_out_io - PM8001_RESERVE_SLOT) > to scsi midlayer. > > Signed-off-by: Viswas G<Viswas.G@microchip.com> > Signed-off-by: Ruksar Devadi<Ruksar.devadi@microchip.com> Any reason you can't also use the request->tag (instead of generating tags internally) for added performance boost? Many other LLDDs do this, as managing tags has a performance overhead. Thanks, John
On Fri, Sep 25, 2020 at 11:59 AM John Garry <john.garry@huawei.com> wrote: > > On 25/09/2020 07:16, Viswas G wrote: > > From: Viswas G<Viswas.G@microchip.com> > > > > Increasing the number of Outstanding IOs from 256 to 1024. > > CCB and tag are allocated according to outstanding IOs. > > Also updating the can_queue value (max_out_io - PM8001_RESERVE_SLOT) > > to scsi midlayer. > > > > Signed-off-by: Viswas G<Viswas.G@microchip.com> > > Signed-off-by: Ruksar Devadi<Ruksar.devadi@microchip.com> > > Any reason you can't also use the request->tag (instead of generating > tags internally) for added performance boost? Many other LLDDs do this, > as managing tags has a performance overhead. > > Thanks, > John +1, I think the reason probably is easily compatible with the older kernel. For upstream one, it makes sense to switch to request->tag. Thanks!
Thank you Jinpu and John for the review. We are yet to add this support in the driver to make use of the block layer request tag. We are planning to add that feature in our async driver first and see the performance improvements and do a full QA team validation before submitting to open source. The current patch set was created based on our async driver which has been tested by our QA team. We could see some performance boost with these changes as well. Regards, Viswas G > -----Original Message----- > From: Jinpu Wang <jinpu.wang@cloud.ionos.com> > Sent: Friday, September 25, 2020 3:42 PM > To: John Garry <john.garry@huawei.com> > Cc: Viswas G <Viswas.G@microchip.com.com>; Linux SCSI Mailinglist <linux- > scsi@vger.kernel.org>; Vasanthalakshmi Tharmarajan - I30664 > <Vasanthalakshmi.Tharmarajan@microchip.com>; Viswas G - I30667 > <Viswas.G@microchip.com>; Ruksar Devadi - I52327 > <Ruksar.devadi@microchip.com> > Subject: Re: [PATCH 3/4] pm80xx : Increase the number of outstanding IO > supported > > EXTERNAL EMAIL: Do not click links or open attachments unless you know > the content is safe > > On Fri, Sep 25, 2020 at 11:59 AM John Garry <john.garry@huawei.com> > wrote: > > > > On 25/09/2020 07:16, Viswas G wrote: > > > From: Viswas G<Viswas.G@microchip.com> > > > > > > Increasing the number of Outstanding IOs from 256 to 1024. > > > CCB and tag are allocated according to outstanding IOs. > > > Also updating the can_queue value (max_out_io - > PM8001_RESERVE_SLOT) > > > to scsi midlayer. > > > > > > Signed-off-by: Viswas G<Viswas.G@microchip.com> > > > Signed-off-by: Ruksar Devadi<Ruksar.devadi@microchip.com> > > > > Any reason you can't also use the request->tag (instead of generating > > tags internally) for added performance boost? Many other LLDDs do > > this, as managing tags has a performance overhead. > > > > Thanks, > > John > > +1, I think the reason probably is easily compatible with the older kernel. > For upstream one, it makes sense to switch to request->tag. > > Thanks!
On Fri, Sep 25, 2020 at 8:06 AM Viswas G <Viswas.G@microchip.com.com> wrote: > > From: Viswas G <Viswas.G@microchip.com> > > Increasing the number of Outstanding IOs from 256 to 1024. > CCB and tag are allocated according to outstanding IOs. > Also updating the can_queue value (max_out_io - PM8001_RESERVE_SLOT) > to scsi midlayer. > > Signed-off-by: Viswas G <Viswas.G@microchip.com> > Signed-off-by: Ruksar Devadi <Ruksar.devadi@microchip.com> As commented in other patches, please also document the reason for the change in commit message. The patch itself looks fine to me! Thank you > --- > drivers/scsi/pm8001/pm8001_defs.h | 4 +- > drivers/scsi/pm8001/pm8001_hwi.c | 6 +-- > drivers/scsi/pm8001/pm8001_init.c | 79 ++++++++++++++++++++++++++++----------- > drivers/scsi/pm8001/pm8001_sas.h | 2 +- > drivers/scsi/pm8001/pm80xx_hwi.c | 28 ++++---------- > 5 files changed, 72 insertions(+), 47 deletions(-) > > diff --git a/drivers/scsi/pm8001/pm8001_defs.h b/drivers/scsi/pm8001/pm8001_defs.h > index 1bf1bcfaf010..501b574239e8 100644 > --- a/drivers/scsi/pm8001/pm8001_defs.h > +++ b/drivers/scsi/pm8001/pm8001_defs.h > @@ -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 */ > diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c > index e9106575a30f..2b7b2954ec31 100644 > --- a/drivers/scsi/pm8001/pm8001_hwi.c > +++ b/drivers/scsi/pm8001/pm8001_hwi.c > @@ -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); > diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c > index d6789a261c1c..d04d6ecd8c0f 100644 > --- a/drivers/scsi/pm8001/pm8001_init.c > +++ b/drivers/scsi/pm8001/pm8001_init.c > @@ -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,59 @@ static int pm8001_pci_probe(struct pci_dev *pdev, > 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, ret = 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) { > + ret = -ENOMEM; > + 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 > + (KERN_ERR "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); > diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h > index bdfce3c3f619..9d7796a74ed4 100644 > --- a/drivers/scsi/pm8001/pm8001_sas.h > +++ b/drivers/scsi/pm8001/pm8001_sas.h > @@ -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; > }; > diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c > index 26e9e8877107..7593f248afb2 100644 > --- a/drivers/scsi/pm8001/pm80xx_hwi.c > +++ b/drivers/scsi/pm8001/pm80xx_hwi.c > @@ -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 = > -- > 2.16.3 >
diff --git a/drivers/scsi/pm8001/pm8001_defs.h b/drivers/scsi/pm8001/pm8001_defs.h index 1bf1bcfaf010..501b574239e8 100644 --- a/drivers/scsi/pm8001/pm8001_defs.h +++ b/drivers/scsi/pm8001/pm8001_defs.h @@ -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 */ diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index e9106575a30f..2b7b2954ec31 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -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); diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index d6789a261c1c..d04d6ecd8c0f 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -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,59 @@ static int pm8001_pci_probe(struct pci_dev *pdev, 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, ret = 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) { + ret = -ENOMEM; + 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 + (KERN_ERR "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); diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index bdfce3c3f619..9d7796a74ed4 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -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; }; diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 26e9e8877107..7593f248afb2 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -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 =