scsi: 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 S <shivasharan.srikanteshwara@broadcom.com> Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Reviewed-by: Tomas Henzl <thenzl@redhat.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
f6c0d55c5b
commit
8bf7c65d37
drivers/scsi/megaraid
|
@ -1338,20 +1338,8 @@ MR_BuildRaidContext(struct megasas_instance *instance,
|
||||||
ref_in_start_stripe, io_info,
|
ref_in_start_stripe, io_info,
|
||||||
pRAID_Context, map);
|
pRAID_Context, map);
|
||||||
/* If IO on an invalid Pd, then FP is not possible.*/
|
/* 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;
|
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;
|
return retval;
|
||||||
} else if (isRead) {
|
} else if (isRead) {
|
||||||
uint stripIdx;
|
uint stripIdx;
|
||||||
|
|
|
@ -181,7 +181,9 @@ inline void megasas_return_cmd_fusion(struct megasas_instance *instance,
|
||||||
struct megasas_cmd_fusion *cmd)
|
struct megasas_cmd_fusion *cmd)
|
||||||
{
|
{
|
||||||
cmd->scmd = NULL;
|
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,
|
memset(cmd->io_request, 0,
|
||||||
sizeof(struct MPI2_RAID_SCSI_IO_REQUEST));
|
sizeof(struct MPI2_RAID_SCSI_IO_REQUEST));
|
||||||
cmd->io_request_phys_addr = io_req_base_phys + offset;
|
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))
|
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.ldStartBlock = ((u64)start_lba_hi << 32) | start_lba_lo;
|
||||||
io_info.numBlocks = datalength;
|
io_info.numBlocks = datalength;
|
||||||
io_info.ldTgtId = device_id;
|
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);
|
scsi_buff_len = scsi_bufflen(scp);
|
||||||
io_request->DataLength = cpu_to_le32(scsi_buff_len);
|
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)
|
io_info.isRead && io_info.ra_capable)
|
||||||
fp_possible = false;
|
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;
|
mrdev_priv = scp->device->hostdata;
|
||||||
|
|
||||||
if (atomic_inc_return(&instance->fw_outstanding) >
|
if (atomic_inc_return(&instance->fw_outstanding) >
|
||||||
|
@ -2090,9 +2092,10 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
|
||||||
} else
|
} else
|
||||||
scp->SCp.Status &= ~MEGASAS_LOAD_BALANCE_FLAG;
|
scp->SCp.Status &= ~MEGASAS_LOAD_BALANCE_FLAG;
|
||||||
|
|
||||||
cmd->is_raid_1_fp_write = io_info.is_raid_1_fp_write;
|
if (instance->is_ventura)
|
||||||
if (io_info.is_raid_1_fp_write)
|
|
||||||
cmd->r1_alt_dev_handle = io_info.r1_alt_dev_handle;
|
cmd->r1_alt_dev_handle = io_info.r1_alt_dev_handle;
|
||||||
|
else
|
||||||
|
cmd->r1_alt_dev_handle = MR_DEVHANDLE_INVALID;
|
||||||
|
|
||||||
if ((raidLUN[0] == 1) &&
|
if ((raidLUN[0] == 1) &&
|
||||||
(local_map_ptr->raidMap.devHndlInfo[io_info.pd_after_lb].validHandles > 1)) {
|
(local_map_ptr->raidMap.devHndlInfo[io_info.pd_after_lb].validHandles > 1)) {
|
||||||
|
@ -2451,72 +2454,6 @@ megasas_get_request_descriptor(struct megasas_instance *instance, u16 index)
|
||||||
return (union MEGASAS_REQUEST_DESCRIPTOR_UNION *)p;
|
return (union MEGASAS_REQUEST_DESCRIPTOR_UNION *)p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* megasas_fpio_to_ldio-
|
|
||||||
* This function converts an fp io to ldio
|
|
||||||
*/
|
|
||||||
|
|
||||||
void megasas_fpio_to_ldio(struct megasas_instance *instance,
|
|
||||||
struct megasas_cmd_fusion *cmd, struct scsi_cmnd *scmd)
|
|
||||||
{
|
|
||||||
struct fusion_context *fusion;
|
|
||||||
union RAID_CONTEXT_UNION *praid_context;
|
|
||||||
struct MR_LD_RAID *raid;
|
|
||||||
struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
|
|
||||||
u32 device_id, ld;
|
|
||||||
|
|
||||||
fusion = instance->ctrl_context;
|
|
||||||
cmd->request_desc->SCSIIO.RequestFlags =
|
|
||||||
(MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO
|
|
||||||
<< MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
|
|
||||||
cmd->io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
|
|
||||||
cmd->io_request->DevHandle = cpu_to_le16(MEGASAS_DEV_INDEX(scmd));
|
|
||||||
|
|
||||||
/*remove FAST PATH ENABLE bit in IoFlags */
|
|
||||||
cmd->io_request->IoFlags &=
|
|
||||||
cpu_to_le16(~MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH);
|
|
||||||
|
|
||||||
/* if the numSGE > max_sge_in_main_sge set the chain offset*/
|
|
||||||
if (cmd->io_request->RaidContext.raid_context_g35.num_sge >
|
|
||||||
fusion->max_sge_in_main_msg)
|
|
||||||
cmd->io_request->ChainOffset = fusion->chain_offset_io_request;
|
|
||||||
memcpy(cmd->io_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len);
|
|
||||||
cmd->io_request->CDB.EEDP32.PrimaryReferenceTag = 0;
|
|
||||||
cmd->io_request->CDB.EEDP32.PrimaryApplicationTagMask = 0;
|
|
||||||
cmd->io_request->EEDPFlags = 0;
|
|
||||||
cmd->io_request->Control = 0;
|
|
||||||
cmd->io_request->EEDPBlockSize = 0;
|
|
||||||
cmd->is_raid_1_fp_write = 0;
|
|
||||||
|
|
||||||
device_id = MEGASAS_DEV_INDEX(cmd->scmd);
|
|
||||||
local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
|
|
||||||
ld = MR_TargetIdToLdGet(device_id, local_map_ptr);
|
|
||||||
raid = MR_LdRaidGet(ld, local_map_ptr);
|
|
||||||
praid_context = &cmd->io_request->RaidContext;
|
|
||||||
if (cmd->scmd->sc_data_direction == PCI_DMA_FROMDEVICE) {
|
|
||||||
if ((raid->cpuAffinity.ldRead.cpu0)
|
|
||||||
&& (raid->cpuAffinity.ldRead.cpu1))
|
|
||||||
praid_context->raid_context_g35.routing_flags.bits.cpu_sel
|
|
||||||
= MR_RAID_CTX_CPUSEL_FCFS;
|
|
||||||
else if (raid->cpuAffinity.ldRead.cpu1)
|
|
||||||
praid_context->raid_context_g35.routing_flags.bits.cpu_sel
|
|
||||||
= MR_RAID_CTX_CPUSEL_1;
|
|
||||||
else
|
|
||||||
praid_context->raid_context_g35.routing_flags.bits.cpu_sel
|
|
||||||
= MR_RAID_CTX_CPUSEL_0;
|
|
||||||
} else {
|
|
||||||
if ((raid->cpuAffinity.ldWrite.cpu0)
|
|
||||||
&& (raid->cpuAffinity.ldWrite.cpu1))
|
|
||||||
praid_context->raid_context_g35.routing_flags.bits.cpu_sel
|
|
||||||
= MR_RAID_CTX_CPUSEL_FCFS;
|
|
||||||
else if (raid->cpuAffinity.ldWrite.cpu1)
|
|
||||||
praid_context->raid_context_g35.routing_flags.bits.cpu_sel
|
|
||||||
= MR_RAID_CTX_CPUSEL_1;
|
|
||||||
else
|
|
||||||
praid_context->raid_context_g35.routing_flags.bits.cpu_sel
|
|
||||||
= MR_RAID_CTX_CPUSEL_0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* megasas_prepate_secondRaid1_IO
|
/* megasas_prepate_secondRaid1_IO
|
||||||
* It prepares the raid 1 second IO
|
* It prepares the raid 1 second IO
|
||||||
|
@ -2527,60 +2464,36 @@ void megasas_prepare_secondRaid1_IO(struct megasas_instance *instance,
|
||||||
{
|
{
|
||||||
union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc, *req_desc2 = NULL;
|
union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc, *req_desc2 = NULL;
|
||||||
struct fusion_context *fusion;
|
struct fusion_context *fusion;
|
||||||
|
|
||||||
fusion = instance->ctrl_context;
|
fusion = instance->ctrl_context;
|
||||||
req_desc = cmd->request_desc;
|
req_desc = cmd->request_desc;
|
||||||
if (r1_cmd) {
|
/* copy the io request frame as well as 8 SGEs data for r1 command*/
|
||||||
/* copy the io request frame as well
|
memcpy(r1_cmd->io_request, cmd->io_request,
|
||||||
* as 8 SGEs data for r1 command
|
(sizeof(struct MPI2_RAID_SCSI_IO_REQUEST)));
|
||||||
*/
|
memcpy(&r1_cmd->io_request->SGL, &cmd->io_request->SGL,
|
||||||
memcpy(r1_cmd->io_request, cmd->io_request,
|
(fusion->max_sge_in_main_msg * sizeof(union MPI2_SGE_IO_UNION)));
|
||||||
sizeof(struct MPI2_RAID_SCSI_IO_REQUEST));
|
/*sense buffer is different for r1 command*/
|
||||||
memcpy(&r1_cmd->io_request->SGL, &cmd->io_request->SGL,
|
r1_cmd->io_request->SenseBufferLowAddress =
|
||||||
(fusion->max_sge_in_main_msg *
|
cpu_to_le32(r1_cmd->sense_phys_addr);
|
||||||
sizeof(union MPI2_SGE_IO_UNION)));
|
r1_cmd->scmd = cmd->scmd;
|
||||||
/*sense buffer is different for r1 command*/
|
req_desc2 = megasas_get_request_descriptor(instance,
|
||||||
r1_cmd->io_request->SenseBufferLowAddress =
|
(r1_cmd->index - 1));
|
||||||
cpu_to_le32(r1_cmd->sense_phys_addr);
|
req_desc2->Words = 0;
|
||||||
r1_cmd->scmd = cmd->scmd;
|
r1_cmd->request_desc = req_desc2;
|
||||||
req_desc2 =
|
req_desc2->SCSIIO.SMID = cpu_to_le16(r1_cmd->index);
|
||||||
megasas_get_request_descriptor(instance, r1_cmd->index-1);
|
req_desc2->SCSIIO.RequestFlags = req_desc->SCSIIO.RequestFlags;
|
||||||
if (req_desc2) {
|
r1_cmd->request_desc->SCSIIO.DevHandle = cmd->r1_alt_dev_handle;
|
||||||
req_desc2->Words = 0;
|
r1_cmd->io_request->DevHandle = cmd->r1_alt_dev_handle;
|
||||||
r1_cmd->request_desc = req_desc2;
|
r1_cmd->r1_alt_dev_handle = cmd->io_request->DevHandle;
|
||||||
req_desc2->SCSIIO.SMID =
|
cmd->io_request->RaidContext.raid_context_g35.smid.peer_smid =
|
||||||
cpu_to_le16(r1_cmd->index);
|
cpu_to_le16(r1_cmd->index);
|
||||||
req_desc2->SCSIIO.RequestFlags =
|
r1_cmd->io_request->RaidContext.raid_context_g35.smid.peer_smid =
|
||||||
req_desc->SCSIIO.RequestFlags;
|
cpu_to_le16(cmd->index);
|
||||||
r1_cmd->is_raid_1_fp_write = 1;
|
/*MSIxIndex of both commands request descriptors should be same*/
|
||||||
r1_cmd->request_desc->SCSIIO.DevHandle =
|
r1_cmd->request_desc->SCSIIO.MSIxIndex =
|
||||||
cmd->r1_alt_dev_handle;
|
cmd->request_desc->SCSIIO.MSIxIndex;
|
||||||
r1_cmd->io_request->DevHandle = cmd->r1_alt_dev_handle;
|
/*span arm is different for r1 cmd*/
|
||||||
cmd->io_request->RaidContext.raid_context_g35.smid.peer_smid =
|
r1_cmd->io_request->RaidContext.raid_context_g35.span_arm =
|
||||||
cpu_to_le16(r1_cmd->index);
|
|
||||||
r1_cmd->io_request->RaidContext.raid_context_g35.smid.peer_smid =
|
|
||||||
cpu_to_le16(cmd->index);
|
|
||||||
/* MSIxIndex of both commands request
|
|
||||||
* descriptors should be same
|
|
||||||
*/
|
|
||||||
r1_cmd->request_desc->SCSIIO.MSIxIndex =
|
|
||||||
cmd->request_desc->SCSIIO.MSIxIndex;
|
|
||||||
/*span arm is different for r1 cmd*/
|
|
||||||
r1_cmd->io_request->RaidContext.raid_context_g35.span_arm =
|
|
||||||
cmd->io_request->RaidContext.raid_context_g35.span_arm + 1;
|
cmd->io_request->RaidContext.raid_context_g35.span_arm + 1;
|
||||||
} else {
|
|
||||||
megasas_return_cmd_fusion(instance, r1_cmd);
|
|
||||||
dev_info(&instance->pdev->dev,
|
|
||||||
"unable to get request descriptor, firing as normal IO\n");
|
|
||||||
atomic_dec(&instance->fw_outstanding);
|
|
||||||
megasas_fpio_to_ldio(instance, cmd, cmd->scmd);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dev_info(&instance->pdev->dev,
|
|
||||||
"unable to get command, firing as normal IO\n");
|
|
||||||
atomic_dec(&instance->fw_outstanding);
|
|
||||||
megasas_fpio_to_ldio(instance, cmd, cmd->scmd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2624,10 +2537,6 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance,
|
||||||
index = cmd->index;
|
index = cmd->index;
|
||||||
|
|
||||||
req_desc = megasas_get_request_descriptor(instance, index-1);
|
req_desc = megasas_get_request_descriptor(instance, index-1);
|
||||||
if (!req_desc) {
|
|
||||||
atomic_dec(&instance->fw_outstanding);
|
|
||||||
return SCSI_MLQUEUE_HOST_BUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
req_desc->Words = 0;
|
req_desc->Words = 0;
|
||||||
cmd->request_desc = req_desc;
|
cmd->request_desc = req_desc;
|
||||||
|
@ -2657,12 +2566,7 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance,
|
||||||
/* driver side count always should be less than max_fw_cmds
|
/* driver side count always should be less than max_fw_cmds
|
||||||
* to get new command
|
* to get new command
|
||||||
*/
|
*/
|
||||||
if (cmd->is_raid_1_fp_write &&
|
if (cmd->r1_alt_dev_handle != MR_DEVHANDLE_INVALID) {
|
||||||
atomic_inc_return(&instance->fw_outstanding) >
|
|
||||||
(instance->host->can_queue)) {
|
|
||||||
megasas_fpio_to_ldio(instance, cmd, cmd->scmd);
|
|
||||||
atomic_dec(&instance->fw_outstanding);
|
|
||||||
} else if (cmd->is_raid_1_fp_write) {
|
|
||||||
r1_cmd = megasas_get_cmd_fusion(instance,
|
r1_cmd = megasas_get_cmd_fusion(instance,
|
||||||
(scmd->request->tag + instance->max_fw_cmds));
|
(scmd->request->tag + instance->max_fw_cmds));
|
||||||
megasas_prepare_secondRaid1_IO(instance, cmd, r1_cmd);
|
megasas_prepare_secondRaid1_IO(instance, cmd, r1_cmd);
|
||||||
|
@ -2683,6 +2587,61 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* megasas_complete_r1_command -
|
||||||
|
* completes R1 FP write commands which has valid peer smid
|
||||||
|
* @instance: Adapter soft state
|
||||||
|
* @cmd_fusion: MPT command frame
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
megasas_complete_r1_command(struct megasas_instance *instance,
|
||||||
|
struct megasas_cmd_fusion *cmd)
|
||||||
|
{
|
||||||
|
u8 *sense, status, ex_status;
|
||||||
|
u32 data_length;
|
||||||
|
u16 peer_smid;
|
||||||
|
struct fusion_context *fusion;
|
||||||
|
struct megasas_cmd_fusion *r1_cmd = NULL;
|
||||||
|
struct scsi_cmnd *scmd_local = NULL;
|
||||||
|
struct RAID_CONTEXT_G35 *rctx_g35;
|
||||||
|
|
||||||
|
rctx_g35 = &cmd->io_request->RaidContext.raid_context_g35;
|
||||||
|
fusion = instance->ctrl_context;
|
||||||
|
peer_smid = le16_to_cpu(rctx_g35->smid.peer_smid);
|
||||||
|
|
||||||
|
r1_cmd = fusion->cmd_list[peer_smid - 1];
|
||||||
|
scmd_local = cmd->scmd;
|
||||||
|
status = rctx_g35->status;
|
||||||
|
ex_status = rctx_g35->ex_status;
|
||||||
|
data_length = cmd->io_request->DataLength;
|
||||||
|
sense = cmd->sense;
|
||||||
|
|
||||||
|
cmd->cmd_completed = true;
|
||||||
|
|
||||||
|
/* Check if peer command is completed or not*/
|
||||||
|
if (r1_cmd->cmd_completed) {
|
||||||
|
rctx_g35 = &r1_cmd->io_request->RaidContext.raid_context_g35;
|
||||||
|
if (rctx_g35->status != MFI_STAT_OK) {
|
||||||
|
status = rctx_g35->status;
|
||||||
|
ex_status = rctx_g35->ex_status;
|
||||||
|
data_length = r1_cmd->io_request->DataLength;
|
||||||
|
sense = r1_cmd->sense;
|
||||||
|
}
|
||||||
|
|
||||||
|
megasas_return_cmd_fusion(instance, r1_cmd);
|
||||||
|
map_cmd_status(fusion, scmd_local, status, ex_status,
|
||||||
|
le32_to_cpu(data_length), sense);
|
||||||
|
if (instance->ldio_threshold &&
|
||||||
|
megasas_cmd_type(scmd_local) == READ_WRITE_LDIO)
|
||||||
|
atomic_dec(&instance->ldio_outstanding);
|
||||||
|
scmd_local->SCp.ptr = NULL;
|
||||||
|
megasas_return_cmd_fusion(instance, cmd);
|
||||||
|
scsi_dma_unmap(scmd_local);
|
||||||
|
scmd_local->scsi_done(scmd_local);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* complete_cmd_fusion - Completes command
|
* complete_cmd_fusion - Completes command
|
||||||
* @instance: Adapter soft state
|
* @instance: Adapter soft state
|
||||||
|
@ -2696,10 +2655,10 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
|
||||||
struct MPI2_RAID_SCSI_IO_REQUEST *scsi_io_req;
|
struct MPI2_RAID_SCSI_IO_REQUEST *scsi_io_req;
|
||||||
struct fusion_context *fusion;
|
struct fusion_context *fusion;
|
||||||
struct megasas_cmd *cmd_mfi;
|
struct megasas_cmd *cmd_mfi;
|
||||||
struct megasas_cmd_fusion *cmd_fusion, *r1_cmd = NULL;
|
struct megasas_cmd_fusion *cmd_fusion;
|
||||||
u16 smid, num_completed;
|
u16 smid, num_completed;
|
||||||
u8 reply_descript_type, *sense;
|
u8 reply_descript_type, *sense, status, extStatus;
|
||||||
u32 status, extStatus, device_id, data_length;
|
u32 device_id, data_length;
|
||||||
union desc_value d_val;
|
union desc_value d_val;
|
||||||
struct LD_LOAD_BALANCE_INFO *lbinfo;
|
struct LD_LOAD_BALANCE_INFO *lbinfo;
|
||||||
int threshold_reply_count = 0;
|
int threshold_reply_count = 0;
|
||||||
|
@ -2729,25 +2688,11 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
|
||||||
|
|
||||||
while (d_val.u.low != cpu_to_le32(UINT_MAX) &&
|
while (d_val.u.low != cpu_to_le32(UINT_MAX) &&
|
||||||
d_val.u.high != cpu_to_le32(UINT_MAX)) {
|
d_val.u.high != cpu_to_le32(UINT_MAX)) {
|
||||||
/*
|
|
||||||
* Ensure that the peer command is NULL here in case a
|
|
||||||
* command has completed but the R1 FP Write peer has
|
|
||||||
* not completed yet.If not null, it's possible that
|
|
||||||
* another thread will complete the peer
|
|
||||||
* command and should not.
|
|
||||||
*/
|
|
||||||
r1_cmd = NULL;
|
|
||||||
|
|
||||||
smid = le16_to_cpu(reply_desc->SMID);
|
smid = le16_to_cpu(reply_desc->SMID);
|
||||||
|
|
||||||
cmd_fusion = fusion->cmd_list[smid - 1];
|
cmd_fusion = fusion->cmd_list[smid - 1];
|
||||||
|
scsi_io_req = (struct MPI2_RAID_SCSI_IO_REQUEST *)
|
||||||
scsi_io_req =
|
cmd_fusion->io_request;
|
||||||
(struct MPI2_RAID_SCSI_IO_REQUEST *)
|
|
||||||
cmd_fusion->io_request;
|
|
||||||
|
|
||||||
if (cmd_fusion->scmd)
|
|
||||||
cmd_fusion->scmd->SCp.ptr = NULL;
|
|
||||||
|
|
||||||
scmd_local = cmd_fusion->scmd;
|
scmd_local = cmd_fusion->scmd;
|
||||||
status = scsi_io_req->RaidContext.raid_context.status;
|
status = scsi_io_req->RaidContext.raid_context.status;
|
||||||
|
@ -2768,88 +2713,33 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
|
||||||
break;
|
break;
|
||||||
case MPI2_FUNCTION_SCSI_IO_REQUEST: /*Fast Path IO.*/
|
case MPI2_FUNCTION_SCSI_IO_REQUEST: /*Fast Path IO.*/
|
||||||
/* Update load balancing info */
|
/* Update load balancing info */
|
||||||
device_id = MEGASAS_DEV_INDEX(scmd_local);
|
if (fusion->load_balance_info &&
|
||||||
lbinfo = &fusion->load_balance_info[device_id];
|
(cmd_fusion->scmd->SCp.Status &
|
||||||
/*
|
MEGASAS_LOAD_BALANCE_FLAG)) {
|
||||||
* check for the raid 1/10 fast path writes
|
device_id = MEGASAS_DEV_INDEX(scmd_local);
|
||||||
*/
|
lbinfo = &fusion->load_balance_info[device_id];
|
||||||
if (!cmd_fusion->is_raid_1_fp_write &&
|
|
||||||
(cmd_fusion->scmd->SCp.Status &
|
|
||||||
MEGASAS_LOAD_BALANCE_FLAG)) {
|
|
||||||
atomic_dec(&lbinfo->scsi_pending_cmds[cmd_fusion->pd_r1_lb]);
|
atomic_dec(&lbinfo->scsi_pending_cmds[cmd_fusion->pd_r1_lb]);
|
||||||
cmd_fusion->scmd->SCp.Status &=
|
cmd_fusion->scmd->SCp.Status &= ~MEGASAS_LOAD_BALANCE_FLAG;
|
||||||
~MEGASAS_LOAD_BALANCE_FLAG;
|
|
||||||
} else if (cmd_fusion->is_raid_1_fp_write) {
|
|
||||||
/* get peer command */
|
|
||||||
if (cmd_fusion->index < instance->max_fw_cmds)
|
|
||||||
r1_cmd = fusion->cmd_list[(cmd_fusion->index +
|
|
||||||
instance->max_fw_cmds)-1];
|
|
||||||
else {
|
|
||||||
r1_cmd =
|
|
||||||
fusion->cmd_list[(cmd_fusion->index -
|
|
||||||
instance->max_fw_cmds)-1];
|
|
||||||
}
|
|
||||||
cmd_fusion->cmd_completed = true;
|
|
||||||
}
|
}
|
||||||
|
//Fall thru and complete IO
|
||||||
if (reply_descript_type ==
|
|
||||||
MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) {
|
|
||||||
if (megasas_dbg_lvl == 5)
|
|
||||||
dev_err(&instance->pdev->dev, "\nFAST Path "
|
|
||||||
"IO Success\n");
|
|
||||||
}
|
|
||||||
/* Fall thru and complete IO */
|
|
||||||
case MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST: /* LD-IO Path */
|
case MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST: /* LD-IO Path */
|
||||||
/* Map the FW Cmd Status */
|
atomic_dec(&instance->fw_outstanding);
|
||||||
/*
|
if (cmd_fusion->r1_alt_dev_handle == MR_DEVHANDLE_INVALID) {
|
||||||
* check for the raid 1/10 fast path writes
|
|
||||||
*/
|
|
||||||
if (r1_cmd && r1_cmd->is_raid_1_fp_write
|
|
||||||
&& r1_cmd->cmd_completed) {
|
|
||||||
/*
|
|
||||||
* if the peer Raid 1/10 fast path failed,
|
|
||||||
* mark IO as failed to the scsi layer.
|
|
||||||
* over write the current status by the failed
|
|
||||||
* status makes sure that if any one of
|
|
||||||
* command fails,return fail status to
|
|
||||||
* scsi layer
|
|
||||||
*/
|
|
||||||
if (r1_cmd->io_request->RaidContext.raid_context.status !=
|
|
||||||
MFI_STAT_OK) {
|
|
||||||
status =
|
|
||||||
r1_cmd->io_request->RaidContext.raid_context.status;
|
|
||||||
extStatus =
|
|
||||||
r1_cmd->io_request->RaidContext.raid_context.ex_status;
|
|
||||||
data_length =
|
|
||||||
r1_cmd->io_request->DataLength;
|
|
||||||
sense = r1_cmd->sense;
|
|
||||||
}
|
|
||||||
r1_cmd->io_request->RaidContext.raid_context.status = 0;
|
|
||||||
r1_cmd->io_request->RaidContext.raid_context.ex_status = 0;
|
|
||||||
cmd_fusion->is_raid_1_fp_write = 0;
|
|
||||||
r1_cmd->is_raid_1_fp_write = 0;
|
|
||||||
r1_cmd->cmd_completed = false;
|
|
||||||
cmd_fusion->cmd_completed = false;
|
|
||||||
megasas_return_cmd_fusion(instance, r1_cmd);
|
|
||||||
}
|
|
||||||
if (!cmd_fusion->is_raid_1_fp_write) {
|
|
||||||
map_cmd_status(fusion, scmd_local, status,
|
map_cmd_status(fusion, scmd_local, status,
|
||||||
extStatus, data_length, sense);
|
extStatus, le32_to_cpu(data_length),
|
||||||
scsi_io_req->RaidContext.raid_context.status = 0;
|
sense);
|
||||||
scsi_io_req->RaidContext.raid_context.ex_status = 0;
|
if (instance->ldio_threshold &&
|
||||||
if (instance->ldio_threshold
|
(megasas_cmd_type(scmd_local) == READ_WRITE_LDIO))
|
||||||
&& megasas_cmd_type(scmd_local) == READ_WRITE_LDIO)
|
|
||||||
atomic_dec(&instance->ldio_outstanding);
|
atomic_dec(&instance->ldio_outstanding);
|
||||||
|
scmd_local->SCp.ptr = NULL;
|
||||||
megasas_return_cmd_fusion(instance, cmd_fusion);
|
megasas_return_cmd_fusion(instance, cmd_fusion);
|
||||||
scsi_dma_unmap(scmd_local);
|
scsi_dma_unmap(scmd_local);
|
||||||
scmd_local->scsi_done(scmd_local);
|
scmd_local->scsi_done(scmd_local);
|
||||||
}
|
} else /* Optimal VD - R1 FP command completion. */
|
||||||
atomic_dec(&instance->fw_outstanding);
|
megasas_complete_r1_command(instance, cmd_fusion);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case MEGASAS_MPI2_FUNCTION_PASSTHRU_IO_REQUEST: /*MFI command */
|
case MEGASAS_MPI2_FUNCTION_PASSTHRU_IO_REQUEST: /*MFI command */
|
||||||
cmd_mfi = instance->cmd_list[cmd_fusion->sync_cmd_idx];
|
cmd_mfi = instance->cmd_list[cmd_fusion->sync_cmd_idx];
|
||||||
|
|
||||||
/* Poll mode. Dummy free.
|
/* Poll mode. Dummy free.
|
||||||
* In case of Interrupt mode, caller has reverse check.
|
* In case of Interrupt mode, caller has reverse check.
|
||||||
*/
|
*/
|
||||||
|
@ -3896,7 +3786,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason)
|
||||||
{
|
{
|
||||||
int retval = SUCCESS, i, j, convert = 0;
|
int retval = SUCCESS, i, j, convert = 0;
|
||||||
struct megasas_instance *instance;
|
struct megasas_instance *instance;
|
||||||
struct megasas_cmd_fusion *cmd_fusion, *mpt_cmd_fusion;
|
struct megasas_cmd_fusion *cmd_fusion, *r1_cmd;
|
||||||
struct fusion_context *fusion;
|
struct fusion_context *fusion;
|
||||||
u32 abs_state, status_reg, reset_adapter;
|
u32 abs_state, status_reg, reset_adapter;
|
||||||
u32 io_timeout_in_crash_mode = 0;
|
u32 io_timeout_in_crash_mode = 0;
|
||||||
|
@ -3973,15 +3863,8 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason)
|
||||||
cmd_fusion = fusion->cmd_list[i];
|
cmd_fusion = fusion->cmd_list[i];
|
||||||
/*check for extra commands issued by driver*/
|
/*check for extra commands issued by driver*/
|
||||||
if (instance->is_ventura) {
|
if (instance->is_ventura) {
|
||||||
cmd_fusion->is_raid_1_fp_write = 0;
|
r1_cmd = fusion->cmd_list[i + instance->max_fw_cmds];
|
||||||
cmd_fusion->cmd_completed = false;
|
megasas_return_cmd_fusion(instance, r1_cmd);
|
||||||
mpt_cmd_fusion =
|
|
||||||
fusion->cmd_list[i + instance->max_fw_cmds];
|
|
||||||
mpt_cmd_fusion->is_raid_1_fp_write = 0;
|
|
||||||
mpt_cmd_fusion->cmd_completed = false;
|
|
||||||
if (mpt_cmd_fusion->scmd)
|
|
||||||
megasas_return_cmd_fusion(instance,
|
|
||||||
mpt_cmd_fusion);
|
|
||||||
}
|
}
|
||||||
scmd_local = cmd_fusion->scmd;
|
scmd_local = cmd_fusion->scmd;
|
||||||
if (cmd_fusion->scmd) {
|
if (cmd_fusion->scmd) {
|
||||||
|
|
|
@ -673,6 +673,7 @@ struct MPI2_IOC_INIT_REQUEST {
|
||||||
|
|
||||||
/* mrpriv defines */
|
/* mrpriv defines */
|
||||||
#define MR_PD_INVALID 0xFFFF
|
#define MR_PD_INVALID 0xFFFF
|
||||||
|
#define MR_DEVHANDLE_INVALID 0xFFFF
|
||||||
#define MAX_SPAN_DEPTH 8
|
#define MAX_SPAN_DEPTH 8
|
||||||
#define MAX_QUAD_DEPTH MAX_SPAN_DEPTH
|
#define MAX_QUAD_DEPTH MAX_SPAN_DEPTH
|
||||||
#define MAX_RAIDMAP_SPAN_DEPTH (MAX_SPAN_DEPTH)
|
#define MAX_RAIDMAP_SPAN_DEPTH (MAX_SPAN_DEPTH)
|
||||||
|
@ -921,7 +922,6 @@ struct IO_REQUEST_INFO {
|
||||||
u8 span_arm; /* span[7:5], arm[4:0] */
|
u8 span_arm; /* span[7:5], arm[4:0] */
|
||||||
u8 pd_after_lb;
|
u8 pd_after_lb;
|
||||||
u16 r1_alt_dev_handle; /* raid 1/10 only */
|
u16 r1_alt_dev_handle; /* raid 1/10 only */
|
||||||
bool is_raid_1_fp_write;
|
|
||||||
bool ra_capable;
|
bool ra_capable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1060,7 +1060,6 @@ struct megasas_cmd_fusion {
|
||||||
u32 index;
|
u32 index;
|
||||||
u8 pd_r1_lb;
|
u8 pd_r1_lb;
|
||||||
struct completion done;
|
struct completion done;
|
||||||
bool is_raid_1_fp_write;
|
|
||||||
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 */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue