Commit 33203bc4 authored by Shivasharan S's avatar Shivasharan S Committed by Martin K. Petersen

scsi: 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: default avatarShivasharan S <shivasharan.srikanteshwara@broadcom.com>
Signed-off-by: default avatarKashyap Desai <kashyap.desai@broadcom.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Reviewed-by: default avatarTomas Henzl <thenzl@redhat.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 96188a89
...@@ -2172,6 +2172,11 @@ struct megasas_instance { ...@@ -2172,6 +2172,11 @@ struct megasas_instance {
atomic_t fw_outstanding; atomic_t fw_outstanding;
atomic_t ldio_outstanding; atomic_t ldio_outstanding;
atomic_t fw_reset_no_pci_access; 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 megasas_instance_template *instancet;
struct tasklet_struct isr_tasklet; struct tasklet_struct isr_tasklet;
...@@ -2443,7 +2448,9 @@ __le16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map); ...@@ -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); u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map);
__le16 get_updated_dev_handle(struct megasas_instance *instance, __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, void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *map,
struct LD_LOAD_BALANCE_INFO *lbInfo); struct LD_LOAD_BALANCE_INFO *lbInfo);
int megasas_get_ctrl_info(struct megasas_instance *instance); int megasas_get_ctrl_info(struct megasas_instance *instance);
...@@ -2472,4 +2479,5 @@ void megasas_update_sdev_properties(struct scsi_device *sdev); ...@@ -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_reset_fusion(struct Scsi_Host *shost, int reason);
int megasas_task_abort_fusion(struct scsi_cmnd *scmd); int megasas_task_abort_fusion(struct scsi_cmnd *scmd);
int megasas_reset_target_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 */ #endif /*LSI_MEGARAID_SAS_H */
...@@ -155,6 +155,11 @@ __le16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map) ...@@ -155,6 +155,11 @@ __le16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map)
return map->raidMap.devHndlInfo[pd].curDevHdl; 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) u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map)
{ {
return le16_to_cpu(map->raidMap.ldSpanMap[ld].ldRaid.targetId); 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, ...@@ -929,6 +934,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
u8 retval = TRUE; u8 retval = TRUE;
u64 *pdBlock = &io_info->pdBlock; u64 *pdBlock = &io_info->pdBlock;
__le16 *pDevHandle = &io_info->devHandle; __le16 *pDevHandle = &io_info->devHandle;
u8 *pPdInterface = &io_info->pd_interface;
u32 logArm, rowMod, armQ, arm; u32 logArm, rowMod, armQ, arm;
struct fusion_context *fusion; struct fusion_context *fusion;
...@@ -960,15 +966,18 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, ...@@ -960,15 +966,18 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
if (pd != MR_PD_INVALID) { if (pd != MR_PD_INVALID) {
*pDevHandle = MR_PdDevHandleGet(pd, map); *pDevHandle = MR_PdDevHandleGet(pd, map);
*pPdInterface = MR_PdInterfaceTypeGet(pd, map);
/* get second pd also for raid 1/10 fast path writes*/ /* 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); r1_alt_pd = MR_ArPdGet(arRef, physArm + 1, map);
if (r1_alt_pd != MR_PD_INVALID) if (r1_alt_pd != MR_PD_INVALID)
io_info->r1_alt_dev_handle = io_info->r1_alt_dev_handle =
MR_PdDevHandleGet(r1_alt_pd, map); MR_PdDevHandleGet(r1_alt_pd, map);
} }
} else { } else {
*pDevHandle = cpu_to_le16(MR_PD_INVALID); *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID);
if ((raid->level >= 5) && if ((raid->level >= 5) &&
((fusion->adapter_type == THUNDERBOLT_SERIES) || ((fusion->adapter_type == THUNDERBOLT_SERIES) ||
((fusion->adapter_type == INVADER_SERIES) && ((fusion->adapter_type == INVADER_SERIES) &&
...@@ -977,8 +986,10 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, ...@@ -977,8 +986,10 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
else if (raid->level == 1) { else if (raid->level == 1) {
physArm = physArm + 1; physArm = physArm + 1;
pd = MR_ArPdGet(arRef, physArm, map); pd = MR_ArPdGet(arRef, physArm, map);
if (pd != MR_PD_INVALID) if (pd != MR_PD_INVALID) {
*pDevHandle = MR_PdDevHandleGet(pd, map); *pDevHandle = MR_PdDevHandleGet(pd, map);
*pPdInterface = MR_PdInterfaceTypeGet(pd, map);
}
} }
} }
...@@ -1025,6 +1036,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, ...@@ -1025,6 +1036,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
u8 retval = TRUE; u8 retval = TRUE;
u64 *pdBlock = &io_info->pdBlock; u64 *pdBlock = &io_info->pdBlock;
__le16 *pDevHandle = &io_info->devHandle; __le16 *pDevHandle = &io_info->devHandle;
u8 *pPdInterface = &io_info->pd_interface;
struct fusion_context *fusion; struct fusion_context *fusion;
fusion = instance->ctrl_context; fusion = instance->ctrl_context;
...@@ -1070,16 +1082,19 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, ...@@ -1070,16 +1082,19 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
if (pd != MR_PD_INVALID) { if (pd != MR_PD_INVALID) {
/* Get dev handle from Pd. */ /* Get dev handle from Pd. */
*pDevHandle = MR_PdDevHandleGet(pd, map); *pDevHandle = MR_PdDevHandleGet(pd, map);
*pPdInterface = MR_PdInterfaceTypeGet(pd, map);
/* get second pd also for raid 1/10 fast path writes*/ /* 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); r1_alt_pd = MR_ArPdGet(arRef, physArm + 1, map);
if (r1_alt_pd != MR_PD_INVALID) if (r1_alt_pd != MR_PD_INVALID)
io_info->r1_alt_dev_handle = io_info->r1_alt_dev_handle =
MR_PdDevHandleGet(r1_alt_pd, map); MR_PdDevHandleGet(r1_alt_pd, map);
} }
} else { } else {
/* set dev handle as invalid. */ /* set dev handle as invalid. */
*pDevHandle = cpu_to_le16(MR_PD_INVALID); *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID);
if ((raid->level >= 5) && if ((raid->level >= 5) &&
((fusion->adapter_type == THUNDERBOLT_SERIES) || ((fusion->adapter_type == THUNDERBOLT_SERIES) ||
((fusion->adapter_type == INVADER_SERIES) && ((fusion->adapter_type == INVADER_SERIES) &&
...@@ -1089,9 +1104,11 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, ...@@ -1089,9 +1104,11 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
/* Get alternate Pd. */ /* Get alternate Pd. */
physArm = physArm + 1; physArm = physArm + 1;
pd = MR_ArPdGet(arRef, physArm, map); pd = MR_ArPdGet(arRef, physArm, map);
if (pd != MR_PD_INVALID) if (pd != MR_PD_INVALID) {
/* Get dev handle from Pd */ /* Get dev handle from Pd */
*pDevHandle = MR_PdDevHandleGet(pd, map); *pDevHandle = MR_PdDevHandleGet(pd, map);
*pPdInterface = MR_PdInterfaceTypeGet(pd, map);
}
} }
} }
...@@ -1509,11 +1526,11 @@ void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *drv_map, ...@@ -1509,11 +1526,11 @@ void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *drv_map,
} }
u8 megasas_get_best_arm_pd(struct megasas_instance *instance, u8 megasas_get_best_arm_pd(struct megasas_instance *instance,
struct LD_LOAD_BALANCE_INFO *lbInfo, struct IO_REQUEST_INFO *io_info) struct LD_LOAD_BALANCE_INFO *lbInfo,
struct IO_REQUEST_INFO *io_info,
struct MR_DRV_RAID_MAP_ALL *drv_map)
{ {
struct fusion_context *fusion;
struct MR_LD_RAID *raid; struct MR_LD_RAID *raid;
struct MR_DRV_RAID_MAP_ALL *drv_map;
u16 pd1_dev_handle; u16 pd1_dev_handle;
u16 pend0, pend1, ld; u16 pend0, pend1, ld;
u64 diff0, diff1; u64 diff0, diff1;
...@@ -1527,9 +1544,6 @@ u8 megasas_get_best_arm_pd(struct megasas_instance *instance, ...@@ -1527,9 +1544,6 @@ u8 megasas_get_best_arm_pd(struct megasas_instance *instance,
>> RAID_CTX_SPANARM_SPAN_SHIFT); >> RAID_CTX_SPANARM_SPAN_SHIFT);
arm = (io_info->span_arm & RAID_CTX_SPANARM_ARM_MASK); arm = (io_info->span_arm & RAID_CTX_SPANARM_ARM_MASK);
fusion = instance->ctrl_context;
drv_map = fusion->ld_drv_map[(instance->map_id & 1)];
ld = MR_TargetIdToLdGet(io_info->ldTgtId, drv_map); ld = MR_TargetIdToLdGet(io_info->ldTgtId, drv_map);
raid = MR_LdRaidGet(ld, drv_map); raid = MR_LdRaidGet(ld, drv_map);
span_row_size = instance->UnevenSpanSupport ? span_row_size = instance->UnevenSpanSupport ?
...@@ -1544,7 +1558,7 @@ u8 megasas_get_best_arm_pd(struct megasas_instance *instance, ...@@ -1544,7 +1558,7 @@ u8 megasas_get_best_arm_pd(struct megasas_instance *instance,
pd1_dev_handle = MR_PdDevHandleGet(pd1, drv_map); pd1_dev_handle = MR_PdDevHandleGet(pd1, drv_map);
if (pd1_dev_handle == MR_PD_INVALID) { if (pd1_dev_handle == MR_DEVHANDLE_INVALID) {
bestArm = arm; bestArm = arm;
} else { } else {
/* get the pending cmds for the data and mirror arms */ /* get the pending cmds for the data and mirror arms */
...@@ -1581,19 +1595,18 @@ u8 megasas_get_best_arm_pd(struct megasas_instance *instance, ...@@ -1581,19 +1595,18 @@ u8 megasas_get_best_arm_pd(struct megasas_instance *instance,
} }
__le16 get_updated_dev_handle(struct megasas_instance *instance, __le16 get_updated_dev_handle(struct megasas_instance *instance,
struct LD_LOAD_BALANCE_INFO *lbInfo, struct IO_REQUEST_INFO *io_info) struct LD_LOAD_BALANCE_INFO *lbInfo,
struct IO_REQUEST_INFO *io_info,
struct MR_DRV_RAID_MAP_ALL *drv_map)
{ {
u8 arm_pd; u8 arm_pd;
__le16 devHandle; __le16 devHandle;
struct fusion_context *fusion;
struct MR_DRV_RAID_MAP_ALL *drv_map;
fusion = instance->ctrl_context;
drv_map = fusion->ld_drv_map[(instance->map_id & 1)];
/* get best new arm (PD ID) */ /* get best new arm (PD ID) */
arm_pd = megasas_get_best_arm_pd(instance, lbInfo, io_info); arm_pd = megasas_get_best_arm_pd(instance, lbInfo, io_info, drv_map);
devHandle = MR_PdDevHandleGet(arm_pd, drv_map); devHandle = MR_PdDevHandleGet(arm_pd, drv_map);
io_info->pd_interface = MR_PdInterfaceTypeGet(arm_pd, drv_map);
atomic_inc(&lbInfo->scsi_pending_cmds[arm_pd]); atomic_inc(&lbInfo->scsi_pending_cmds[arm_pd]);
return devHandle; return devHandle;
} }
This diff is collapsed.
...@@ -702,7 +702,7 @@ struct MPI2_IOC_INIT_REQUEST { ...@@ -702,7 +702,7 @@ struct MPI2_IOC_INIT_REQUEST {
struct MR_DEV_HANDLE_INFO { struct MR_DEV_HANDLE_INFO {
__le16 curDevHdl; __le16 curDevHdl;
u8 validHandles; u8 validHandles;
u8 reserved; u8 interfaceType;
__le16 devHandle[2]; __le16 devHandle[2];
}; };
...@@ -914,6 +914,7 @@ struct IO_REQUEST_INFO { ...@@ -914,6 +914,7 @@ struct IO_REQUEST_INFO {
u16 ldTgtId; u16 ldTgtId;
u8 isRead; u8 isRead;
__le16 devHandle; __le16 devHandle;
u8 pd_interface;
u64 pdBlock; u64 pdBlock;
u8 fpOkForIo; u8 fpOkForIo;
u8 IoforUnevenSpan; u8 IoforUnevenSpan;
...@@ -1025,6 +1026,16 @@ struct MR_FW_RAID_MAP_DYNAMIC { ...@@ -1025,6 +1026,16 @@ struct MR_FW_RAID_MAP_DYNAMIC {
#define IEEE_SGE_FLAGS_CHAIN_ELEMENT (0x80) #define IEEE_SGE_FLAGS_CHAIN_ELEMENT (0x80)
#define IEEE_SGE_FLAGS_END_OF_LIST (0x40) #define IEEE_SGE_FLAGS_END_OF_LIST (0x40)
#define MPI2_SGE_FLAGS_SHIFT (0x02)
#define IEEE_SGE_FLAGS_FORMAT_MASK (0xC0)
#define IEEE_SGE_FLAGS_FORMAT_IEEE (0x00)
#define IEEE_SGE_FLAGS_FORMAT_NVME (0x02)
#define MPI26_IEEE_SGE_FLAGS_NSF_MASK (0x1C)
#define MPI26_IEEE_SGE_FLAGS_NSF_MPI_IEEE (0x00)
#define MPI26_IEEE_SGE_FLAGS_NSF_NVME_PRP (0x08)
#define MPI26_IEEE_SGE_FLAGS_NSF_NVME_SGL (0x10)
struct megasas_register_set; struct megasas_register_set;
struct megasas_instance; struct megasas_instance;
...@@ -1061,6 +1072,7 @@ struct megasas_cmd_fusion { ...@@ -1061,6 +1072,7 @@ struct megasas_cmd_fusion {
u32 index; u32 index;
u8 pd_r1_lb; u8 pd_r1_lb;
struct completion done; struct completion done;
u8 pd_interface;
u16 r1_alt_dev_handle; /* raid 1/10 only*/ u16 r1_alt_dev_handle; /* raid 1/10 only*/
bool cmd_completed; /* raid 1/10 fp writes status holder */ bool cmd_completed; /* raid 1/10 fp writes status holder */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment