diff options
author | Sumit.Saxena@lsi.com <Sumit.Saxena@lsi.com> | 2013-10-18 03:20:37 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-10-25 06:27:36 -0400 |
commit | 999ece0af91cdf15e7e0687567914721b4499860 (patch) | |
tree | a314c2f5c91ebfefac2a2576739ead7b00f37f7b /drivers | |
parent | 1109c94444504bff8b7463879e598fb320bf77c0 (diff) |
[SCSI] megaraid_sas: Fix synchronization problem between sysPD IO path and AEN path
There is syncronization problem between sysPD IO path and AEN path. Driver
maintains instance->pd_list[] array, which will get updated(by calling
function megasas_get_pd_list[]), whenever any of below events occurs-
MR_EVT_PD_INSERTED
MR_EVT_PD_REMOVED
MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED
MR_EVT_FOREIGN_CFG_IMPORTED
At same time running sysPD IO will be accessing the same array
instance->pd_list[], which is getting updated in AEN path, because of this IO
may not get correct PD info from instance->pd_list[] array.
Signed-off-by: Adam Radford <adam.radford@lsi.com>
Signed-off-by: Sumit Saxena <sumit.saxena@lsi.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas.h | 1 | ||||
-rw-r--r-- | 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 0c73ba4bf451..e9e543c58485 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h | |||
@@ -1531,6 +1531,7 @@ struct megasas_instance { | |||
1531 | struct megasas_register_set __iomem *reg_set; | 1531 | struct megasas_register_set __iomem *reg_set; |
1532 | u32 *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY]; | 1532 | u32 *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY]; |
1533 | struct megasas_pd_list pd_list[MEGASAS_MAX_PD]; | 1533 | struct megasas_pd_list pd_list[MEGASAS_MAX_PD]; |
1534 | struct megasas_pd_list local_pd_list[MEGASAS_MAX_PD]; | ||
1534 | u8 ld_ids[MEGASAS_MAX_LD_IDS]; | 1535 | u8 ld_ids[MEGASAS_MAX_LD_IDS]; |
1535 | s8 init_id; | 1536 | s8 init_id; |
1536 | 1537 | ||
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index e62ff020c253..2cf9470dd11b 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c | |||
@@ -3194,19 +3194,21 @@ megasas_get_pd_list(struct megasas_instance *instance) | |||
3194 | (le32_to_cpu(ci->count) < | 3194 | (le32_to_cpu(ci->count) < |
3195 | (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) { | 3195 | (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) { |
3196 | 3196 | ||
3197 | memset(instance->pd_list, 0, | 3197 | memset(instance->local_pd_list, 0, |
3198 | MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)); | 3198 | MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)); |
3199 | 3199 | ||
3200 | for (pd_index = 0; pd_index < le32_to_cpu(ci->count); pd_index++) { | 3200 | for (pd_index = 0; pd_index < le32_to_cpu(ci->count); pd_index++) { |
3201 | 3201 | ||
3202 | instance->pd_list[le16_to_cpu(pd_addr->deviceId)].tid = | 3202 | instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].tid = |
3203 | le16_to_cpu(pd_addr->deviceId); | 3203 | le16_to_cpu(pd_addr->deviceId); |
3204 | instance->pd_list[le16_to_cpu(pd_addr->deviceId)].driveType = | 3204 | instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].driveType = |
3205 | pd_addr->scsiDevType; | 3205 | pd_addr->scsiDevType; |
3206 | instance->pd_list[le16_to_cpu(pd_addr->deviceId)].driveState = | 3206 | instance->local_pd_list[le16_to_cpu(pd_addr->deviceId)].driveState = |
3207 | MR_PD_STATE_SYSTEM; | 3207 | MR_PD_STATE_SYSTEM; |
3208 | pd_addr++; | 3208 | pd_addr++; |
3209 | } | 3209 | } |
3210 | memcpy(instance->pd_list, instance->local_pd_list, | ||
3211 | sizeof(instance->pd_list)); | ||
3210 | } | 3212 | } |
3211 | 3213 | ||
3212 | pci_free_consistent(instance->pdev, | 3214 | pci_free_consistent(instance->pdev, |