Commit 5f19f7c8 authored by Shivasharan S's avatar Shivasharan S Committed by Martin K. Petersen

scsi: megaraid_sas: Update LD map after populating drv_map driver map copy

Issue – There may be some IO accessing incorrect raid map, but driver
has checks in IO path to handle those cases. It is always better to move
to new raid map only once raid map is populated and validated.  No
functional defect. Fix is provided as part of review.  Fix – Update
instance->map_id after driver has populated new driver raid map from
firmware raid map.
Signed-off-by: default avatarSumit Saxena <sumit.saxena@broadcom.com>
Signed-off-by: default avatarShivasharan S <shivasharan.srikanteshwara@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 619831f2
......@@ -230,7 +230,7 @@ enum MFI_CMD_OP {
/*
* Global functions
*/
extern u8 MR_ValidateMapInfo(struct megasas_instance *instance);
extern u8 MR_ValidateMapInfo(struct megasas_instance *instance, u64 map_id);
/*
......
......@@ -3331,10 +3331,10 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
&& (cmd->frame->dcmd.mbox.b[1] == 1)) {
fusion->fast_path_io = 0;
spin_lock_irqsave(instance->host->host_lock, flags);
status = cmd->frame->hdr.cmd_status;
instance->map_update_cmd = NULL;
if (cmd->frame->hdr.cmd_status != 0) {
if (cmd->frame->hdr.cmd_status !=
MFI_STAT_NOT_FOUND)
if (status != MFI_STAT_OK) {
if (status != MFI_STAT_NOT_FOUND)
dev_warn(&instance->pdev->dev, "map syncfailed, status = 0x%x\n",
cmd->frame->hdr.cmd_status);
else {
......@@ -3344,8 +3344,8 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
flags);
break;
}
} else
instance->map_id++;
}
megasas_return_cmd(instance, cmd);
/*
......@@ -3353,10 +3353,14 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
* Validate Map will set proper value.
* Meanwhile all IOs will go as LD IO.
*/
if (MR_ValidateMapInfo(instance))
if (status == MFI_STAT_OK &&
(MR_ValidateMapInfo(instance, (instance->map_id + 1)))) {
instance->map_id++;
fusion->fast_path_io = 1;
else
} else {
fusion->fast_path_io = 0;
}
megasas_sync_map_info(instance);
spin_unlock_irqrestore(instance->host->host_lock,
flags);
......@@ -5432,7 +5436,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
ctrl_info->adapterOperations2.supportUnevenSpans;
if (instance->UnevenSpanSupport) {
struct fusion_context *fusion = instance->ctrl_context;
if (MR_ValidateMapInfo(instance))
if (MR_ValidateMapInfo(instance, instance->map_id))
fusion->fast_path_io = 1;
else
fusion->fast_path_io = 0;
......
......@@ -168,7 +168,7 @@ static struct MR_LD_SPAN *MR_LdSpanPtrGet(u32 ld, u32 span,
/*
* This function will Populate Driver Map using firmware raid map
*/
static int MR_PopulateDrvRaidMap(struct megasas_instance *instance)
static int MR_PopulateDrvRaidMap(struct megasas_instance *instance, u64 map_id)
{
struct fusion_context *fusion = instance->ctrl_context;
struct MR_FW_RAID_MAP_ALL *fw_map_old = NULL;
......@@ -181,7 +181,7 @@ static int MR_PopulateDrvRaidMap(struct megasas_instance *instance)
struct MR_DRV_RAID_MAP_ALL *drv_map =
fusion->ld_drv_map[(instance->map_id & 1)];
fusion->ld_drv_map[(map_id & 1)];
struct MR_DRV_RAID_MAP *pDrvRaidMap = &drv_map->raidMap;
void *raid_map_data = NULL;
......@@ -190,7 +190,7 @@ static int MR_PopulateDrvRaidMap(struct megasas_instance *instance)
0xff, (sizeof(u16) * MAX_LOGICAL_DRIVES_DYN));
if (instance->max_raid_mapsize) {
fw_map_dyn = fusion->ld_map[(instance->map_id & 1)];
fw_map_dyn = fusion->ld_map[(map_id & 1)];
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)
......@@ -255,7 +255,7 @@ static int MR_PopulateDrvRaidMap(struct megasas_instance *instance)
} else if (instance->supportmax256vd) {
fw_map_ext =
(struct MR_FW_RAID_MAP_EXT *)fusion->ld_map[(instance->map_id & 1)];
(struct MR_FW_RAID_MAP_EXT *)fusion->ld_map[(map_id & 1)];
ld_count = (u16)le16_to_cpu(fw_map_ext->ldCount);
if (ld_count > MAX_LOGICAL_DRIVES_EXT) {
dev_dbg(&instance->pdev->dev, "megaraid_sas: LD count exposed in RAID map in not valid\n");
......@@ -282,7 +282,7 @@ static int MR_PopulateDrvRaidMap(struct megasas_instance *instance)
cpu_to_le32(sizeof(struct MR_FW_RAID_MAP_EXT));
} else {
fw_map_old = (struct MR_FW_RAID_MAP_ALL *)
fusion->ld_map[(instance->map_id & 1)];
fusion->ld_map[(map_id & 1)];
pFwRaidMap = &fw_map_old->raidMap;
ld_count = (u16)le32_to_cpu(pFwRaidMap->ldCount);
if (ld_count > MAX_LOGICAL_DRIVES) {
......@@ -313,7 +313,7 @@ static int MR_PopulateDrvRaidMap(struct megasas_instance *instance)
/*
* This function will validate Map info data provided by FW
*/
u8 MR_ValidateMapInfo(struct megasas_instance *instance)
u8 MR_ValidateMapInfo(struct megasas_instance *instance, u64 map_id)
{
struct fusion_context *fusion;
struct MR_DRV_RAID_MAP_ALL *drv_map;
......@@ -325,11 +325,11 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance)
u16 ld;
u32 expected_size;
if (MR_PopulateDrvRaidMap(instance))
if (MR_PopulateDrvRaidMap(instance, map_id))
return 0;
fusion = instance->ctrl_context;
drv_map = fusion->ld_drv_map[(instance->map_id & 1)];
drv_map = fusion->ld_drv_map[(map_id & 1)];
pDrvRaidMap = &drv_map->raidMap;
lbInfo = fusion->load_balance_info;
......
......@@ -1320,7 +1320,7 @@ megasas_get_map_info(struct megasas_instance *instance)
fusion->fast_path_io = 0;
if (!megasas_get_ld_map_info(instance)) {
if (MR_ValidateMapInfo(instance)) {
if (MR_ValidateMapInfo(instance, instance->map_id)) {
fusion->fast_path_io = 1;
return 0;
}
......
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