[GIT PULL] SCSI fixes for 4.10-rc7
Six fairly small fixes. None is a real show stopper, two automation detected problems: one memory leak, one use after free and four others each of which fixes something that has been a significant source of annoyance to someone. The patch is available here: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git scsi-fixes The short changelog is: Bart Van Assche (1): scsi: qla2xxx: Fix a recently introduced memory leak Dave Carroll (1): scsi: aacraid: Fix INTx/MSI-x issue with older controllers Mauricio Faria de Oliveira (1): scsi: qla2xxx: Avoid that issuing a LIP triggers a kernel crash Ram Pai (1): scsi: mpt3sas: Force request partial completion alignment Steffen Maier (1): scsi: zfcp: fix use-after-free by not tracing WKA port open/close on failed send ojab (1): scsi: mpt3sas: disable ASPM for MPI2 controllers And the diffstat: drivers/s390/scsi/zfcp_fsf.c | 8 drivers/scsi/aacraid/comminit.c | 8 ++-- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 18 ++ drivers/scsi/qla2xxx/qla_isr.c | 3 ++- drivers/scsi/qla2xxx/qla_os.c| 2 +- 5 files changed, 31 insertions(+), 8 deletions(-) With full diff below. James --- diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 75f820ca..27ff38f 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -1583,7 +1583,7 @@ static void zfcp_fsf_open_wka_port_handler(struct zfcp_fsf_req *req) int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port) { struct zfcp_qdio *qdio = wka_port->adapter->qdio; - struct zfcp_fsf_req *req = NULL; + struct zfcp_fsf_req *req; int retval = -EIO; spin_lock_irq(>req_q_lock); @@ -1612,7 +1612,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port) zfcp_fsf_req_free(req); out: spin_unlock_irq(>req_q_lock); - if (req && !IS_ERR(req)) + if (!retval) zfcp_dbf_rec_run_wka("fsowp_1", wka_port, req->req_id); return retval; } @@ -1638,7 +1638,7 @@ static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req) int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port) { struct zfcp_qdio *qdio = wka_port->adapter->qdio; - struct zfcp_fsf_req *req = NULL; + struct zfcp_fsf_req *req; int retval = -EIO; spin_lock_irq(>req_q_lock); @@ -1667,7 +1667,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port) zfcp_fsf_req_free(req); out: spin_unlock_irq(>req_q_lock); - if (req && !IS_ERR(req)) + if (!retval) zfcp_dbf_rec_run_wka("fscwp_1", wka_port, req->req_id); return retval; } diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 4f56b10..5b48bed 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c @@ -50,9 +50,13 @@ struct aac_common aac_config = { static inline int aac_is_msix_mode(struct aac_dev *dev) { - u32 status; + u32 status = 0; - status = src_readl(dev, MUnit.OMR); + if (dev->pdev->device == PMC_DEVICE_S6 || + dev->pdev->device == PMC_DEVICE_S7 || + dev->pdev->device == PMC_DEVICE_S8) { + status = src_readl(dev, MUnit.OMR); + } return (status & AAC_INT_MODE_MSIX); } diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 75f3fce..0b5b423 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -4657,6 +4658,7 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) struct MPT3SAS_DEVICE *sas_device_priv_data; u32 response_code = 0; unsigned long flags; + unsigned int sector_sz; mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply); scmd = _scsih_scsi_lookup_get_clear(ioc, smid); @@ -4715,6 +4717,20 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) } xfer_cnt = le32_to_cpu(mpi_reply->TransferCount); + + /* In case of bogus fw or device, we could end up having +* unaligned partial completion. We can force alignment here, +* then scsi-ml does not need to handle this misbehavior. +*/ + sector_sz = scmd->device->sector_size; + if (unlikely(scmd->request->cmd_type == REQ_TYPE_FS && sector_sz && +xfer_cnt % sector_sz)) { + sdev_printk(KERN_INFO, scmd->device, + "unaligned partial completion avoided (xfer_cnt=%u, sector_sz=%u)\n", + xfer_cnt, sector_sz); + xfer_cnt = round_down(xfer_cnt, sector_sz); + } + scsi_set_resid(scmd, scsi_bufflen(scmd) - xfer_cnt);
Re: [PATCH net-next v2 00/12] net: dsa: remove unnecessary phy.h include
On 02/10/2017 10:51 AM, David Miller wrote: > From: Kalle Valo> Date: Thu, 09 Feb 2017 16:10:06 +0200 > >> Florian Fainelli writes: >> > If not, for something like this it's a must: > > drivers/net/wireless/ath/wil6210/cfg80211.c:24:30: error: expected ‘)’ > before ‘bool’ > module_param(disable_ap_sme, bool, 0444); > ^ > drivers/net/wireless/ath/wil6210/cfg80211.c:25:34: error: expected ‘)’ > before string constant > MODULE_PARM_DESC(disable_ap_sme, " let user space handle AP mode SME"); > ^ > Like like that file needs linux/module.h included. Johannes already fixed a similar (or same) problem in my tree: wil6210: include moduleparam.h https://git.kernel.org/cgit/linux/kernel/git/kvalo/wireless-drivers-next.git/commit/?id=949c2d0096753d518ef6e0bd8418c8086747196b I'm planning to send you a pull request tomorrow which contains that one. >>> >>> Thanks Kalle! >>> >>> David, can you hold on this series until Kalle's pull request gets >>> submitted? Past this error, allmodconfig builds fine with this patch >>> series (just tested). Thanks! >> >> Just submitted the pull request: >> >> https://patchwork.ozlabs.org/patch/726133/ > > I've retried this patch series, and will push it out assuming the build > completes properly. I see it merged in net-next/master, thanks a lot this is going to save a lot of cycles in the future, thanks David! -- Florian
Re: [PATCH net-next v2 00/12] net: dsa: remove unnecessary phy.h include
From: Kalle ValoDate: Thu, 09 Feb 2017 16:10:06 +0200 > Florian Fainelli writes: > If not, for something like this it's a must: drivers/net/wireless/ath/wil6210/cfg80211.c:24:30: error: expected ‘)’ before ‘bool’ module_param(disable_ap_sme, bool, 0444); ^ drivers/net/wireless/ath/wil6210/cfg80211.c:25:34: error: expected ‘)’ before string constant MODULE_PARM_DESC(disable_ap_sme, " let user space handle AP mode SME"); ^ Like like that file needs linux/module.h included. >>> >>> Johannes already fixed a similar (or same) problem in my tree: >>> >>> wil6210: include moduleparam.h >>> >>> https://git.kernel.org/cgit/linux/kernel/git/kvalo/wireless-drivers-next.git/commit/?id=949c2d0096753d518ef6e0bd8418c8086747196b >>> >>> I'm planning to send you a pull request tomorrow which contains that >>> one. >> >> Thanks Kalle! >> >> David, can you hold on this series until Kalle's pull request gets >> submitted? Past this error, allmodconfig builds fine with this patch >> series (just tested). Thanks! > > Just submitted the pull request: > > https://patchwork.ozlabs.org/patch/726133/ I've retried this patch series, and will push it out assuming the build completes properly.
Re: [PATCH RFC] target/user: Add double ring buffers support.
On 02/09/2017 10:48 PM, lixi...@cmss.chinamobile.com wrote: For now the tcmu is based on UIO framework and only using the map0 with fixed ring buffer size. This will work fine mostly, but when we are using the 10GBASE NIC, the ring buffer is too small to deal with the incoming iscsi cmds. We can resolve the above issue by increasingt the ring buffer size larger, but we don't know the exactly size to all cases. This patch will add double ring buffers support by adding map1 support through UIO device. Hi Xiubo, Yes I think it's now clear we need more buffer space to avoid bottlenecks for high iops. The initial design kept it simple with the 1MB vmalloc'd space but anticipated greater would be needed. It should not be necessary to change userspace or the TCMU ABI to handle growing the buffer for fast devices: 1. increase the region mmap()ed by userspace, TCMU_RING_SIZE, from 1MB to 1GB or larger 2. Don't vmalloc() the whole thing, instead vmalloc for the cmd ring portion, and dynamically alloc pages for the data area as needed and map them into the data area. 3. Upgrade the current fixed-size bitmap-based tracking of data area to handle the new scheme 4. Implement an algorithm to keep allocated pages mapped into the data area for reuse, and maybe a heuristic to keep extreme burstiness from over-allocating pages This should allow TCMU to allocate more data area as needed, not waste memory for slower devices, and avoid userspace ABI changes. Could we prototype this approach and see if it is workable? Thanks -- Regards -- Andy
Re: [PATCH v3 19/39] megaraid_sas: MR_TargetIdToLdGet u8 to u16 and avoid invalid raid-map access
On 10.2.2017 09:59, Shivasharan S wrote: > Change MR_TargetIdToLdGet return type from u8 to u16. > > ld id range check is added at two places in this patch - > @megasas_build_ldio_fusion and @megasas_build_ld_nonrw_fusion. > Previous driver code used different data type for lds TargetId returned from > MR_TargetIdToLdGet. > Prior to this change, above two functions was safeguarded due to function > always return u8 > and maximum value of ld id returned was 255. > > In below check, fw_supported_vd_count as of today is 64 or 256 and > valid range to support is either 0-63 or 0-255. Ideally want to filter > accessing > raid map for ld ids which are not valid. With the u16 change, invalid ld id > value > is 0x and we will see kernel panic due to random memory access in > MR_LdRaidGet. > The changes will ensure we do not call MR_LdRaidGet if ld id is beyond size > of ldSpanMap array. > >if (ld < instance->fw_supported_vd_count) > > From firmware perspective,ld id 0xFF is invalid and even though current driver > code forward such command, firmware fails with target not available. > > ld target id issue occurs mainly whenever driver loops to populate raid map > (ea. MR_ValidateMapInfo). > These are the only two places where we may see out of range target ids and > wants to > protect raid map access based on range provided by Firmware API. > > Signed-off-by: Shivasharan S> Signed-off-by: Kashyap Desai Reviewed-by: Tomas Henzl Tomas
[PATCH v3 32/39] megaraid_sas: Change build_mpt_mfi_pass_thru to return void
Code refactoring to build_mpt_mfi_pass_thru to return void. Signed-off-by: Kashyap DesaiSigned-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 10 ++ 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index c0a58dc..bafaf03 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3229,7 +3229,7 @@ irqreturn_t megasas_isr_fusion(int irq, void *devp) * mfi_cmd:megasas_cmd pointer * */ -u8 +void build_mpt_mfi_pass_thru(struct megasas_instance *instance, struct megasas_cmd *mfi_cmd) { @@ -3279,8 +3279,6 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance, MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR; mpi25_ieee_chain->Length = cpu_to_le32(instance->max_chain_frame_sz); - - return 0; } /** @@ -3295,11 +3293,7 @@ build_mpt_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc = NULL; u16 index; - if (build_mpt_mfi_pass_thru(instance, cmd)) { - dev_err(>pdev->dev, "Couldn't build MFI pass thru cmd\n"); - return NULL; - } - + build_mpt_mfi_pass_thru(instance, cmd); index = cmd->context.smid; req_desc = megasas_get_request_descriptor(instance, index - 1); -- 2.8.3
RE: [PATCH v3 19/39] megaraid_sas: MR_TargetIdToLdGet u8 to u16 and avoid invalid raid-map access
> -Original Message- > From: Hannes Reinecke [mailto:h...@suse.com] > Sent: Friday, February 10, 2017 5:05 PM > To: Shivasharan S; linux-scsi@vger.kernel.org > Cc: martin.peter...@oracle.com; the...@redhat.com; > j...@linux.vnet.ibm.com; kashyap.de...@broadcom.com; > sumit.sax...@broadcom.com > Subject: Re: [PATCH v3 19/39] megaraid_sas: MR_TargetIdToLdGet u8 to u16 > and avoid invalid raid-map access > > On 02/10/2017 09:59 AM, Shivasharan S wrote: > > Change MR_TargetIdToLdGet return type from u8 to u16. > > > > ld id range check is added at two places in this patch - > > @megasas_build_ldio_fusion and @megasas_build_ld_nonrw_fusion. > > Previous driver code used different data type for lds TargetId returned from > MR_TargetIdToLdGet. > > Prior to this change, above two functions was safeguarded due to > > function always return u8 and maximum value of ld id returned was 255. > > > > In below check, fw_supported_vd_count as of today is 64 or 256 and > > valid range to support is either 0-63 or 0-255. Ideally want to > > filter accessing raid map for ld ids which are not valid. With the u16 > > change, invalid ld id value is 0x and we will see kernel panic due to random > memory access in MR_LdRaidGet. > > The changes will ensure we do not call MR_LdRaidGet if ld id is beyond size of > ldSpanMap array. > > > >if (ld < instance->fw_supported_vd_count) > > > > From firmware perspective,ld id 0xFF is invalid and even though > > current driver code forward such command, firmware fails with target not > available. > > > > ld target id issue occurs mainly whenever driver loops to populate raid map > (ea. MR_ValidateMapInfo). > > These are the only two places where we may see out of range target ids > > and wants to protect raid map access based on range provided by Firmware > API. > > > > Signed-off-by: Shivasharan S> > Signed-off-by: Kashyap Desai > > --- > > > > fix in v2 - updated description content. > > > > drivers/scsi/megaraid/megaraid_sas.h| 2 +- > > drivers/scsi/megaraid/megaraid_sas_fp.c | 5 +++-- > > drivers/scsi/megaraid/megaraid_sas_fusion.c | 25 > > ++--- > > 3 files changed, 18 insertions(+), 14 deletions(-) > > > > diff --git a/drivers/scsi/megaraid/megaraid_sas.h > > b/drivers/scsi/megaraid/megaraid_sas.h > > index 0a20fff..efc01a3 100644 > > --- a/drivers/scsi/megaraid/megaraid_sas.h > > +++ b/drivers/scsi/megaraid/megaraid_sas.h > > @@ -2448,7 +2448,7 @@ MR_BuildRaidContext(struct megasas_instance > *instance, > > struct IO_REQUEST_INFO *io_info, > > struct RAID_CONTEXT *pRAID_Context, > > struct MR_DRV_RAID_MAP_ALL *map, u8 **raidLUN); > > -u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map); > > +u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL > *map); > > struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_DRV_RAID_MAP_ALL > > *map); > > u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_DRV_RAID_MAP_ALL *map); > > u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_DRV_RAID_MAP_ALL > > *map); diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c > > b/drivers/scsi/megaraid/megaraid_sas_fp.c > > index a0b0e68..9d5d485 100644 > > --- a/drivers/scsi/megaraid/megaraid_sas_fp.c > > +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c > > @@ -165,7 +165,7 @@ u16 MR_GetLDTgtId(u32 ld, struct > MR_DRV_RAID_MAP_ALL *map) > > return le16_to_cpu(map->raidMap.ldSpanMap[ld].ldRaid.targetId); > > } > > > > -u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map) > > +u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL > *map) > > { > > return map->raidMap.ldTgtIdToLd[ldTgtId]; > > } > > @@ -1151,7 +1151,7 @@ MR_BuildRaidContext(struct megasas_instance > > *instance, { > > struct fusion_context *fusion; > > struct MR_LD_RAID *raid; > > - u32 ld, stripSize, stripe_mask; > > + u32 stripSize, stripe_mask; > > u64 endLba, endStrip, endRow, start_row, start_strip; > > u64 regStart; > > u32 regSize; > > @@ -1163,6 +1163,7 @@ MR_BuildRaidContext(struct megasas_instance > *instance, > > u8 retval = 0; > > u8 startlba_span = SPAN_INVALID; > > u64 *pdBlock = _info->pdBlock; > > + u16 ld; > > > > ldStartBlock = io_info->ldStartBlock; > > numBlocks = io_info->numBlocks; > > diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c > > b/drivers/scsi/megaraid/megaraid_sas_fusion.c > > index 9019b82..4aaf307 100644 > > --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c > > +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c > > @@ -1121,7 +1121,8 @@ megasas_sync_map_info(struct megasas_instance > *instance) > > int i; > > struct megasas_cmd *cmd; > > struct megasas_dcmd_frame *dcmd; > > - u32 size_sync_info, num_lds; > > + u16 num_lds; > > + u32 size_sync_info;
[PATCH v3 25/39] megaraid_sas: Change max_cmd from u32 to u16 in all functions
Since maximum supported FW commands are all defined as u16, change all local variables referring to max_cmd from u32 to u16. Signed-off-by: Kashyap DesaiSigned-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_base.c | 10 +- drivers/scsi/megaraid/megaraid_sas_fusion.c | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index cd9d223..06001b4 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1549,7 +1549,7 @@ megasas_dump_pending_frames(struct megasas_instance *instance) struct megasas_io_frame *ldio; struct megasas_pthru_frame *pthru; u32 sgcount; - u32 max_cmd = instance->max_fw_cmds; + u16 max_cmd = instance->max_fw_cmds; dev_err(>pdev->dev, "[%d]: Dumping Frame Phys Address of all pending cmds in FW\n",instance->host->host_no); dev_err(>pdev->dev, "[%d]: Total OS Pending cmds : %d\n",instance->host->host_no,atomic_read(>fw_outstanding)); @@ -3467,7 +3467,7 @@ megasas_internal_reset_defer_cmds(struct megasas_instance *instance) { struct megasas_cmd *cmd; int i; - u32 max_cmd = instance->max_fw_cmds; + u16 max_cmd = instance->max_fw_cmds; u32 defer_index; unsigned long flags; @@ -3843,7 +3843,7 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr) static void megasas_teardown_frame_pool(struct megasas_instance *instance) { int i; - u32 max_cmd = instance->max_mfi_cmds; + u16 max_cmd = instance->max_mfi_cmds; struct megasas_cmd *cmd; if (!instance->frame_dma_pool) @@ -3887,7 +3887,7 @@ static void megasas_teardown_frame_pool(struct megasas_instance *instance) static int megasas_create_frame_pool(struct megasas_instance *instance) { int i; - u32 max_cmd; + u16 max_cmd; u32 sge_sz; u32 total_sz; u32 frame_count; @@ -4021,7 +4021,7 @@ int megasas_alloc_cmds(struct megasas_instance *instance) { int i; int j; - u32 max_cmd; + u16 max_cmd; struct megasas_cmd *cmd; struct fusion_context *fusion; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index baea4c2..2d6d979 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -367,7 +367,7 @@ megasas_free_cmds_fusion(struct megasas_instance *instance) static int megasas_create_sg_sense_fusion(struct megasas_instance *instance) { int i; - u32 max_cmd; + u16 max_cmd; struct fusion_context *fusion; struct megasas_cmd_fusion *cmd; @@ -1274,7 +1274,8 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) { struct megasas_register_set __iomem *reg_set; struct fusion_context *fusion; - u32 max_cmd, scratch_pad_2; + u16 max_cmd; + u32 scratch_pad_2; int i = 0, count; fusion = instance->ctrl_context; -- 2.8.3
Re: [PATCH v3 19/39] megaraid_sas: MR_TargetIdToLdGet u8 to u16 and avoid invalid raid-map access
On 02/10/2017 09:59 AM, Shivasharan S wrote: > Change MR_TargetIdToLdGet return type from u8 to u16. > > ld id range check is added at two places in this patch - > @megasas_build_ldio_fusion and @megasas_build_ld_nonrw_fusion. > Previous driver code used different data type for lds TargetId returned from > MR_TargetIdToLdGet. > Prior to this change, above two functions was safeguarded due to function > always return u8 > and maximum value of ld id returned was 255. > > In below check, fw_supported_vd_count as of today is 64 or 256 and > valid range to support is either 0-63 or 0-255. Ideally want to filter > accessing > raid map for ld ids which are not valid. With the u16 change, invalid ld id > value > is 0x and we will see kernel panic due to random memory access in > MR_LdRaidGet. > The changes will ensure we do not call MR_LdRaidGet if ld id is beyond size > of ldSpanMap array. > >if (ld < instance->fw_supported_vd_count) > > From firmware perspective,ld id 0xFF is invalid and even though current driver > code forward such command, firmware fails with target not available. > > ld target id issue occurs mainly whenever driver loops to populate raid map > (ea. MR_ValidateMapInfo). > These are the only two places where we may see out of range target ids and > wants to > protect raid map access based on range provided by Firmware API. > > Signed-off-by: Shivasharan S> Signed-off-by: Kashyap Desai > --- > > fix in v2 - updated description content. > > drivers/scsi/megaraid/megaraid_sas.h| 2 +- > drivers/scsi/megaraid/megaraid_sas_fp.c | 5 +++-- > drivers/scsi/megaraid/megaraid_sas_fusion.c | 25 ++--- > 3 files changed, 18 insertions(+), 14 deletions(-) > > diff --git a/drivers/scsi/megaraid/megaraid_sas.h > b/drivers/scsi/megaraid/megaraid_sas.h > index 0a20fff..efc01a3 100644 > --- a/drivers/scsi/megaraid/megaraid_sas.h > +++ b/drivers/scsi/megaraid/megaraid_sas.h > @@ -2448,7 +2448,7 @@ MR_BuildRaidContext(struct megasas_instance *instance, > struct IO_REQUEST_INFO *io_info, > struct RAID_CONTEXT *pRAID_Context, > struct MR_DRV_RAID_MAP_ALL *map, u8 **raidLUN); > -u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map); > +u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map); > struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_DRV_RAID_MAP_ALL *map); > u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_DRV_RAID_MAP_ALL *map); > u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_DRV_RAID_MAP_ALL *map); > diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c > b/drivers/scsi/megaraid/megaraid_sas_fp.c > index a0b0e68..9d5d485 100644 > --- a/drivers/scsi/megaraid/megaraid_sas_fp.c > +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c > @@ -165,7 +165,7 @@ u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map) > return le16_to_cpu(map->raidMap.ldSpanMap[ld].ldRaid.targetId); > } > > -u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map) > +u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map) > { > return map->raidMap.ldTgtIdToLd[ldTgtId]; > } > @@ -1151,7 +1151,7 @@ MR_BuildRaidContext(struct megasas_instance *instance, > { > struct fusion_context *fusion; > struct MR_LD_RAID *raid; > - u32 ld, stripSize, stripe_mask; > + u32 stripSize, stripe_mask; > u64 endLba, endStrip, endRow, start_row, start_strip; > u64 regStart; > u32 regSize; > @@ -1163,6 +1163,7 @@ MR_BuildRaidContext(struct megasas_instance *instance, > u8 retval = 0; > u8 startlba_span = SPAN_INVALID; > u64 *pdBlock = _info->pdBlock; > + u16 ld; > > ldStartBlock = io_info->ldStartBlock; > numBlocks = io_info->numBlocks; > diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c > b/drivers/scsi/megaraid/megaraid_sas_fusion.c > index 9019b82..4aaf307 100644 > --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c > +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c > @@ -1121,7 +1121,8 @@ megasas_sync_map_info(struct megasas_instance *instance) > int i; > struct megasas_cmd *cmd; > struct megasas_dcmd_frame *dcmd; > - u32 size_sync_info, num_lds; > + u16 num_lds; > + u32 size_sync_info; > struct fusion_context *fusion; > struct MR_LD_TARGET_SYNC *ci = NULL; > struct MR_DRV_RAID_MAP_ALL *map; > @@ -1870,7 +1871,7 @@ megasas_set_pd_lba(struct MPI2_RAID_SCSI_IO_REQUEST > *io_request, u8 cdb_len, > struct MR_DRV_RAID_MAP_ALL *local_map_ptr, u32 ref_tag) > { > struct MR_LD_RAID *raid; > - u32 ld; > + u16 ld; > u64 start_blk = io_info->pdBlock; > u8 *cdb = io_request->CDB.CDB32; > u32 num_blocks = io_info->numBlocks; > @@ -2303,10 +2304,11 @@
Re: aacraid: kernel: AAC: Host adapter dead -1 (bisected)
Cc: linux-scsi@vger.kernel.org 2017-02-10 13:24 GMT+03:00 Greg Kroah-Hartman: > On Fri, Feb 10, 2017 at 02:25:26AM +0300, Andrey Jr. Melnikov wrote: >> In article <201701151205.37563.a.miskiew...@gmail.com> you wrote: >> > Newsgroups: gmane.linux.kernel >> >> >> > Hi. >> >> > There is a bug with handling of adaptec raid cards (in my case it is >> > Adaptec >> > 3405) where kernel logs hundreds of "AAC: Host adapter dead -1" messages. >> >> > Bug was reported previously on lkml but there was no progres in solving it. >> >> > There is also bugzilla entry: >> > https://bugzilla.kernel.org/show_bug.cgi?id=151661 >> >> > I've bisected that to commit bellow and indeed, reverting it from kernel >> > 4.9.3 >> > makes messages go away. >> >> >> Don't try to switch Adaptec 3405/3805 RAID cards to MSI-X interrupt mode. >> Fix https://bugzilla.kernel.org/show_bug.cgi?id=151661 >> >> Signed-off-by: Andrey Jr. Melnikov >> >> --- >> >> diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h >> index 969c312de1be..2ad8403dea40 100644 >> --- a/drivers/scsi/aacraid/aacraid.h >> +++ b/drivers/scsi/aacraid/aacraid.h > > > > Why are you sending this to me and not the scsi developers who can > actually do something with this patch? Bug in bugzilla open half year ago, microsemi maintainer slowly read his fine docs about his hardware, broken driver fills our log with useless messages every 10 seconds. So, make decision - apply this patch to stable 4.9.x/4.4.x tree or revert commit 78cbccd3bd683c295a44af8050797dc4a41376ff from it.
[PATCH v3 38/39] megaraid_sas: Change RAID_1_10_RMW_CMDS to RAID_1_PEER_CMDS and set value to 2
For RAID1 FastPath writes, driver needs to allocate extra commands internally to accommodate for the extra peer command being sent. Currently driver is allocating 2 extra commands for each but only one extra command is necessary. Set RAID_1_10_RMW_CMDS to 2 and also change macro name to RAID_1_PEER_CMDS. Signed-off-by: Kashyap DesaiSigned-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +- drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 9928766..7500901 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -293,7 +293,7 @@ megasas_fusion_update_can_queue(struct megasas_instance *instance, int fw_boot_c if (instance->is_ventura) instance->max_mpt_cmds = - instance->max_fw_cmds * RAID_1_10_RMW_CMDS; + instance->max_fw_cmds * RAID_1_PEER_CMDS; else instance->max_mpt_cmds = instance->max_fw_cmds; } diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h index 8e8c35f..d78d7611 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.h +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h @@ -101,7 +101,7 @@ enum MR_RAID_FLAGS_IO_SUB_TYPE { #define MEGASAS_FP_CMD_LEN 16 #define MEGASAS_FUSION_IN_RESET 0 #define THRESHOLD_REPLY_COUNT 50 -#define RAID_1_10_RMW_CMDS 3 +#define RAID_1_PEER_CMDS 2 #define JBOD_MAPS_COUNT2 enum MR_FUSION_ADAPTER_TYPE { -- 2.8.3
[PATCH v3 08/39] megaraid_sas: megasas_get_request_descriptor always return valid desc
No functional change. Code clean up. Removing error code which is not valid scenario. In megasas_get_request_descriptor we can remove the error handling which is not required. With fusion controllers, if there is a valid message frame available, we are guaranteed to get a corresponding request descriptor. Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- Changes in v2 - split patches into two. discussed below http://marc.info/?l=linux-scsi=148638999110404=2 drivers/scsi/megaraid/megaraid_sas_fusion.c | 24 ++-- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 6ec7a18..b6c5dc5 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -2438,18 +2438,12 @@ megasas_build_io_fusion(struct megasas_instance *instance, return 0; } -union MEGASAS_REQUEST_DESCRIPTOR_UNION * +static union MEGASAS_REQUEST_DESCRIPTOR_UNION * megasas_get_request_descriptor(struct megasas_instance *instance, u16 index) { u8 *p; struct fusion_context *fusion; - if (index >= instance->max_mpt_cmds) { - dev_err(>pdev->dev, "Invalid SMID (0x%x)request for " - "descriptor for scsi%d\n", index, - instance->host->host_no); - return NULL; - } fusion = instance->ctrl_context; p = fusion->req_frames_desc + sizeof(union MEGASAS_REQUEST_DESCRIPTOR_UNION) * index; @@ -2960,7 +2954,7 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance, union MEGASAS_REQUEST_DESCRIPTOR_UNION * build_mpt_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) { - union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; + union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc = NULL; u16 index; if (build_mpt_mfi_pass_thru(instance, cmd)) { @@ -2972,9 +2966,6 @@ build_mpt_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) req_desc = megasas_get_request_descriptor(instance, index - 1); - if (!req_desc) - return NULL; - req_desc->Words = 0; req_desc->SCSIIO.RequestFlags = (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); @@ -2997,11 +2988,6 @@ megasas_issue_dcmd_fusion(struct megasas_instance *instance, union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; req_desc = build_mpt_cmd(instance, cmd); - if (!req_desc) { - dev_info(>pdev->dev, "Failed from %s %d\n", - __func__, __LINE__); - return DCMD_NOT_FIRED; - } megasas_fire_cmd_fusion(instance, req_desc); return DCMD_SUCCESS; @@ -3438,12 +3424,6 @@ megasas_issue_tm(struct megasas_instance *instance, u16 device_handle, req_desc = megasas_get_request_descriptor(instance, (cmd_fusion->index - 1)); - if (!req_desc) { - dev_err(>pdev->dev, "Failed from %s %d\n", - __func__, __LINE__); - megasas_return_cmd(instance, cmd_mfi); - return -ENOMEM; - } cmd_fusion->request_desc = req_desc; req_desc->Words = 0; -- 2.8.3
Re: aacraid: kernel: AAC: Host adapter dead -1 (bisected)
On Fri, Feb 10, 2017 at 01:45:06PM +0300, Andrey Melnikov wrote: > Cc: linux-scsi@vger.kernel.org > > 2017-02-10 13:24 GMT+03:00 Greg Kroah-Hartman: > > On Fri, Feb 10, 2017 at 02:25:26AM +0300, Andrey Jr. Melnikov wrote: > >> In article <201701151205.37563.a.miskiew...@gmail.com> you wrote: > >> > Newsgroups: gmane.linux.kernel > >> > >> > >> > Hi. > >> > >> > There is a bug with handling of adaptec raid cards (in my case it is > >> > Adaptec > >> > 3405) where kernel logs hundreds of "AAC: Host adapter dead -1" messages. > >> > >> > Bug was reported previously on lkml but there was no progres in solving > >> > it. > >> > >> > There is also bugzilla entry: > >> > https://bugzilla.kernel.org/show_bug.cgi?id=151661 > >> > >> > I've bisected that to commit bellow and indeed, reverting it from kernel > >> > 4.9.3 > >> > makes messages go away. > >> > >> > >> Don't try to switch Adaptec 3405/3805 RAID cards to MSI-X interrupt mode. > >> Fix https://bugzilla.kernel.org/show_bug.cgi?id=151661 > >> > >> Signed-off-by: Andrey Jr. Melnikov > >> > >> --- > >> > >> diff --git a/drivers/scsi/aacraid/aacraid.h > >> b/drivers/scsi/aacraid/aacraid.h > >> index 969c312de1be..2ad8403dea40 100644 > >> --- a/drivers/scsi/aacraid/aacraid.h > >> +++ b/drivers/scsi/aacraid/aacraid.h > > > > > > > > Why are you sending this to me and not the scsi developers who can > > actually do something with this patch? > > Bug in bugzilla open half year ago, microsemi maintainer slowly read > his fine docs about his hardware, broken driver fills our log with > useless messages every 10 seconds. > So, make decision - apply this patch to stable 4.9.x/4.4.x tree or > revert commit 78cbccd3bd683c295a44af8050797dc4a41376ff from it. I don't understand, that's not how the stable kernels work, please read Documentation/stable_kernel_rules.txt for how the process works. Please get a patch accepted into Linus's tree and then we will be glad to apply it to the stable kernel trees. thanks, greg k-h
[PATCH v3 24/39] megaraid_sas: set pd_after_lb from MR_BuildRaidContext and initialize pDevHandle to MR_DEVHANDLE_INVALID
Issue is limited for Syncro firmware where pd_after_lb is not set but is accidentally used. Not a functional issue, but results in low performance due to improper load balancing between two LUNs. Signed-off-by: Kashyap DesaiSigned-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fp.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index 68582d9..a5517e7 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -948,6 +948,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, struct fusion_context *fusion; fusion = instance->ctrl_context; + *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID); /*Get row and span from io_info for Uneven Span IO.*/ row = io_info->start_row; @@ -986,7 +987,6 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, MR_PdDevHandleGet(r1_alt_pd, map); } } else { - *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID); if ((raid->level >= 5) && ((fusion->adapter_type == THUNDERBOLT_SERIES) || ((fusion->adapter_type == INVADER_SERIES) && @@ -1013,6 +1013,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; io_info->span_arm = pRAID_Context->span_arm; } + io_info->pd_after_lb = pd; return retval; } @@ -1049,7 +1050,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, struct fusion_context *fusion; fusion = instance->ctrl_context; - + *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID); row = mega_div64_32(stripRow, raid->rowDataSize); @@ -1102,8 +1103,6 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, MR_PdDevHandleGet(r1_alt_pd, map); } } else { - /* set dev handle as invalid. */ - *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID); if ((raid->level >= 5) && ((fusion->adapter_type == THUNDERBOLT_SERIES) || ((fusion->adapter_type == INVADER_SERIES) && @@ -1132,6 +1131,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; io_info->span_arm = pRAID_Context->span_arm; } + io_info->pd_after_lb = pd; return retval; } -- 2.8.3
[PATCH v3 15/39] megaraid_sas: enhance debug logs in OCR context
Add additional logging from driver in OCR context. Add debug logs for partial completion of IOs is iodone context. Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 3 +++ drivers/scsi/megaraid/megaraid_sas_base.c | 38 ++--- drivers/scsi/megaraid/megaraid_sas_fusion.c | 35 +- 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index bed8a37..93da6dc 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1405,6 +1405,9 @@ struct megasas_ctrl_info { #define VD_EXT_DEBUG 0 +/* Driver's internal Logging levels*/ +#define OCR_LOGS(1 << 0) + #define SCAN_PD_CHANNEL0x1 #define SCAN_VD_CHANNEL0x2 diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 51b35a6..b41bbea 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -2742,6 +2742,24 @@ blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd) } /** + * megasas_dump_frame -This function will dump MPT/MFI frame + */ +static inline void +megasas_dump_frame(void *mpi_request, int sz) +{ + int i; + __le32 *mfp = (__le32 *)mpi_request; + + printk(KERN_INFO "IO request frame:\n\t"); + for (i = 0; i < sz; i++) { + if (i && ((i % 8) == 0)) + printk("\n\t"); + printk("%08x ", le32_to_cpu(mfp[i])); + } + printk("\n"); +} + +/** * megasas_reset_bus_host -Bus & host reset handler entry point */ static int megasas_reset_bus_host(struct scsi_cmnd *scmd) @@ -2751,12 +2769,26 @@ 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, + atomic_read((atomic_t *)>device->host->host_busy), + atomic_read(>fw_outstanding)); + /* * First wait for all commands to complete */ - if (instance->ctrl_context) - ret = megasas_reset_fusion(scmd->device->host, 1); - else + if (instance->ctrl_context) { + struct megasas_cmd_fusion *cmd; + cmd = (struct megasas_cmd_fusion *)scmd->SCp.ptr; + if (cmd) + megasas_dump_frame(cmd->io_request, + sizeof(struct MPI2_RAID_SCSI_IO_REQUEST)); + ret = megasas_reset_fusion(scmd->device->host, + SCSIIO_TIMEOUT_OCR); + } else ret = megasas_generic_reset(scmd); return ret; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 4628671..1252a3c 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1445,8 +1445,10 @@ map_cmd_status(struct fusion_context *fusion, struct scsi_cmnd *scmd, u8 status, u8 ext_status, u32 data_length, u8 *sense) { + u8 cmd_type; int resid; + cmd_type = megasas_cmd_type(scmd); switch (status) { case MFI_STAT_OK: @@ -1477,6 +1479,13 @@ map_cmd_status(struct fusion_context *fusion, */ resid = (scsi_bufflen(scmd) - data_length); scsi_set_resid(scmd, resid); + + if (resid && + ((cmd_type == READ_WRITE_LDIO) || + (cmd_type == READ_WRITE_SYSPDIO))) + scmd_printk(KERN_INFO, scmd, "BRCM Debug mfi stat 0x%x, data len" + " requested/completed 0x%x/0x%x\n", + status, scsi_bufflen(scmd), data_length); break; case MFI_STAT_LD_OFFLINE: @@ -3477,6 +3486,14 @@ int megasas_wait_for_outstanding_fusion(struct megasas_instance *instance, " will reset adapter scsi%d.\n", instance->host->host_no); megasas_complete_cmd_dpc_fusion((unsigned long)instance); + if (instance->requestorId && reason) { + dev_warn(>pdev->dev, "SR-IOV Found FW in FAULT" + " state while polling during" + " I/O timeout handling for %d\n",
[PATCH v3 34/39] megaraid_sas: Use synchronize_irq to wait for IRQs to complete
FIX - Do not use random delay to synchronize with IRQ. Use kernel API. Signed-off-by: Kashyap DesaiSigned-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 20 ++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index bafaf03..d8bfb87 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3145,6 +3145,22 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) } /** + * megasas_sync_irqs - Synchronizes all IRQs owned by adapter + * @instance: Adapter soft state + */ +void megasas_sync_irqs(unsigned long instance_addr) +{ + u32 count, i; + struct megasas_instance *instance = + (struct megasas_instance *)instance_addr; + + count = instance->msix_vectors > 0 ? instance->msix_vectors : 1; + + for (i = 0; i < count; i++) + synchronize_irq(pci_irq_vector(instance->pdev, i)); +} + +/** * megasas_complete_cmd_dpc_fusion - Completes command * @instance: Adapter soft state * @@ -3820,7 +3836,7 @@ megasas_issue_tm(struct megasas_instance *instance, u16 device_handle, break; else { instance->instancet->disable_intr(instance); - msleep(1000); + megasas_sync_irqs((unsigned long)instance); megasas_complete_cmd_dpc_fusion ((unsigned long)instance); instance->instancet->enable_intr(instance); @@ -4174,7 +4190,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason) set_bit(MEGASAS_FUSION_IN_RESET, >reset_flags); atomic_set(>adprecovery, MEGASAS_ADPRESET_SM_POLLING); instance->instancet->disable_intr(instance); - msleep(1000); + megasas_sync_irqs((unsigned long)instance); /* First try waiting for commands to complete */ if (megasas_wait_for_outstanding_fusion(instance, reason, -- 2.8.3
[PATCH v3 00/39] megaraid_sas: Updates for scsi-next
Changes in v3: Patch 21: Fix to pass rctx_g35 pointer to set/get_num_sge() Move all v2 changelog descriptions beyond actual commit message body Changes in v2: Patch 3: Fix to update status and ex_status from failed r1_cmd Patch 8: Split into two separate patches, 1. megasas_get_request_descriptor will always return valid request descriptor 2. With above changes, issue_dcmd always return DCMD_SUCCESS. Change return type to void and update all callers. Patch 11: Update commit description, remove reference to dependent patch. Patch 12: Update with correct commit description Patch 14: Fix typo in commit description Patch 19: Correction to commit description Drop patch 33 of last patch series which added call for flush_scheduled_work Shivasharan S (39): Revert "scsi: megaraid_sas: Enable or Disable Fast path based on the PCI Threshold Bandwidth" megaraid_sas: cpu select rework. megaraid_sas: raid 1 fast path code optimize megaraid_sas: 32 bit descriptor fire cmd optimization megaraid_sas: Refactor MEGASAS_IS_LOGICAL macro using sdev megaraid_sas: RAID map is accessed for SYS PDs when use_seqnum_jbod_fp is not set megaraid_sas: Use DID_REQUEUE megaraid_sas: megasas_get_request_descriptor always return valid desc megaraid_sas: change issue_dcmd to return void from int megaraid_sas: NVME Interface detection and prop settings megaraid_sas: NVME interface target prop added megaraid_sas: NVME fast path io support megaraid_sas: raid 1 write performance for large io megaraid_sas: set residual bytes count during IO completion megaraid_sas: enhance debug logs in OCR context megaraid_sas: add print in device removal path megaraid_sas: reduce size of fusion_context and use vmalloc if kmalloc fails megaraid_sas: In validate raid map, raid capability is not converted to cpu format for all lds megaraid_sas: MR_TargetIdToLdGet u8 to u16 and avoid invalid raid-map access megaraid_sas: Big endian RDPQ mode fix megaraid_sas: big endian support changes megaraid_sas: avoid unaligned access in ioctl path megaraid_sas: latest controller OCR capability from FW before sending shutdown DCMD megaraid_sas: set pd_after_lb from MR_BuildRaidContext and initialize pDevHandle to MR_DEVHANDLE_INVALID megaraid_sas: Change max_cmd from u32 to u16 in all functions megaraid_sas: update can_queue only if the new value is less megaraid_sas: max_fw_cmds are decremented twice, remove duplicate megaraid_sas: megasas_return_cmd does not memset IO frame to zero megaraid_sas: Remove unused pd_index from megasas_build_ld_nonrw_fusion megaraid_sas: Do not set fp_possible if TM capable for non-RW syspdIO, change fp_possible to bool megaraid_sas: During OCR, if get_ctrl_info fails do not continue with OCR megaraid_sas: Change build_mpt_mfi_pass_thru to return void megaraid_sas: Bail out the driver load if ld_list_query fails megaraid_sas: Use synchronize_irq to wait for IRQs to complete megaraid_sas: Increase internal command pool megaraid_sas: Cleanup VD_EXT_DEBUG and SPAN_DEBUG related debug prints megaraid_sas: Indentation and smatch warning fixes megaraid_sas: Change RAID_1_10_RMW_CMDS to RAID_1_PEER_CMDS and set value to 2 megaraid_sas: driver version upgrade drivers/scsi/megaraid/megaraid_sas.h| 82 +- drivers/scsi/megaraid/megaraid_sas_base.c | 548 +++ drivers/scsi/megaraid/megaraid_sas_fp.c | 427 ++--- drivers/scsi/megaraid/megaraid_sas_fusion.c | 1352 --- drivers/scsi/megaraid/megaraid_sas_fusion.h | 144 ++- 5 files changed, 1434 insertions(+), 1119 deletions(-) -- 2.8.3
[PATCH v3 11/39] megaraid_sas: NVME interface target prop added
This patch fetch true values of NVME property from FW using New DCMD interface MR_DCMD_DEV_GET_TARGET_PROP Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 14 +++ drivers/scsi/megaraid/megaraid_sas_base.c | 144 +++- drivers/scsi/megaraid/megaraid_sas_fusion.h | 1 + 3 files changed, 155 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index f9efddf..a45ff10 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -695,6 +695,18 @@ struct MR_PD_INFO { u8 reserved1[512-428]; } __packed; +/* + * Definition of structure used to expose attributes of VD or JBOD + * (this structure is to be filled by firmware when MR_DCMD_DRV_GET_TARGET_PROP + * is fired by driver) + */ +struct MR_TARGET_PROPERTIES { + u32max_io_size_kb; + u32device_qdepth; + u32sector_size; + u8 reserved[500]; +} __packed; + /* * defines the physical drive address structure */ @@ -2090,6 +2102,8 @@ struct megasas_instance { dma_addr_t hb_host_mem_h; struct MR_PD_INFO *pd_info; dma_addr_t pd_info_h; + struct MR_TARGET_PROPERTIES *tgt_prop; + dma_addr_t tgt_prop_h; __le32 *reply_queue; dma_addr_t reply_queue_h; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index f383bf2..51b35a6 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -118,6 +118,8 @@ static int megasas_register_aen(struct megasas_instance *instance, u32 seq_num, u32 class_locale_word); static void megasas_get_pd_info(struct megasas_instance *instance, struct scsi_device *sdev); +static int megasas_get_target_prop(struct megasas_instance *instance, + struct scsi_device *sdev); /* * PCI ID table for all supported controllers */ @@ -1834,14 +1836,16 @@ megasas_set_nvme_device_properties(struct scsi_device *sdev, u32 max_io_size) * set nvme device properties. see - megasas_set_nvme_device_properties * * @sdev: scsi device - * + * @is_target_prop true, if fw provided target properties. */ -static void megasas_set_static_target_properties(struct scsi_device *sdev) +static void megasas_set_static_target_properties(struct scsi_device *sdev, +bool is_target_prop) { u16 target_index = 0; u8 interface_type; u32 device_qd = MEGASAS_DEFAULT_CMD_PER_LUN; u32 max_io_size_kb = MR_DEFAULT_NVME_MDTS_KB; + u32 tgt_device_qd; struct megasas_instance *instance; struct MR_PRIV_DEVICE *mr_device_priv_data; @@ -1868,6 +1872,18 @@ static void megasas_set_static_target_properties(struct scsi_device *sdev) break; } + if (is_target_prop) { + tgt_device_qd = le32_to_cpu(instance->tgt_prop->device_qdepth); + if (tgt_device_qd && + (tgt_device_qd <= instance->host->can_queue)) + device_qd = tgt_device_qd; + + /* max_io_size_kb will be set to non zero for +* nvme based vd and syspd. +*/ + max_io_size_kb = le32_to_cpu(instance->tgt_prop->max_io_size_kb); + } + if (instance->nvme_page_size && max_io_size_kb) megasas_set_nvme_device_properties(sdev, (max_io_size_kb << 10)); @@ -1880,6 +1896,8 @@ static int megasas_slave_configure(struct scsi_device *sdev) { u16 pd_index = 0; struct megasas_instance *instance; + int ret_target_prop = DCMD_FAILED; + bool is_target_prop = false; instance = megasas_lookup_instance(sdev->host->host_no); if (instance->pd_list_not_supported) { @@ -1897,7 +1915,14 @@ static int megasas_slave_configure(struct scsi_device *sdev) if ((instance->pd_info) && !MEGASAS_IS_LOGICAL(sdev)) megasas_get_pd_info(instance, sdev); - megasas_set_static_target_properties(sdev); + /* Some ventura firmware may not have instance->nvme_page_size set. +* Do not send MR_DCMD_DRV_GET_TARGET_PROP +*/ + if ((instance->tgt_prop) && (instance->nvme_page_size)) + ret_target_prop = megasas_get_target_prop(instance, sdev); + + is_target_prop = (ret_target_prop == DCMD_SUCCESS) ? true : false; + megasas_set_static_target_properties(sdev, is_target_prop); mutex_unlock(>hba_mutex); @@ -5682,6 +5707,98 @@ megasas_register_aen(struct megasas_instance
[PATCH v3 21/39] megaraid_sas: big endian support changes
Fix endiannes fixes for Ventura specific. Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- Fix in v3: Pass RAID_CONTEXT_G35 pointer to get/set_num_sge drivers/scsi/megaraid/megaraid_sas_fp.c | 15 ++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 70 ++--- drivers/scsi/megaraid/megaraid_sas_fusion.h | 115 +--- 3 files changed, 122 insertions(+), 78 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index 9d5d485..68582d9 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -210,7 +210,7 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) le32_to_cpu(fw_map_dyn->desc_table_size), le32_to_cpu(fw_map_dyn->desc_table_num_elements)); dev_dbg(>pdev->dev, "drv map %p ldCount %d\n", - drv_map, fw_map_dyn->ld_count); + drv_map, le16_to_cpu(fw_map_dyn->ld_count)); #endif desc_table = (struct MR_RAID_MAP_DESC_TABLE *)((void *)fw_map_dyn + le32_to_cpu(fw_map_dyn->desc_table_offset)); @@ -222,7 +222,8 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) pDrvRaidMap->ldCount = (__le16)cpu_to_le16(ld_count); pDrvRaidMap->fpPdIoTimeoutSec = fw_map_dyn->fp_pd_io_timeout_sec; - pDrvRaidMap->totalSize = sizeof(struct MR_DRV_RAID_MAP_ALL); + pDrvRaidMap->totalSize = + cpu_to_le32(sizeof(struct MR_DRV_RAID_MAP_ALL)); /* point to actual data starting point*/ raid_map_data = (void *)fw_map_dyn + le32_to_cpu(fw_map_dyn->desc_table_offset) + @@ -234,11 +235,11 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) dev_dbg(>pdev->dev, "desc table %p\n", desc_table); dev_dbg(>pdev->dev, "raidmap type %d, raidmapOffset 0x%x\n", - desc_table->raid_map_desc_type, - desc_table->raid_map_desc_offset); + le32_to_cpu(desc_table->raid_map_desc_type), + le32_to_cpu(desc_table->raid_map_desc_offset)); dev_dbg(>pdev->dev, "raid map number of elements 0%x, raidmapsize 0x%x\n", - desc_table->raid_map_desc_elements, - desc_table->raid_map_desc_buffer_size); + le32_to_cpu(desc_table->raid_map_desc_elements), + le32_to_cpu(desc_table->raid_map_desc_buffer_size)); #endif switch (le32_to_cpu(desc_table->raid_map_desc_type)) { case RAID_MAP_DESC_TYPE_DEVHDL_INFO: @@ -263,7 +264,7 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) #endif for (j = 0; j < le32_to_cpu(desc_table->raid_map_desc_elements); j++) { pDrvRaidMap->ldTgtIdToLd[j] = - fw_map_dyn->ld_tgt_id_to_ld[j]; + le16_to_cpu(fw_map_dyn->ld_tgt_id_to_ld[j]); #if VD_EXT_DEBUG dev_dbg(>pdev->dev, " %d drv ldTgtIdToLd %d\n", j, pDrvRaidMap->ldTgtIdToLd[j]); diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index b26ee85..baea4c2 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -2080,7 +2080,7 @@ static void megasas_stream_detect(struct megasas_instance *instance, */ continue; - cmd->io_request->RaidContext.raid_context_g35.stream_detected = true; + SET_STREAM_DETECTED(cmd->io_request->RaidContext.raid_context_g35); current_sd->next_seq_lba = io_info->ldStartBlock + io_info->numBlocks; /* @@ -2154,7 +2154,8 @@ megasas_set_raidflag_cpu_affinity(union RAID_CONTEXT_UNION *praid_context, /* Fast path cache by pass capable R0/R1 VD */ if ((raid->level <= 1) && (raid->capability.fp_cache_bypass_capable)) { - rctx_g35->routing_flags.bits.sld = 1; + rctx_g35->routing_flags |= + (1 << MR_RAID_CTX_ROUTINGFLAGS_SLD_SHIFT); rctx_g35->raid_flags =
[PATCH v3 36/39] megaraid_sas: Cleanup VD_EXT_DEBUG and SPAN_DEBUG related debug prints
Signed-off-by: Kashyap DesaiSigned-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 2 - drivers/scsi/megaraid/megaraid_sas_base.c | 15 -- drivers/scsi/megaraid/megaraid_sas_fp.c | 266 +--- drivers/scsi/megaraid/megaraid_sas_fusion.c | 5 - 4 files changed, 2 insertions(+), 286 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 42c0e1f..dc331e8 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1403,8 +1403,6 @@ struct megasas_ctrl_info { #define MEGASAS_FW_BUSY1 -#define VD_EXT_DEBUG 0 - /* Driver's internal Logging levels*/ #define OCR_LOGS(1 << 0) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 0e7121d..5e0dea1 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -4601,17 +4601,6 @@ static void megasas_update_ext_vd_details(struct megasas_instance *instance) } /* irrespective of FW raid maps, driver raid map is constant */ fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP_ALL); - -#if VD_EXT_DEBUG - dev_info(>pdev->dev, "instance->max_raid_mapsize 0x%x\n ", - instance->max_raid_mapsize); - dev_info(>pdev->dev, "new_map_sz = 0x%x, old_map_sz = 0x%x\n", - fusion->new_map_sz, fusion->old_map_sz); - dev_info(>pdev->dev, "ventura_map_sz = 0x%x, current_map_sz = 0x%x\n", - ventura_map_sz, fusion->current_map_sz); - dev_info(>pdev->dev, "fusion->drv_map_sz =0x%x, size of driver raid map 0x%lx\n", - fusion->drv_map_sz, sizeof(struct MR_DRV_RAID_MAP_ALL)); -#endif } /** @@ -5215,10 +5204,6 @@ static int megasas_init_fw(struct megasas_instance *instance) if (instance->is_ventura) { scratch_pad_3 = readl(>reg_set->outbound_scratch_pad_3); -#if VD_EXT_DEBUG - dev_info(>pdev->dev, "scratch_pad3 0x%x\n", - scratch_pad_3); -#endif instance->max_raid_mapsize = ((scratch_pad_3 >> MR_MAX_RAID_MAP_SIZE_OFFSET_SHIFT) & MR_MAX_RAID_MAP_SIZE_MASK); diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index a5517e7..7dc7708 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -77,7 +77,6 @@ MODULE_PARM_DESC(lb_pending_cmds, "Change raid-1 load balancing outstanding " #endif #define TRUE 1 -#define SPAN_DEBUG 0 #define SPAN_ROW_SIZE(map, ld, index_) (MR_LdSpanPtrGet(ld, index_, map)->spanRowSize) #define SPAN_ROW_DATA_SIZE(map_, ld, index_) (MR_LdSpanPtrGet(ld, index_, map)->spanRowDataSize) #define SPAN_INVALID 0xff @@ -202,16 +201,6 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) if (instance->max_raid_mapsize) { fw_map_dyn = fusion->ld_map[(instance->map_id & 1)]; -#if VD_EXT_DEBUG - dev_dbg(>pdev->dev, "raidMapSize 0x%x fw_map_dyn->descTableOffset 0x%x\n", - le32_to_cpu(fw_map_dyn->raid_map_size), - le32_to_cpu(fw_map_dyn->desc_table_offset)); - dev_dbg(>pdev->dev, "descTableSize 0x%x descTableNumElements 0x%x\n", - le32_to_cpu(fw_map_dyn->desc_table_size), - le32_to_cpu(fw_map_dyn->desc_table_num_elements)); - dev_dbg(>pdev->dev, "drv map %p ldCount %d\n", - drv_map, le16_to_cpu(fw_map_dyn->ld_count)); -#endif desc_table = (struct MR_RAID_MAP_DESC_TABLE *)((void *)fw_map_dyn + le32_to_cpu(fw_map_dyn->desc_table_offset)); if (desc_table != fw_map_dyn->raid_map_desc_table) @@ -230,25 +219,10 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) le32_to_cpu(fw_map_dyn->desc_table_size); for (i = 0; i < le32_to_cpu(fw_map_dyn->desc_table_num_elements); ++i) { - -#if VD_EXT_DEBUG - dev_dbg(>pdev->dev, "desc table %p\n", - desc_table); - dev_dbg(>pdev->dev, "raidmap type %d, raidmapOffset 0x%x\n", - le32_to_cpu(desc_table->raid_map_desc_type), - le32_to_cpu(desc_table->raid_map_desc_offset)); - dev_dbg(>pdev->dev, "raid map number of elements 0%x, raidmapsize 0x%x\n", - le32_to_cpu(desc_table->raid_map_desc_elements), - le32_to_cpu(desc_table->raid_map_desc_buffer_size)); -#endif
[PATCH v3 13/39] megaraid_sas: raid 1 write performance for large io
Avoid Host side PCI bandwidth bottleneck and hint FW to do Write buffering using RaidFlag MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT. Once IO is landed in FW with MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT, it will do single DMA from host and buffer the Write operation. On back end, FW will DMA same buffer to the Mirror and Data Arm. This will improve large block IO performance which bottleneck due to Host side PCI bandwidth limitation. Consistent ~4000MB T.P for 256K Block size is expected performance numbers. IOPS for small Block size should be on par with Disk performance. (E.g 42 SAS Disk in JBOD mode gives 3700MB T.P. Same Drive used in R1 WT mode, should give ~1800MB T.P) Using this patch 24 R1 VDs (HDD) gives below performance for Sequential Write. Without this patch, we cannot reach above 3200MB (Throughput is in MB. ) Block Size 50% 256K and 50% 4K 100% 256K 4K 31002030 8K 31402740 16K31403140 32K34003240 64K35003700 128K 38703870 256K 39203920 Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 5 + drivers/scsi/megaraid/megaraid_sas_fusion.c | 32 +++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 075e2e9..bed8a37 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1409,6 +1409,8 @@ struct megasas_ctrl_info { #define SCAN_VD_CHANNEL0x2 #define MEGASAS_KDUMP_QUEUE_DEPTH 100 +#define MR_LARGE_IO_MIN_SIZE (32 * 1024) +#define MR_R1_LDIO_PIGGYBACK_DEFAULT 4 enum MR_SCSI_CMD_TYPE { READ_WRITE_LDIO = 0, @@ -1875,6 +1877,7 @@ union megasas_frame { struct MR_PRIV_DEVICE { bool is_tm_capable; bool tm_busy; + atomic_t r1_ldio_hint; u8 interface_type; }; struct megasas_cmd; @@ -2235,6 +2238,8 @@ struct megasas_instance { bool is_ventura; bool msix_combined; u16 max_raid_mapsize; + /* preffered count to send as LDIO irrspective of FP capable.*/ + u8 r1_ldio_hint_default; u32 nvme_page_size; }; struct MR_LD_VF_MAP { diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 379c723..edbecc5 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1383,6 +1383,7 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) } instance->flag_ieee = 1; + instance->r1_ldio_hint_default = MR_R1_LDIO_PIGGYBACK_DEFAULT; fusion->fast_path_io = 0; fusion->drv_map_pages = get_order(fusion->drv_map_sz); @@ -2110,7 +2111,7 @@ static void megasas_stream_detect(struct megasas_instance *instance, static void megasas_set_raidflag_cpu_affinity(union RAID_CONTEXT_UNION *praid_context, struct MR_LD_RAID *raid, bool fp_possible, - u8 is_read) + u8 is_read, u32 scsi_buff_len) { u8 cpu_sel = MR_RAID_CTX_CPUSEL_0; struct RAID_CONTEXT_G35 *rctx_g35; @@ -2161,6 +2162,17 @@ megasas_set_raidflag_cpu_affinity(union RAID_CONTEXT_UNION *praid_context, } rctx_g35->routing_flags.bits.cpu_sel = cpu_sel; + + /* Always give priority to MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT +* vs MR_RAID_FLAGS_IO_SUB_TYPE_CACHE_BYPASS. +* IO Subtype is not bitmap. +*/ + if ((raid->level == 1) && (!is_read)) { + if (scsi_buff_len > MR_LARGE_IO_MIN_SIZE) + praid_context->raid_context_g35.raid_flags = + (MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT + << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT); + } } /** @@ -2303,6 +2315,14 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, io_info.isRead && io_info.ra_capable) fp_possible = false; + /* FP for Optimal raid level 1. +* All large RAID-1 writes (> 32 KiB, both WT and WB modes) +* are built by the driver as LD I/Os. +* All small RAID-1 WT writes (<= 32 KiB) are built as FP I/Os +* (there is never a reason to process these as buffered writes) +* All small RAID-1 WB writes (<= 32 KiB) are built as FP I/Os +* with the
[PATCH v3 18/39] megaraid_sas: In validate raid map, raid capability is not converted to cpu format for all lds
On a host, if an ld is deleted there is a hole in the ld array returned by the FW. But in MR_ValidateMapInfo we are not accounting for holes in the ld array and traverse only upto index num_lds. This patch takes care of converting the capability field of all the valid lds in the ld raid map. Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fp.c | 13 ++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index d9b0f28..a0b0e68 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -452,7 +452,7 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance) struct LD_LOAD_BALANCE_INFO *lbInfo; PLD_SPAN_INFO ldSpanInfo; struct MR_LD_RAID *raid; - u16 ldCount, num_lds; + u16 num_lds, i; u16 ld; u32 expected_size; @@ -495,10 +495,17 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance) num_lds = le16_to_cpu(drv_map->raidMap.ldCount); /*Convert Raid capability values to CPU arch */ - for (ldCount = 0; ldCount < num_lds; ldCount++) { - ld = MR_TargetIdToLdGet(ldCount, drv_map); + for (i = 0; (num_lds > 0) && (i < MAX_LOGICAL_DRIVES_EXT); i++) { + ld = MR_TargetIdToLdGet(i, drv_map); + + /* For non existing VDs, iterate to next VD*/ + if (ld >= (MAX_LOGICAL_DRIVES_EXT - 1)) + continue; + raid = MR_LdRaidGet(ld, drv_map); le32_to_cpus((u32 *)>capability); + + num_lds--; } return 1; -- 2.8.3
[PATCH v3 20/39] megaraid_sas: Big endian RDPQ mode fix
Fix if RDPQ mode enabled MR FW is deployed on big endian host machine, driver does not setup reply address correctly. Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 4aaf307..b26ee85 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -580,7 +580,7 @@ megasas_alloc_rdpq_fusion(struct megasas_instance *instance) } fusion->rdpq_virt[i].RDPQBaseAddress = - fusion->reply_frames_desc_phys[i]; + cpu_to_le64(fusion->reply_frames_desc_phys[i]); reply_desc = fusion->reply_frames_desc[i]; for (j = 0; j < fusion->reply_q_depth; j++, reply_desc++) -- 2.8.3
[PATCH v3 37/39] megaraid_sas: Indentation and smatch warning fixes
Fix indentation issues and smatch warning reported by Dan Carpenter for previous series as discussed below. http://www.spinics.net/lists/linux-scsi/msg103635.html http://www.spinics.net/lists/linux-scsi/msg103603.html Reported-by: Dan CarpenterSigned-off-by: Kashyap Desai Signed-off-by: Sasikumar Chandrasekaran Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 2 +- drivers/scsi/megaraid/megaraid_sas_base.c | 10 ++-- drivers/scsi/megaraid/megaraid_sas_fp.c | 57 +- drivers/scsi/megaraid/megaraid_sas_fusion.c | 92 ++--- drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 +- 5 files changed, 80 insertions(+), 83 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index dc331e8..8c06cbf 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1376,7 +1376,7 @@ struct megasas_ctrl_info { u16 reserved:8; #endif } adapter_operations4; - u8 pad[0x800-0x7FE]; /* 0x7FE pad to 2K for expansion */ + u8 pad[0x800 - 0x7FE]; /* 0x7FE pad to 2K for expansion */ } __packed; /* diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 5e0dea1..dc9f42e 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -5343,14 +5343,14 @@ static int megasas_init_fw(struct megasas_instance *instance) memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); /* stream detection initialization */ - if (instance->is_ventura) { + if (instance->is_ventura && fusion) { fusion->stream_detect_by_ld = - kzalloc(sizeof(struct LD_STREAM_DETECT *) - * MAX_LOGICAL_DRIVES_EXT, - GFP_KERNEL); + kzalloc(sizeof(struct LD_STREAM_DETECT *) + * MAX_LOGICAL_DRIVES_EXT, + GFP_KERNEL); if (!fusion->stream_detect_by_ld) { dev_err(>pdev->dev, - "unable to allocate stream detection for pool of LDs\n"); + "unable to allocate stream detection for pool of LDs\n"); goto fail_get_ld_pd_list; } for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i) { diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index 7dc7708..62affa7 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -197,7 +197,7 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) memset(drv_map, 0, fusion->drv_map_sz); memset(pDrvRaidMap->ldTgtIdToLd, - 0xff, (sizeof(u16) * MAX_LOGICAL_DRIVES_DYN)); + 0xff, (sizeof(u16) * MAX_LOGICAL_DRIVES_DYN)); if (instance->max_raid_mapsize) { fw_map_dyn = fusion->ld_map[(instance->map_id & 1)]; @@ -224,34 +224,37 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) fw_map_dyn->dev_hndl_info = (struct MR_DEV_HANDLE_INFO *)(raid_map_data + le32_to_cpu(desc_table->raid_map_desc_offset)); memcpy(pDrvRaidMap->devHndlInfo, - fw_map_dyn->dev_hndl_info, - sizeof(struct MR_DEV_HANDLE_INFO) * - le32_to_cpu(desc_table->raid_map_desc_elements)); + fw_map_dyn->dev_hndl_info, + sizeof(struct MR_DEV_HANDLE_INFO) * + le32_to_cpu(desc_table->raid_map_desc_elements)); break; case RAID_MAP_DESC_TYPE_TGTID_INFO: fw_map_dyn->ld_tgt_id_to_ld = - (u16 *) (raid_map_data + - le32_to_cpu(desc_table->raid_map_desc_offset)); - for (j = 0; j < le32_to_cpu(desc_table->raid_map_desc_elements); j++) { - pDrvRaidMap->ldTgtIdToLd[j] = - le16_to_cpu(fw_map_dyn->ld_tgt_id_to_ld[j]); - } + (u16 *)(raid_map_data + + le32_to_cpu(desc_table->raid_map_desc_offset)); + for (j = 0; j < le32_to_cpu(desc_table->raid_map_desc_elements); j++) { + pDrvRaidMap->ldTgtIdToLd[j] = + le16_to_cpu(fw_map_dyn->ld_tgt_id_to_ld[j]); +
[PATCH v3 03/39] megaraid_sas: raid 1 fast path code optimize
No functional change. Code refactor. Remove function megasas_fpio_to_ldio as we never require to convert fpio to ldio because of frame unavailability. Grab extra frame of raid 1 write fast path before it creates first frame as Fast Path. Removed is_raid_1_fp_write flag as raid 1 write fast path command is decided using r1_alt_dev_handle only. Move resetting megasas_cmd_fusion fields at common function megasas_return_cmd_fusion. Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- Fix in v2: ex_status and status was wrongly re-used in megasas_complete_r1_command. discussed below - http://marc.info/?l=linux-scsi=148638763409385=2 drivers/scsi/megaraid/megaraid_sas_fp.c | 14 +- drivers/scsi/megaraid/megaraid_sas_fusion.c | 349 +--- drivers/scsi/megaraid/megaraid_sas_fusion.h | 3 +- 3 files changed, 118 insertions(+), 248 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index f1384b0..24258af 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -1338,20 +1338,8 @@ MR_BuildRaidContext(struct megasas_instance *instance, ref_in_start_stripe, io_info, pRAID_Context, map); /* If IO on an invalid Pd, then FP is not possible.*/ - if (io_info->devHandle == cpu_to_le16(MR_PD_INVALID)) + if (io_info->devHandle == MR_DEVHANDLE_INVALID) io_info->fpOkForIo = FALSE; - /* if FP possible, set the SLUD bit in -* regLockFlags for ventura -*/ - else if ((instance->is_ventura) && (!isRead) && - (raid->writeMode == MR_RL_WRITE_BACK_MODE) && - (raid->capability.fp_cache_bypass_capable)) - ((struct RAID_CONTEXT_G35 *) pRAID_Context)->routing_flags.bits.sld = 1; - /* set raid 1/10 fast path write capable bit in io_info */ - if (io_info->fpOkForIo && - (io_info->r1_alt_dev_handle != MR_PD_INVALID) && - (raid->level == 1) && !isRead) - io_info->is_raid_1_fp_write = 1; return retval; } else if (isRead) { uint stripIdx; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 514c306..7516589 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -181,7 +181,9 @@ inline void megasas_return_cmd_fusion(struct megasas_instance *instance, struct megasas_cmd_fusion *cmd) { cmd->scmd = NULL; - memset(cmd->io_request, 0, sizeof(struct MPI2_RAID_SCSI_IO_REQUEST)); + memset(cmd->io_request, 0, MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE); + cmd->r1_alt_dev_handle = MR_DEVHANDLE_INVALID; + cmd->cmd_completed = false; } /** @@ -701,7 +703,7 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance) memset(cmd->io_request, 0, sizeof(struct MPI2_RAID_SCSI_IO_REQUEST)); cmd->io_request_phys_addr = io_req_base_phys + offset; - cmd->is_raid_1_fp_write = 0; + cmd->r1_alt_dev_handle = MR_DEVHANDLE_INVALID; } if (megasas_create_sg_sense_fusion(instance)) @@ -1984,7 +1986,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, io_info.ldStartBlock = ((u64)start_lba_hi << 32) | start_lba_lo; io_info.numBlocks = datalength; io_info.ldTgtId = device_id; - io_info.r1_alt_dev_handle = MR_PD_INVALID; + io_info.r1_alt_dev_handle = MR_DEVHANDLE_INVALID; scsi_buff_len = scsi_bufflen(scp); io_request->DataLength = cpu_to_le32(scsi_buff_len); @@ -2025,7 +2027,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, io_info.isRead && io_info.ra_capable) fp_possible = false; - if (io_info.r1_alt_dev_handle != MR_PD_INVALID) { + if (io_info.r1_alt_dev_handle != MR_DEVHANDLE_INVALID) { mrdev_priv = scp->device->hostdata; if (atomic_inc_return(>fw_outstanding) > @@ -2090,9 +2092,10 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, } else scp->SCp.Status &= ~MEGASAS_LOAD_BALANCE_FLAG; - cmd->is_raid_1_fp_write = io_info.is_raid_1_fp_write; - if (io_info.is_raid_1_fp_write) + if (instance->is_ventura) cmd->r1_alt_dev_handle = io_info.r1_alt_dev_handle; + else +
[PATCH v3 27/39] megaraid_sas: max_fw_cmds are decremented twice, remove duplicate
Fix to account for the reply_q_sz not exceeding the maximum commands that the firmware can support, instance->max_fw_cmds is already decremented in megasas_fusion_update_can_queue(). Remove the extra decrement logic in code. Signed-off-by: Kashyap DesaiSigned-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 7 --- 1 file changed, 7 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 94b7a68..74cefae 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1285,13 +1285,6 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) megasas_fusion_update_can_queue(instance, PROBE_CONTEXT); /* -* Reduce the max supported cmds by 1. This is to ensure that the -* reply_q_sz (1 more than the max cmd that driver may send) -* does not exceed max cmds that the FW can support -*/ - instance->max_fw_cmds = instance->max_fw_cmds-1; - - /* * Only Driver's internal DCMDs and IOCTL DCMDs needs to have MFI frames */ instance->max_mfi_cmds = -- 2.8.3
[PATCH v3 30/39] megaraid_sas: Do not set fp_possible if TM capable for non-RW syspdIO, change fp_possible to bool
FIX - firmware wants non-RW SYS PD IOs to avoid FastPath for better tracking and other functionalities if the device is task management capable. Signed-off-by: Kashyap DesaiSigned-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index a9b66ce..ba102e4 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -2566,7 +2566,8 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, */ static void megasas_build_syspd_fusion(struct megasas_instance *instance, - struct scsi_cmnd *scmd, struct megasas_cmd_fusion *cmd, u8 fp_possible) + struct scsi_cmnd *scmd, struct megasas_cmd_fusion *cmd, + bool fp_possible) { u32 device_id; struct MPI2_RAID_SCSI_IO_REQUEST *io_request; @@ -2687,6 +2688,8 @@ megasas_build_io_fusion(struct megasas_instance *instance, int sge_count; u8 cmd_type; struct MPI2_RAID_SCSI_IO_REQUEST *io_request = cmd->io_request; + struct MR_PRIV_DEVICE *mr_device_priv_data; + mr_device_priv_data = scp->device->hostdata; /* Zero out some fields so they don't get reused */ memset(io_request->LUN, 0x0, 8); @@ -2715,12 +2718,14 @@ megasas_build_io_fusion(struct megasas_instance *instance, megasas_build_ld_nonrw_fusion(instance, scp, cmd); break; case READ_WRITE_SYSPDIO: + megasas_build_syspd_fusion(instance, scp, cmd, true); + break; case NON_READ_WRITE_SYSPDIO: - if (instance->secure_jbod_support && - (cmd_type == NON_READ_WRITE_SYSPDIO)) - megasas_build_syspd_fusion(instance, scp, cmd, 0); + if (instance->secure_jbod_support || + mr_device_priv_data->is_tm_capable) + megasas_build_syspd_fusion(instance, scp, cmd, false); else - megasas_build_syspd_fusion(instance, scp, cmd, 1); + megasas_build_syspd_fusion(instance, scp, cmd, true); break; default: break; -- 2.8.3
[PATCH v3 35/39] megaraid_sas: Increase internal command pool
Fix - increase internal command pool to 8. Signed-off-by: Kashyap DesaiSigned-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 2 +- drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 508516d..42c0e1f 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1460,7 +1460,7 @@ enum FW_BOOT_CONTEXT { */ #define MEGASAS_INT_CMDS 32 #define MEGASAS_SKINNY_INT_CMDS5 -#define MEGASAS_FUSION_INTERNAL_CMDS 5 +#define MEGASAS_FUSION_INTERNAL_CMDS 8 #define MEGASAS_FUSION_IOCTL_CMDS 3 #define MEGASAS_MFI_IOCTL_CMDS 27 diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index d8bfb87..773ce34 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1350,7 +1350,7 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) fusion->last_reply_idx[i] = 0; /* -* For fusion adapters, 3 commands for IOCTL and 5 commands +* For fusion adapters, 3 commands for IOCTL and 8 commands * for driver's internal DCMDs. */ instance->max_scsi_cmds = instance->max_fw_cmds - -- 2.8.3
[PATCH v3 31/39] megaraid_sas: During OCR, if get_ctrl_info fails do not continue with OCR
Error handling: If controller reset is not able to recover, kill HBA and quit immediately. Signed-off-by: Kashyap DesaiSigned-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index ba102e4..c0a58dc 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -4285,6 +4285,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason) __func__, __LINE__); megaraid_sas_kill_hba(instance); retval = FAILED; + goto out; } /* Reset load balance info */ if (fusion->load_balance_info) -- 2.8.3
[Bug 151661] Adaptec 3405 3805 prints "AAC: Host adapter dead -1" every 10 seconds but works fine anyway
https://bugzilla.kernel.org/show_bug.cgi?id=151661 --- Comment #19 from Arkadiusz Miskiewicz (ar...@maven.pl) --- Fix: http://git.kernel.org/cgit/linux/kernel/git/jejb/scsi.git/patch/?id=8af8e1c22f9994bb1849c01d66c24fe23f9bc9a0 -- You are receiving this mail because: You are watching the assignee of the bug.
[PATCH v3 39/39] megaraid_sas: driver version upgrade
Signed-off-by: Kashyap DesaiSigned-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 8c06cbf..e7e5974 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -35,8 +35,8 @@ /* * MegaRAID SAS Driver meta data */ -#define MEGASAS_VERSION"07.700.00.00-rc1" -#define MEGASAS_RELDATE"November 29, 2016" +#define MEGASAS_VERSION"07.701.16.00-rc1" +#define MEGASAS_RELDATE"February 2, 2017" /* * Device IDs -- 2.8.3
[PATCH v3 10/39] megaraid_sas: NVME Interface detection and prop settings
New functionality Adding detection logic for NVME device attached behind Ventura controller. Driver set HostPageSize in IOC_INIT frame to inform about page size for NVME devices. Firmware reports NVME page size to the driver. PD INFO DCMD provide new interface type NVME_PD. Driver set property of NVME device. Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 23 ++-- drivers/scsi/megaraid/megaraid_sas_base.c | 170 drivers/scsi/megaraid/megaraid_sas_fusion.c | 6 +- drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 +- 4 files changed, 142 insertions(+), 59 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index d9049d5..f9efddf 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -733,7 +733,6 @@ struct megasas_pd_list { u16 tid; u8 driveType; u8 driveState; - u8 interface; } __packed; /* @@ -1530,8 +1529,8 @@ struct megasas_register_set { u32 outbound_scratch_pad ; /*00B0h*/ u32 outbound_scratch_pad_2; /*00B4h*/ u32 outbound_scratch_pad_3; /*00B8h*/ + u32 outbound_scratch_pad_4; /*00BCh*/ - u32 reserved_4; /*00BCh*/ u32 inbound_low_queue_port ;/*00C0h*/ @@ -1864,6 +1863,7 @@ union megasas_frame { struct MR_PRIV_DEVICE { bool is_tm_capable; bool tm_busy; + u8 interface_type; }; struct megasas_cmd; @@ -2055,17 +2055,24 @@ struct MR_DRV_SYSTEM_INFO { }; enum MR_PD_TYPE { -UNKNOWN_DRIVE = 0, -PARALLEL_SCSI = 1, -SAS_PD = 2, -SATA_PD = 3, -FC_PD = 4, + UNKNOWN_DRIVE = 0, + PARALLEL_SCSI = 1, + SAS_PD = 2, + SATA_PD = 3, + FC_PD = 4, + NVME_PD = 5, }; /* JBOD Queue depth definitions */ #define MEGASAS_SATA_QD32 #define MEGASAS_SAS_QD 64 #define MEGASAS_DEFAULT_PD_QD 64 +#define MEGASAS_NVME_QD32 + +#define MR_DEFAULT_NVME_PAGE_SIZE 4096 +#define MR_DEFAULT_NVME_PAGE_SHIFT 12 +#define MR_DEFAULT_NVME_MDTS_KB128 +#define MR_NVME_PAGE_SIZE_MASK 0x00FF struct megasas_instance { @@ -2209,6 +2216,7 @@ struct megasas_instance { bool is_ventura; bool msix_combined; u16 max_raid_mapsize; + u32 nvme_page_size; }; struct MR_LD_VF_MAP { u32 size; @@ -2428,6 +2436,7 @@ int megasas_get_ctrl_info(struct megasas_instance *instance); /* PD sequence */ int megasas_sync_pd_seq_num(struct megasas_instance *instance, bool pend); +void megasas_set_dynamic_target_properties(struct scsi_device *sdev); int megasas_set_crash_dump_params(struct megasas_instance *instance, u8 crash_buf_state); void megasas_free_host_crash_buffer(struct megasas_instance *instance); diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 23fb78a..f383bf2 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -116,8 +116,8 @@ static int megasas_ld_list_query(struct megasas_instance *instance, static int megasas_issue_init_mfi(struct megasas_instance *instance); static int megasas_register_aen(struct megasas_instance *instance, u32 seq_num, u32 class_locale_word); -static int -megasas_get_pd_info(struct megasas_instance *instance, u16 device_id); +static void megasas_get_pd_info(struct megasas_instance *instance, + struct scsi_device *sdev); /* * PCI ID table for all supported controllers */ @@ -1738,16 +1738,21 @@ static struct megasas_instance *megasas_lookup_instance(u16 host_no) } /* -* megasas_update_sdev_properties - Update sdev structure based on controller's FW capabilities +* megasas_set_dynamic_target_properties - +* Device property set by driver may not be static and it is required to be +* updated after OCR +* +* set tm_capable. +* set dma alignment (only for eedp protection enable vd). * * @sdev: OS provided scsi device * * Returns void */ -void megasas_update_sdev_properties(struct scsi_device *sdev) +void megasas_set_dynamic_target_properties(struct scsi_device *sdev) { - u16 pd_index = 0; - u32 device_id, ld; + u16 pd_index = 0, ld; + u32 device_id; struct megasas_instance *instance; struct fusion_context *fusion; struct MR_PRIV_DEVICE *mr_device_priv_data; @@ -1772,57 +1777,102 @@ void megasas_update_sdev_properties(struct scsi_device *sdev) raid = MR_LdRaidGet(ld,
[PATCH v3 23/39] megaraid_sas: latest controller OCR capability from FW before sending shutdown DCMD
Fetch the latest controller OCR capability from FW before sending MR_DCMD_CTRL_SHUTDOWN When application sends a shutdown DCMD (MR_DCMD_CTRL_SHUTDOWN), driver will fetch latest controller information from firmware. This is to ensure that driver always has latest OCR capability of controller before sending the DCMD. Signed-off-by: Kashyap DesaiSigned-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_base.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 5d7aa05..cd9d223 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -6900,6 +6900,13 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, MFI_FRAME_SGL64 | MFI_FRAME_SENSE64)); + if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_SHUTDOWN) { + if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS) { + megasas_return_cmd(instance, cmd); + return -1; + } + } + if (cmd->frame->dcmd.opcode == MR_DRIVER_SET_APP_CRASHDUMP_MODE) { error = megasas_set_crash_dump_params_ioctl(cmd); megasas_return_cmd(instance, cmd); -- 2.8.3
[PATCH v3 19/39] megaraid_sas: MR_TargetIdToLdGet u8 to u16 and avoid invalid raid-map access
Change MR_TargetIdToLdGet return type from u8 to u16. ld id range check is added at two places in this patch - @megasas_build_ldio_fusion and @megasas_build_ld_nonrw_fusion. Previous driver code used different data type for lds TargetId returned from MR_TargetIdToLdGet. Prior to this change, above two functions was safeguarded due to function always return u8 and maximum value of ld id returned was 255. In below check, fw_supported_vd_count as of today is 64 or 256 and valid range to support is either 0-63 or 0-255. Ideally want to filter accessing raid map for ld ids which are not valid. With the u16 change, invalid ld id value is 0x and we will see kernel panic due to random memory access in MR_LdRaidGet. The changes will ensure we do not call MR_LdRaidGet if ld id is beyond size of ldSpanMap array. if (ld < instance->fw_supported_vd_count) >From firmware perspective,ld id 0xFF is invalid and even though current driver code forward such command, firmware fails with target not available. ld target id issue occurs mainly whenever driver loops to populate raid map (ea. MR_ValidateMapInfo). These are the only two places where we may see out of range target ids and wants to protect raid map access based on range provided by Firmware API. Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai --- fix in v2 - updated description content. drivers/scsi/megaraid/megaraid_sas.h| 2 +- drivers/scsi/megaraid/megaraid_sas_fp.c | 5 +++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 25 ++--- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 0a20fff..efc01a3 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2448,7 +2448,7 @@ MR_BuildRaidContext(struct megasas_instance *instance, struct IO_REQUEST_INFO *io_info, struct RAID_CONTEXT *pRAID_Context, struct MR_DRV_RAID_MAP_ALL *map, u8 **raidLUN); -u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map); +u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map); struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_DRV_RAID_MAP_ALL *map); u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_DRV_RAID_MAP_ALL *map); u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_DRV_RAID_MAP_ALL *map); diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index a0b0e68..9d5d485 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -165,7 +165,7 @@ u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map) return le16_to_cpu(map->raidMap.ldSpanMap[ld].ldRaid.targetId); } -u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map) +u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map) { return map->raidMap.ldTgtIdToLd[ldTgtId]; } @@ -1151,7 +1151,7 @@ MR_BuildRaidContext(struct megasas_instance *instance, { struct fusion_context *fusion; struct MR_LD_RAID *raid; - u32 ld, stripSize, stripe_mask; + u32 stripSize, stripe_mask; u64 endLba, endStrip, endRow, start_row, start_strip; u64 regStart; u32 regSize; @@ -1163,6 +1163,7 @@ MR_BuildRaidContext(struct megasas_instance *instance, u8 retval = 0; u8 startlba_span = SPAN_INVALID; u64 *pdBlock = _info->pdBlock; + u16 ld; ldStartBlock = io_info->ldStartBlock; numBlocks = io_info->numBlocks; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 9019b82..4aaf307 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1121,7 +1121,8 @@ megasas_sync_map_info(struct megasas_instance *instance) int i; struct megasas_cmd *cmd; struct megasas_dcmd_frame *dcmd; - u32 size_sync_info, num_lds; + u16 num_lds; + u32 size_sync_info; struct fusion_context *fusion; struct MR_LD_TARGET_SYNC *ci = NULL; struct MR_DRV_RAID_MAP_ALL *map; @@ -1870,7 +1871,7 @@ megasas_set_pd_lba(struct MPI2_RAID_SCSI_IO_REQUEST *io_request, u8 cdb_len, struct MR_DRV_RAID_MAP_ALL *local_map_ptr, u32 ref_tag) { struct MR_LD_RAID *raid; - u32 ld; + u16 ld; u64 start_blk = io_info->pdBlock; u8 *cdb = io_request->CDB.CDB32; u32 num_blocks = io_info->numBlocks; @@ -2303,10 +2304,11 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)]; ld = MR_TargetIdToLdGet(device_id, local_map_ptr); - raid =
[PATCH v3 17/39] megaraid_sas: reduce size of fusion_context and use vmalloc if kmalloc fails
Currently fusion context has fixed array load_balance_info. Use dynamic allocation. In few places, driver do not want physically contigious memory. Attempt to use vmalloc if physical contiguous memory is not available. Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 2 + drivers/scsi/megaraid/megaraid_sas_base.c | 15 ++ drivers/scsi/megaraid/megaraid_sas_fp.c | 3 +- drivers/scsi/megaraid/megaraid_sas_fusion.c | 71 +++-- drivers/scsi/megaraid/megaraid_sas_fusion.h | 3 +- 5 files changed, 76 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 93da6dc..0a20fff 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2488,4 +2488,6 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason); int megasas_task_abort_fusion(struct scsi_cmnd *scmd); int megasas_reset_target_fusion(struct scsi_cmnd *scmd); u32 mega_mod64(u64 dividend, u32 divisor); +int megasas_alloc_fusion_context(struct megasas_instance *instance); +void megasas_free_fusion_context(struct megasas_instance *instance); #endif /*LSI_MEGARAID_SAS_H */ diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index c8fa480..b2da257 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -6029,18 +6029,12 @@ static int megasas_probe_one(struct pci_dev *pdev, case PCI_DEVICE_ID_LSI_CUTLASS_52: case PCI_DEVICE_ID_LSI_CUTLASS_53: { - instance->ctrl_context_pages = - get_order(sizeof(struct fusion_context)); - instance->ctrl_context = (void *)__get_free_pages(GFP_KERNEL, - instance->ctrl_context_pages); - if (!instance->ctrl_context) { - dev_printk(KERN_DEBUG, >dev, "Failed to allocate " - "memory for Fusion context info\n"); + if (megasas_alloc_fusion_context(instance)) { + megasas_free_fusion_context(instance); goto fail_alloc_dma_buf; } fusion = instance->ctrl_context; - memset(fusion, 0, - ((1 << PAGE_SHIFT) << instance->ctrl_context_pages)); + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA)) fusion->adapter_type = THUNDERBOLT_SERIES; @@ -6683,8 +6677,7 @@ static void megasas_detach_one(struct pci_dev *pdev) fusion->pd_seq_sync[i], fusion->pd_seq_phys[i]); } - free_pages((ulong)instance->ctrl_context, - instance->ctrl_context_pages); + megasas_free_fusion_context(instance); } else { megasas_release_mfi(instance); pci_free_consistent(pdev, sizeof(u32), diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index c3ef82d..d9b0f28 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -489,7 +489,8 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance) if (instance->UnevenSpanSupport) mr_update_span_set(drv_map, ldSpanInfo); - mr_update_load_balance_params(drv_map, lbInfo); + if (lbInfo) + mr_update_load_balance_params(drv_map, lbInfo); num_lds = le16_to_cpu(drv_map->raidMap.ldCount); diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 1252a3c..9019b82 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -2397,8 +2398,9 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, io_request->IoFlags |= cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH); } - if ((fusion->load_balance_info[device_id].loadBalanceFlag) && - (io_info.isRead)) { + if (fusion->load_balance_info && + (fusion->load_balance_info[device_id].loadBalanceFlag) && + (io_info.isRead)) { io_info.devHandle = get_updated_dev_handle(instance, >load_balance_info[device_id], @@ -4270,9
[PATCH v3 16/39] megaraid_sas: add print in device removal path
Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_base.c | 19 +++ 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index b41bbea..c8fa480 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -7383,6 +7383,13 @@ megasas_sysfs_set_dbg_lvl(struct device_driver *dd, const char *buf, size_t coun static DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUSR, megasas_sysfs_show_dbg_lvl, megasas_sysfs_set_dbg_lvl); +static inline void megasas_remove_scsi_device(struct scsi_device *sdev) +{ + sdev_printk(KERN_INFO, sdev, "SCSI device is removed\n"); + scsi_remove_device(sdev); + scsi_device_put(sdev); +} + static void megasas_aen_polling(struct work_struct *work) { @@ -7487,10 +7494,8 @@ megasas_aen_polling(struct work_struct *work) else scsi_device_put(sdev1); } else { - if (sdev1) { - scsi_remove_device(sdev1); - scsi_device_put(sdev1); - } + if (sdev1) + megasas_remove_scsi_device(sdev1); } } } @@ -7507,10 +7512,8 @@ megasas_aen_polling(struct work_struct *work) else scsi_device_put(sdev1); } else { - if (sdev1) { - scsi_remove_device(sdev1); - scsi_device_put(sdev1); - } + if (sdev1) + megasas_remove_scsi_device(sdev1); } } } -- 2.8.3
[PATCH v3 01/39] Revert "scsi: megaraid_sas: Enable or Disable Fast path based on the PCI Threshold Bandwidth"
This reverts commit "3e5eadb1a881" ("scsi: megaraid_sas: Enable or Disable Fast path based on the PCI Threshold Bandwidth") This patch was aimed to increase performance of R1 Write operation for large IO size. Since this method used timer approach, it turn on/off fast path did not work as expected. Patch 0013 describes new algorithm and performance number. Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 8 - drivers/scsi/megaraid/megaraid_sas_base.c | 48 - drivers/scsi/megaraid/megaraid_sas_fp.c | 7 - drivers/scsi/megaraid/megaraid_sas_fusion.c | 16 -- drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 +- 5 files changed, 7 insertions(+), 74 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index ba9fbb7..f5c4742 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1477,8 +1477,6 @@ enum FW_BOOT_CONTEXT { #define MFI_1068_FW_HANDSHAKE_OFFSET 0x64 #define MFI_1068_FW_READY 0x -#define MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL HZ - #define MR_MAX_REPLY_QUEUES_OFFSET 0X001F #define MR_MAX_REPLY_QUEUES_EXT_OFFSET 0X003FC000 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT14 @@ -2154,10 +2152,6 @@ struct megasas_instance { atomic_t ldio_outstanding; atomic_t fw_reset_no_pci_access; - atomic64_t bytes_wrote; /* used for raid1 fast path enable or disable */ - atomic_t r1_write_fp_capable; - - struct megasas_instance_template *instancet; struct tasklet_struct isr_tasklet; struct work_struct work_init; @@ -2199,7 +2193,6 @@ struct megasas_instance { long reset_flags; struct mutex reset_mutex; struct timer_list sriov_heartbeat_timer; - struct timer_list r1_fp_hold_timer; char skip_heartbeat_timer_del; u8 requestorId; char PlasmaFW111; @@ -2216,7 +2209,6 @@ struct megasas_instance { bool is_ventura; bool msix_combined; u16 max_raid_mapsize; - u64 pci_threshold_bandwidth; /* used to control the fp writes */ }; struct MR_LD_VF_MAP { u32 size; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 70891a7..3ed876a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1940,9 +1940,6 @@ void megaraid_sas_kill_hba(struct megasas_instance *instance) } /* Complete outstanding ioctls when adapter is killed */ megasas_complete_outstanding_ioctls(instance); - if (instance->is_ventura) - del_timer_sync(>r1_fp_hold_timer); - } /** @@ -2441,24 +2438,6 @@ void megasas_sriov_heartbeat_handler(unsigned long instance_addr) } } -/*Handler for disabling/enabling raid 1 fast paths*/ -void megasas_change_r1_fp_status(unsigned long instance_addr) -{ - struct megasas_instance *instance = - (struct megasas_instance *)instance_addr; - if (atomic64_read(>bytes_wrote) >= - instance->pci_threshold_bandwidth) { - - atomic64_set(>bytes_wrote, 0); - atomic_set(>r1_write_fp_capable, 0); - } else { - atomic64_set(>bytes_wrote, 0); - atomic_set(>r1_write_fp_capable, 1); - } - mod_timer(>r1_fp_hold_timer, -jiffies + MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL); -} - /** * megasas_wait_for_outstanding - Wait for all outstanding cmds * @instance: Adapter soft state @@ -5386,17 +5365,6 @@ static int megasas_init_fw(struct megasas_instance *instance) instance->skip_heartbeat_timer_del = 1; } - if (instance->is_ventura) { - atomic64_set(>bytes_wrote, 0); - atomic_set(>r1_write_fp_capable, 1); - megasas_start_timer(instance, - >r1_fp_hold_timer, - megasas_change_r1_fp_status, - MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL); - dev_info(>pdev->dev, "starting the raid 1 fp timer with interval %d\n", - MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL); - } - return 0; fail_get_ld_pd_list: @@ -6187,9 +6155,6 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state) if (instance->requestorId && !instance->skip_heartbeat_timer_del) del_timer_sync(>sriov_heartbeat_timer); - if (instance->is_ventura) - del_timer_sync(>r1_fp_hold_timer); -
[PATCH v3 05/39] megaraid_sas: Refactor MEGASAS_IS_LOGICAL macro using sdev
Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 4 ++-- drivers/scsi/megaraid/megaraid_sas_base.c | 20 ++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 12 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index f5c4742..dff877f 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2301,8 +2301,8 @@ struct megasas_instance_template { struct megasas_cmd *cmd); }; -#define MEGASAS_IS_LOGICAL(scp) \ - ((scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1) +#define MEGASAS_IS_LOGICAL(sdev) \ + ((sdev->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1) #define MEGASAS_DEV_INDEX(scp) \ (((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + \ diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 3ed876a..6ca49ef 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1279,7 +1279,7 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, u16 flags = 0; struct megasas_pthru_frame *pthru; - is_logical = MEGASAS_IS_LOGICAL(scp); + is_logical = MEGASAS_IS_LOGICAL(scp->device); device_id = MEGASAS_DEV_INDEX(scp); pthru = (struct megasas_pthru_frame *)cmd->frame; @@ -1519,11 +1519,11 @@ inline int megasas_cmd_type(struct scsi_cmnd *cmd) case WRITE_6: case READ_16: case WRITE_16: - ret = (MEGASAS_IS_LOGICAL(cmd)) ? + ret = (MEGASAS_IS_LOGICAL(cmd->device)) ? READ_WRITE_LDIO : READ_WRITE_SYSPDIO; break; default: - ret = (MEGASAS_IS_LOGICAL(cmd)) ? + ret = (MEGASAS_IS_LOGICAL(cmd->device)) ? NON_READ_WRITE_LDIO : NON_READ_WRITE_SYSPDIO; } return ret; @@ -1699,15 +1699,16 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) scmd->result = 0; - if (MEGASAS_IS_LOGICAL(scmd) && + if (MEGASAS_IS_LOGICAL(scmd->device) && (scmd->device->id >= instance->fw_supported_vd_count || scmd->device->lun)) { scmd->result = DID_BAD_TARGET << 16; goto out_done; } - if ((scmd->cmnd[0] == SYNCHRONIZE_CACHE) && MEGASAS_IS_LOGICAL(scmd) && - (!instance->fw_sync_cache_support)) { + if ((scmd->cmnd[0] == SYNCHRONIZE_CACHE) && + MEGASAS_IS_LOGICAL(scmd->device) && + (!instance->fw_sync_cache_support)) { scmd->result = DID_OK << 16; goto out_done; } @@ -1758,7 +1759,7 @@ void megasas_update_sdev_properties(struct scsi_device *sdev) if (!fusion) return; - if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && + if (!MEGASAS_IS_LOGICAL(sdev) && instance->use_seqnum_jbod_fp) { pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id; @@ -1826,8 +1827,7 @@ static int megasas_slave_configure(struct scsi_device *sdev) instance = megasas_lookup_instance(sdev->host->host_no); if (instance->pd_list_not_supported) { - if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && - sdev->type == TYPE_DISK) { + if (!MEGASAS_IS_LOGICAL(sdev) && sdev->type == TYPE_DISK) { pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id; if (instance->pd_list[pd_index].driveState != @@ -1854,7 +1854,7 @@ static int megasas_slave_alloc(struct scsi_device *sdev) struct MR_PRIV_DEVICE *mr_device_priv_data; instance = megasas_lookup_instance(sdev->host->host_no); - if (sdev->channel < MEGASAS_MAX_PD_CHANNELS) { + if (!MEGASAS_IS_LOGICAL(sdev)) { /* * Open the OS scan to the SYSTEM PD */ diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 24b72c5..675afc9 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3581,13 +3581,13 @@ static u16 megasas_get_tm_devhandle(struct scsi_device *sdev) instance = (struct megasas_instance *)sdev->host->hostdata; fusion = instance->ctrl_context; - if (sdev->channel <
[PATCH v3 02/39] megaraid_sas: cpu select rework.
No functional change. Code refactor. Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 175 1 file changed, 100 insertions(+), 75 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 54728b3..514c306 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1819,6 +1819,73 @@ static void megasas_stream_detect(struct megasas_instance *instance, } /** + * megasas_set_raidflag_cpu_affinity - This function sets the cpu + * affinity (cpu of the controller) and raid_flags in the raid context + * based on IO type. + * + * @praid_context: IO RAID context + * @raid: LD raid map + * @fp_possible: Is fast path possible? + * @is_read: Is read IO? + * + */ +static void +megasas_set_raidflag_cpu_affinity(union RAID_CONTEXT_UNION *praid_context, + struct MR_LD_RAID *raid, bool fp_possible, + u8 is_read) +{ + u8 cpu_sel = MR_RAID_CTX_CPUSEL_0; + struct RAID_CONTEXT_G35 *rctx_g35; + + rctx_g35 = _context->raid_context_g35; + if (fp_possible) { + if (is_read) { + if ((raid->cpuAffinity.pdRead.cpu0) && + (raid->cpuAffinity.pdRead.cpu1)) + cpu_sel = MR_RAID_CTX_CPUSEL_FCFS; + else if (raid->cpuAffinity.pdRead.cpu1) + cpu_sel = MR_RAID_CTX_CPUSEL_1; + } else { + if ((raid->cpuAffinity.pdWrite.cpu0) && + (raid->cpuAffinity.pdWrite.cpu1)) + cpu_sel = MR_RAID_CTX_CPUSEL_FCFS; + else if (raid->cpuAffinity.pdWrite.cpu1) + cpu_sel = MR_RAID_CTX_CPUSEL_1; + /* Fast path cache by pass capable R0/R1 VD */ + if ((raid->level <= 1) && + (raid->capability.fp_cache_bypass_capable)) { + rctx_g35->routing_flags.bits.sld = 1; + rctx_g35->raid_flags = + (MR_RAID_FLAGS_IO_SUB_TYPE_CACHE_BYPASS + << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT); + } + } + } else { + if (is_read) { + if ((raid->cpuAffinity.ldRead.cpu0) && + (raid->cpuAffinity.ldRead.cpu1)) + cpu_sel = MR_RAID_CTX_CPUSEL_FCFS; + else if (raid->cpuAffinity.ldRead.cpu1) + cpu_sel = MR_RAID_CTX_CPUSEL_1; + } else { + if ((raid->cpuAffinity.ldWrite.cpu0) && + (raid->cpuAffinity.ldWrite.cpu1)) + cpu_sel = MR_RAID_CTX_CPUSEL_FCFS; + else if (raid->cpuAffinity.ldWrite.cpu1) + cpu_sel = MR_RAID_CTX_CPUSEL_1; + + if (rctx_g35->stream_detected && + (raid->level == 5) && + (raid->writeMode == MR_RL_WRITE_THROUGH_MODE) && + (cpu_sel == MR_RAID_CTX_CPUSEL_FCFS)) + cpu_sel = MR_RAID_CTX_CPUSEL_0; + } + } + + rctx_g35->routing_flags.bits.cpu_sel = cpu_sel; +} + +/** * megasas_build_ldio_fusion - Prepares IOs to devices * @instance: Adapter soft state * @scp: SCSI command @@ -1832,8 +1899,10 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, struct scsi_cmnd *scp, struct megasas_cmd_fusion *cmd) { - u8 fp_possible; - u32 start_lba_lo, start_lba_hi, device_id, datalength = 0, ld; + bool fp_possible; + u16 ld; + u32 start_lba_lo, start_lba_hi, device_id, datalength = 0; + u32 scsi_buff_len; struct MPI2_RAID_SCSI_IO_REQUEST *io_request; union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; struct IO_REQUEST_INFO io_info; @@ -1842,7 +1911,8 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, u8 *raidLUN; unsigned long spinlock_flags; union RAID_CONTEXT_UNION *praid_context; - struct MR_LD_RAID *raid; + struct MR_LD_RAID *raid = NULL; + struct MR_PRIV_DEVICE *mrdev_priv; device_id = MEGASAS_DEV_INDEX(scp); @@ -1858,7 +1928,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, start_lba_lo = 0; start_lba_hi
[PATCH v3 33/39] megaraid_sas: Bail out the driver load if ld_list_query fails
Error handling: Bail out the driver load if key FW cmds (LD_LIST) are not return successful. Clean up error handling in megasas_init_fw. Signed-off-by: Kashyap DesaiSigned-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_base.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 30e390c..0e7121d 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -5352,7 +5352,7 @@ static int megasas_init_fw(struct megasas_instance *instance) (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list))); if (megasas_get_pd_list(instance) < 0) { dev_err(>pdev->dev, "failed to get PD list\n"); - goto fail_get_pd_list; + goto fail_get_ld_pd_list; } memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); @@ -5388,7 +5388,7 @@ static int megasas_init_fw(struct megasas_instance *instance) if (megasas_ld_list_query(instance, MR_LD_QUERY_TYPE_EXPOSED_TO_HOST)) - megasas_get_ld_list(instance); + goto fail_get_ld_pd_list; /* * Compute the max allowed sectors per IO: The controller info has two @@ -5507,8 +5507,6 @@ static int megasas_init_fw(struct megasas_instance *instance) fail_get_ld_pd_list: instance->instancet->disable_intr(instance); -fail_get_pd_list: - instance->instancet->disable_intr(instance); fail_init_adapter: megasas_destroy_irqs(instance); fail_setup_irqs: @@ -5520,9 +5518,11 @@ static int megasas_init_fw(struct megasas_instance *instance) instance->ctrl_info = NULL; iounmap(instance->reg_set); - fail_ioremap: +fail_ioremap: pci_release_selected_regions(instance->pdev, 1 pdev->dev, "Failed from %s %d\n", + __func__, __LINE__); return -EINVAL; } -- 2.8.3
[PATCH v3 22/39] megaraid_sas: avoid unaligned access in ioctl path
Fix kernel warning for accessing unaligned memory access in driver. Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_base.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index b2da257..5d7aa05 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -7007,7 +7008,8 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw + ioc->sense_off); - if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)), + if (copy_to_user((void __user *)((unsigned long) +get_unaligned((unsigned long *)sense_ptr)), sense, ioc->sense_len)) { dev_err(>pdev->dev, "Failed to copy out to user " "sense data\n"); -- 2.8.3
[PATCH v3 09/39] megaraid_sas: change issue_dcmd to return void from int
With the changes to remove checks for a valid request descriptor, issue_dcmd will now always return DCMD_SUCCESS. This patch changes return type of issue_dcmd to void and change all callers appropriately. Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- Fix in v2 : 1. split patches into two as discussed below http://marc.info/?l=linux-scsi=148638999110404=2 2. issue_dcmd return type changed from int to void. drivers/scsi/megaraid/megaraid_sas.h| 2 +- drivers/scsi/megaraid/megaraid_sas_base.c | 19 +++ drivers/scsi/megaraid/megaraid_sas_fusion.c | 8 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index dff877f..d9049d5 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2297,7 +2297,7 @@ struct megasas_instance_template { u32 (*init_adapter)(struct megasas_instance *); u32 (*build_and_issue_cmd) (struct megasas_instance *, struct scsi_cmnd *); - int (*issue_dcmd)(struct megasas_instance *instance, + void (*issue_dcmd)(struct megasas_instance *instance, struct megasas_cmd *cmd); }; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 80fcdf5..23fb78a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -202,12 +202,12 @@ void megasas_fusion_ocr_wq(struct work_struct *work); static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance, int initial); -int +void megasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd) { instance->instancet->fire_cmd(instance, cmd->frame_phys_addr, 0, instance->reg_set); - return 0; + return; } /** @@ -995,13 +995,14 @@ megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd) frame_hdr->cmd_status = MFI_STAT_INVALID_STATUS; frame_hdr->flags |= cpu_to_le16(MFI_FRAME_DONT_POST_IN_REPLY_QUEUE); - if ((atomic_read(>adprecovery) == MEGASAS_HW_CRITICAL_ERROR) || - (instance->instancet->issue_dcmd(instance, cmd))) { + if (atomic_read(>adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { dev_err(>pdev->dev, "Failed from %s %d\n", __func__, __LINE__); return DCMD_NOT_FIRED; } + instance->instancet->issue_dcmd(instance, cmd); + return wait_and_poll(instance, cmd, instance->requestorId ? MEGASAS_ROUTINE_WAIT_TIME_VF : MFI_IO_TIMEOUT_SECS); } @@ -1023,13 +1024,14 @@ megasas_issue_blocked_cmd(struct megasas_instance *instance, int ret = 0; cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS; - if ((atomic_read(>adprecovery) == MEGASAS_HW_CRITICAL_ERROR) || - (instance->instancet->issue_dcmd(instance, cmd))) { + if (atomic_read(>adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { dev_err(>pdev->dev, "Failed from %s %d\n", __func__, __LINE__); return DCMD_NOT_FIRED; } + instance->instancet->issue_dcmd(instance, cmd); + if (timeout) { ret = wait_event_timeout(instance->int_cmd_wait_q, cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, timeout * HZ); @@ -1087,13 +1089,14 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance, cmd->sync_cmd = 1; cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS; - if ((atomic_read(>adprecovery) == MEGASAS_HW_CRITICAL_ERROR) || - (instance->instancet->issue_dcmd(instance, cmd))) { + if (atomic_read(>adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { dev_err(>pdev->dev, "Failed from %s %d\n", __func__, __LINE__); return DCMD_NOT_FIRED; } + instance->instancet->issue_dcmd(instance, cmd); + if (timeout) { ret = wait_event_timeout(instance->abort_cmd_wait_q, cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, timeout * HZ); diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index b6c5dc5..c38fde0 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1115,7 +1115,7 @@ megasas_get_map_info(struct megasas_instance *instance) int megasas_sync_map_info(struct megasas_instance *instance) { - int ret = 0, i; + int i; struct megasas_cmd *cmd; struct megasas_dcmd_frame *dcmd;
[PATCH v3 04/39] megaraid_sas: 32 bit descriptor fire cmd optimization
No functional change. Code refactor. megasas_fire_cmd_fusion can always use 32 bit descriptor write for ventura. No need to pass extra flag. Only IOC INIT required 64 bit Descriptor write. Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Tomas Henzl Reviewed-by: Hannes Reinecke --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 65 +++-- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 7516589..24b72c5 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -188,40 +188,35 @@ inline void megasas_return_cmd_fusion(struct megasas_instance *instance, /** * megasas_fire_cmd_fusion - Sends command to the FW + * @instance: Adapter soft state + * @req_desc: 32bit or 64bit Request descriptor + * + * Perform PCI Write. Ventura supports 32 bit Descriptor. + * Prior to Ventura (12G) MR controller supports 64 bit Descriptor. */ + static void megasas_fire_cmd_fusion(struct megasas_instance *instance, - union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc, bool is_32bit) + union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc) { - struct megasas_register_set __iomem *regs = instance->reg_set; - unsigned long flags; - - if (is_32bit) + if (instance->is_ventura) writel(le32_to_cpu(req_desc->u.low), - &(regs)->inbound_single_queue_port); - else if (instance->is_ventura) { + >reg_set->inbound_single_queue_port); + else { +#if defined(writeq) && defined(CONFIG_64BIT) + u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) | + le32_to_cpu(req_desc->u.low)); + + writeq(req_data, >reg_set->inbound_low_queue_port); +#else + unsigned long flags; spin_lock_irqsave(>hba_lock, flags); writel(le32_to_cpu(req_desc->u.low), - &(regs)->inbound_low_queue_port); + >reg_set->inbound_low_queue_port); writel(le32_to_cpu(req_desc->u.high), - &(regs)->inbound_high_queue_port); + >reg_set->inbound_high_queue_port); mmiowb(); spin_unlock_irqrestore(>hba_lock, flags); - } else { -#if defined(writeq) && defined(CONFIG_64BIT) - u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) | - le32_to_cpu(req_desc->u.low)); - - writeq(req_data, >reg_set->inbound_low_queue_port); -#else - - spin_lock_irqsave(>hba_lock, flags); - writel(le32_to_cpu(req_desc->u.low), - >reg_set->inbound_low_queue_port); - writel(le32_to_cpu(req_desc->u.high), - >reg_set->inbound_high_queue_port); - mmiowb(); - spin_unlock_irqrestore(>hba_lock, flags); #endif } } @@ -771,6 +766,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) const char *sys_info; MFI_CAPABILITIES *drv_ops; u32 scratch_pad_2; + unsigned long flags; fusion = instance->ctrl_context; @@ -897,7 +893,14 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) break; } - megasas_fire_cmd_fusion(instance, _desc, false); + /* For Ventura also IOC INIT required 64 bit Descriptor write. */ + spin_lock_irqsave(>hba_lock, flags); + writel(le32_to_cpu(req_desc.u.low), + >reg_set->inbound_low_queue_port); + writel(le32_to_cpu(req_desc.u.high), + >reg_set->inbound_high_queue_port); + mmiowb(); + spin_unlock_irqrestore(>hba_lock, flags); wait_and_poll(instance, cmd, MFI_POLL_TIMEOUT_SECS); @@ -2577,11 +2580,10 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance, * Issue the command to the FW */ - megasas_fire_cmd_fusion(instance, req_desc, instance->is_ventura); + megasas_fire_cmd_fusion(instance, req_desc); if (r1_cmd) - megasas_fire_cmd_fusion(instance, r1_cmd->request_desc, - instance->is_ventura); + megasas_fire_cmd_fusion(instance, r1_cmd->request_desc); return 0; @@ -3001,7 +3003,7 @@ megasas_issue_dcmd_fusion(struct megasas_instance *instance, return DCMD_NOT_FIRED; } - megasas_fire_cmd_fusion(instance, req_desc, instance->is_ventura); + megasas_fire_cmd_fusion(instance, req_desc); return DCMD_SUCCESS; } @@ -3294,8 +3296,7 @@ void megasas_refire_mgmt_cmd(struct megasas_instance *instance)
[PATCH v3 14/39] megaraid_sas: set residual bytes count during IO completion
Fixing issue of not setting residual bytes correctly. Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index edbecc5..4628671 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1445,6 +1445,7 @@ map_cmd_status(struct fusion_context *fusion, struct scsi_cmnd *scmd, u8 status, u8 ext_status, u32 data_length, u8 *sense) { + int resid; switch (status) { @@ -1467,6 +1468,15 @@ map_cmd_status(struct fusion_context *fusion, SCSI_SENSE_BUFFERSIZE); scmd->result |= DRIVER_SENSE << 24; } + + /* +* If the IO request is partially completed, then MR FW will +* update "io_request->DataLength" field with actual number of +* bytes transferred.Driver will set residual bytes count in +* SCSI command structure. +*/ + resid = (scsi_bufflen(scmd) - data_length); + scsi_set_resid(scmd, resid); break; case MFI_STAT_LD_OFFLINE: -- 2.8.3
[PATCH v3 07/39] megaraid_sas: Use DID_REQUEUE
Moving to use DID_REQUEUE return type for reliable unconditional retries. Driver wants unconditional re-queue, so replace DID_RESET with DID_REQUEUE Discussed below - https://www.spinics.net/lists/linux-scsi/msg102848.html Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_base.c | 4 ++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 67a205a..80fcdf5 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1668,7 +1668,7 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) /* Check for an mpio path and adjust behavior */ if (atomic_read(>adprecovery) == MEGASAS_ADPRESET_SM_INFAULT) { if (megasas_check_mpio_paths(instance, scmd) == - (DID_RESET << 16)) { + (DID_REQUEUE << 16)) { return SCSI_MLQUEUE_HOST_BUSY; } else { scmd->result = DID_NO_CONNECT << 16; @@ -2492,7 +2492,7 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance) struct megasas_cmd, list); list_del_init(_cmd->list); if (reset_cmd->scmd) { - reset_cmd->scmd->result = DID_RESET << 16; + reset_cmd->scmd->result = DID_REQUEUE << 16; dev_notice(>pdev->dev, "%d:%p reset [%02x]\n", reset_index, reset_cmd, reset_cmd->scmd->cmnd[0]); diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 675afc9..6ec7a18 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3770,7 +3770,7 @@ int megasas_check_mpio_paths(struct megasas_instance *instance, struct scsi_cmnd *scmd) { struct megasas_instance *peer_instance = NULL; - int retval = (DID_RESET << 16); + int retval = (DID_REQUEUE << 16); if (instance->peerIsPresent) { peer_instance = megasas_get_peer_instance(instance); -- 2.8.3
[PATCH v3 26/39] megaraid_sas: update can_queue only if the new value is less
Minor Optimization: No need to update HBA can_queue value if the current max FW commands is equal to earlier value. Signed-off-by: Kashyap DesaiSigned-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 2d6d979..94b7a68 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -259,7 +259,7 @@ megasas_fusion_update_can_queue(struct megasas_instance *instance, int fw_boot_c if (fw_boot_context == OCR_CONTEXT) { cur_max_fw_cmds = cur_max_fw_cmds - 1; - if (cur_max_fw_cmds <= instance->max_fw_cmds) { + if (cur_max_fw_cmds < instance->max_fw_cmds) { instance->cur_can_queue = cur_max_fw_cmds - (MEGASAS_FUSION_INTERNAL_CMDS + MEGASAS_FUSION_IOCTL_CMDS); -- 2.8.3
[PATCH v3 29/39] megaraid_sas: Remove unused pd_index from megasas_build_ld_nonrw_fusion
Signed-off-by: Kashyap DesaiSigned-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 74cefae..a9b66ce 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -2480,7 +2480,7 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, { u32 device_id; struct MPI2_RAID_SCSI_IO_REQUEST *io_request; - u16 pd_index = 0, ld; + u16 ld; struct MR_DRV_RAID_MAP_ALL *local_map_ptr; struct fusion_context *fusion = instance->ctrl_context; u8 span, physArm; @@ -2492,7 +2492,6 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, io_request = cmd->io_request; device_id = MEGASAS_DEV_INDEX(scmd); - pd_index = MEGASAS_PD_INDEX(scmd); local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)]; io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd)); /* get RAID_Context pointer */ -- 2.8.3
[PATCH v3 06/39] megaraid_sas: RAID map is accessed for SYS PDs when use_seqnum_jbod_fp is not set
Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_base.c | 25 ++--- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 6ca49ef..67a205a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1756,28 +1756,31 @@ void megasas_update_sdev_properties(struct scsi_device *sdev) fusion = instance->ctrl_context; mr_device_priv_data = sdev->hostdata; - if (!fusion) + if (!fusion || !mr_device_priv_data) return; - if (!MEGASAS_IS_LOGICAL(sdev) && - instance->use_seqnum_jbod_fp) { - pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + - sdev->id; - pd_sync = (void *)fusion->pd_seq_sync - [(instance->pd_seq_map_id - 1) & 1]; - mr_device_priv_data->is_tm_capable = - pd_sync->seq[pd_index].capability.tmCapable; - } else { + if (MEGASAS_IS_LOGICAL(sdev)) { device_id = ((sdev->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id; local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)]; ld = MR_TargetIdToLdGet(device_id, local_map_ptr); + if (ld >= instance->fw_supported_vd_count) + return; raid = MR_LdRaidGet(ld, local_map_ptr); if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER) - blk_queue_update_dma_alignment(sdev->request_queue, 0x7); + blk_queue_update_dma_alignment(sdev->request_queue, + 0x7); + mr_device_priv_data->is_tm_capable = raid->capability.tmCapable; + } else if (instance->use_seqnum_jbod_fp) { + pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + + sdev->id; + pd_sync = (void *)fusion->pd_seq_sync + [(instance->pd_seq_map_id - 1) & 1]; + mr_device_priv_data->is_tm_capable = + pd_sync->seq[pd_index].capability.tmCapable; } } -- 2.8.3
[PATCH v3 28/39] megaraid_sas: megasas_return_cmd does not memset IO frame to zero
Memset the IO frame to zero after release. Signed-off-by: Kashyap DesaiSigned-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h | 1 + drivers/scsi/megaraid/megaraid_sas_base.c | 10 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index efc01a3..508516d 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2238,6 +2238,7 @@ struct megasas_instance { u8 is_rdpq; bool dev_handle; bool fw_sync_cache_support; + u32 mfi_frame_size; bool is_ventura; bool msix_combined; u16 max_raid_mapsize; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 06001b4..30e390c 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -268,6 +268,8 @@ megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) cmd->scmd = NULL; cmd->frame_count = 0; cmd->flags = 0; + memset(cmd->frame, 0, instance->mfi_frame_size); + cmd->frame->io.context = cpu_to_le32(cmd->index); if (!fusion && reset_devices) cmd->frame->hdr.cmd = MFI_CMD_INVALID; list_add(>list, (>cmd_pool)->next); @@ -3889,7 +3891,6 @@ static int megasas_create_frame_pool(struct megasas_instance *instance) int i; u16 max_cmd; u32 sge_sz; - u32 total_sz; u32 frame_count; struct megasas_cmd *cmd; @@ -3917,12 +3918,13 @@ static int megasas_create_frame_pool(struct megasas_instance *instance) * Total 192 byte (3 MFI frame of 64 byte) */ frame_count = instance->ctrl_context ? (3 + 1) : (15 + 1); - total_sz = MEGAMFI_FRAME_SIZE * frame_count; + instance->mfi_frame_size = MEGAMFI_FRAME_SIZE * frame_count; /* * Use DMA pool facility provided by PCI layer */ instance->frame_dma_pool = pci_pool_create("megasas frame pool", - instance->pdev, total_sz, 256, 0); + instance->pdev, instance->mfi_frame_size, + 256, 0); if (!instance->frame_dma_pool) { dev_printk(KERN_DEBUG, >pdev->dev, "failed to setup frame pool\n"); @@ -3966,7 +3968,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance) return -ENOMEM; } - memset(cmd->frame, 0, total_sz); + memset(cmd->frame, 0, instance->mfi_frame_size); cmd->frame->io.context = cpu_to_le32(cmd->index); cmd->frame->io.pad_0 = 0; if (!instance->ctrl_context && reset_devices) -- 2.8.3
[PATCH v3 12/39] megaraid_sas: NVME fast path io support
This patch provide true fast path IO support. Driver creates PRP for NVME drives and send Fast Path for performance. Certain h/w requirement needs to be taken care in driver. Signed-off-by: Shivasharan SSigned-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 10 +- drivers/scsi/megaraid/megaraid_sas_fp.c | 55 +++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 316 ++-- drivers/scsi/megaraid/megaraid_sas_fusion.h | 14 +- 4 files changed, 350 insertions(+), 45 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index a45ff10..075e2e9 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2172,6 +2172,11 @@ struct megasas_instance { atomic_t fw_outstanding; atomic_t ldio_outstanding; atomic_t fw_reset_no_pci_access; + atomic_t ieee_sgl; + atomic_t prp_sgl; + atomic_t sge_holes_type1; + atomic_t sge_holes_type2; + atomic_t sge_holes_type3; struct megasas_instance_template *instancet; struct tasklet_struct isr_tasklet; @@ -2443,7 +2448,9 @@ __le16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map); u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map); __le16 get_updated_dev_handle(struct megasas_instance *instance, - struct LD_LOAD_BALANCE_INFO *lbInfo, struct IO_REQUEST_INFO *in_info); + struct LD_LOAD_BALANCE_INFO *lbInfo, + struct IO_REQUEST_INFO *in_info, + struct MR_DRV_RAID_MAP_ALL *drv_map); void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *map, struct LD_LOAD_BALANCE_INFO *lbInfo); int megasas_get_ctrl_info(struct megasas_instance *instance); @@ -2472,4 +2479,5 @@ void megasas_update_sdev_properties(struct scsi_device *sdev); int megasas_reset_fusion(struct Scsi_Host *shost, int reason); int megasas_task_abort_fusion(struct scsi_cmnd *scmd); int megasas_reset_target_fusion(struct scsi_cmnd *scmd); +u32 mega_mod64(u64 dividend, u32 divisor); #endif /*LSI_MEGARAID_SAS_H */ diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index 24258af..c3ef82d 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -155,6 +155,11 @@ __le16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map) return map->raidMap.devHndlInfo[pd].curDevHdl; } +static u8 MR_PdInterfaceTypeGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map) +{ + return map->raidMap.devHndlInfo[pd].interfaceType; +} + u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map) { return le16_to_cpu(map->raidMap.ldSpanMap[ld].ldRaid.targetId); @@ -929,6 +934,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, u8 retval = TRUE; u64 *pdBlock = _info->pdBlock; __le16 *pDevHandle = _info->devHandle; + u8 *pPdInterface = _info->pd_interface; u32 logArm, rowMod, armQ, arm; struct fusion_context *fusion; @@ -960,15 +966,18 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, if (pd != MR_PD_INVALID) { *pDevHandle = MR_PdDevHandleGet(pd, map); + *pPdInterface = MR_PdInterfaceTypeGet(pd, map); /* get second pd also for raid 1/10 fast path writes*/ - if (raid->level == 1) { + if (instance->is_ventura && + (raid->level == 1) && + !io_info->isRead) { r1_alt_pd = MR_ArPdGet(arRef, physArm + 1, map); if (r1_alt_pd != MR_PD_INVALID) io_info->r1_alt_dev_handle = MR_PdDevHandleGet(r1_alt_pd, map); } } else { - *pDevHandle = cpu_to_le16(MR_PD_INVALID); + *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID); if ((raid->level >= 5) && ((fusion->adapter_type == THUNDERBOLT_SERIES) || ((fusion->adapter_type == INVADER_SERIES) && @@ -977,8 +986,10 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, else if (raid->level == 1) { physArm = physArm + 1; pd = MR_ArPdGet(arRef, physArm, map); - if (pd != MR_PD_INVALID) + if (pd != MR_PD_INVALID) { *pDevHandle = MR_PdDevHandleGet(pd, map); + *pPdInterface = MR_PdInterfaceTypeGet(pd, map); + }