]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
scsi: megaraid_sas: Update LD map after populating drv_map driver map copy
authorShivasharan S <shivasharan.srikanteshwara@broadcom.com>
Fri, 5 Jan 2018 13:27:44 +0000 (05:27 -0800)
committerJack Vogel <jack.vogel@oracle.com>
Thu, 8 Mar 2018 02:44:10 +0000 (18:44 -0800)
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: Sumit Saxena <sumit.saxena@broadcom.com>
Signed-off-by: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Orabug: 27625001
Signed-off-by: Jack Vogel <jack.vogel@oracle.com>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/megaraid/megaraid_sas_base.c
drivers/scsi/megaraid/megaraid_sas_fp.c
drivers/scsi/megaraid/megaraid_sas_fusion.c

index 14779464a2d1f3cb0896465a5578d142f50ab05e..4e785d429e2c0adb201db614f5dc19c0c2d22cce 100644 (file)
@@ -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);
 
 
 /*
index d62fda0a6a260fbb60b556651b2cc5966e21e1e0..112acefdc751444576c47200e6383de342796816 100644 (file)
@@ -3335,10 +3335,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 {
@@ -3348,8 +3348,8 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
                                                flags);
                                        break;
                                }
-                       } else
-                               instance->map_id++;
+                       }
+
                        megasas_return_cmd(instance, cmd);
 
                        /*
@@ -3357,10 +3357,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);
@@ -5440,7 +5444,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;
index f2ffde430ec18d19ad8f47099dbc68722cf39845..59ecbb3b53b52acd3a37a105dc181f7845239c53 100644 (file)
@@ -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;
index 31f858f62e35cfc408cacb598d8f180bdfe14720..603c9875cb7c72f177347e0f72d21f91be844f32 100644 (file)
@@ -1324,7 +1324,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;
                }