diff options
| author | Chaitra P B <chaitra.basappa@broadcom.com> | 2016-05-06 04:59:31 -0400 |
|---|---|---|
| committer | Martin K. Petersen <martin.petersen@oracle.com> | 2016-05-11 16:14:31 -0400 |
| commit | 5f0dfb7a9bcc8139958f59ecb9bbd7e738ae702d (patch) | |
| tree | 88ceb21699c892611b53b94ba21b395aff2885b1 | |
| parent | 6c197093847e8cdec844df39a373bfe1f9a1ac8a (diff) | |
mpt3sas: Used "synchronize_irq()"API to synchronize timed-out IO & TMs
Replaced mpt3sas_base_flush_reply_queues() with
mpt3sas_base_sync_reply_irqs(),as mpt3sas_base_flush_reply_queues()
skips over reply queues that are currently busy (i.e. being handled by
interrupt processing in another core). If a reply queue is busy, then
call to synchronize_irq()in mpt3sas_base_sync_reply_irqs()make sures the
other core has finished flushing the queue and completed any calls to
the mid-layer scsi_done() routine.
Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com>
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
| -rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_base.c | 15 | ||||
| -rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_base.h | 3 | ||||
| -rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_scsih.c | 4 |
3 files changed, 12 insertions, 10 deletions
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index b7f4e664f5f3..751f13edece0 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c | |||
| @@ -1104,18 +1104,16 @@ _base_is_controller_msix_enabled(struct MPT3SAS_ADAPTER *ioc) | |||
| 1104 | } | 1104 | } |
| 1105 | 1105 | ||
| 1106 | /** | 1106 | /** |
| 1107 | * mpt3sas_base_flush_reply_queues - flushing the MSIX reply queues | 1107 | * mpt3sas_base_sync_reply_irqs - flush pending MSIX interrupts |
| 1108 | * @ioc: per adapter object | 1108 | * @ioc: per adapter object |
| 1109 | * Context: ISR conext | 1109 | * Context: non ISR conext |
| 1110 | * | 1110 | * |
| 1111 | * Called when a Task Management request has completed. We want | 1111 | * Called when a Task Management request has completed. |
| 1112 | * to flush the other reply queues so all the outstanding IO has been | ||
| 1113 | * completed back to OS before we process the TM completetion. | ||
| 1114 | * | 1112 | * |
| 1115 | * Return nothing. | 1113 | * Return nothing. |
| 1116 | */ | 1114 | */ |
| 1117 | void | 1115 | void |
| 1118 | mpt3sas_base_flush_reply_queues(struct MPT3SAS_ADAPTER *ioc) | 1116 | mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc) |
| 1119 | { | 1117 | { |
| 1120 | struct adapter_reply_queue *reply_q; | 1118 | struct adapter_reply_queue *reply_q; |
| 1121 | 1119 | ||
| @@ -1126,12 +1124,13 @@ mpt3sas_base_flush_reply_queues(struct MPT3SAS_ADAPTER *ioc) | |||
| 1126 | return; | 1124 | return; |
| 1127 | 1125 | ||
| 1128 | list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { | 1126 | list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { |
| 1129 | if (ioc->shost_recovery) | 1127 | if (ioc->shost_recovery || ioc->remove_host || |
| 1128 | ioc->pci_error_recovery) | ||
| 1130 | return; | 1129 | return; |
| 1131 | /* TMs are on msix_index == 0 */ | 1130 | /* TMs are on msix_index == 0 */ |
| 1132 | if (reply_q->msix_index == 0) | 1131 | if (reply_q->msix_index == 0) |
| 1133 | continue; | 1132 | continue; |
| 1134 | _base_interrupt(reply_q->vector, (void *)reply_q); | 1133 | synchronize_irq(reply_q->vector); |
| 1135 | } | 1134 | } |
| 1136 | } | 1135 | } |
| 1137 | 1136 | ||
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index 71b1c58fec3b..892c9be008b5 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h | |||
| @@ -1236,7 +1236,8 @@ void *mpt3sas_base_get_msg_frame(struct MPT3SAS_ADAPTER *ioc, u16 smid); | |||
| 1236 | void *mpt3sas_base_get_sense_buffer(struct MPT3SAS_ADAPTER *ioc, u16 smid); | 1236 | void *mpt3sas_base_get_sense_buffer(struct MPT3SAS_ADAPTER *ioc, u16 smid); |
| 1237 | __le32 mpt3sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc, | 1237 | __le32 mpt3sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc, |
| 1238 | u16 smid); | 1238 | u16 smid); |
| 1239 | void mpt3sas_base_flush_reply_queues(struct MPT3SAS_ADAPTER *ioc); | 1239 | |
| 1240 | void mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc); | ||
| 1240 | 1241 | ||
| 1241 | /* hi-priority queue */ | 1242 | /* hi-priority queue */ |
| 1242 | u16 mpt3sas_base_get_smid_hpr(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx); | 1243 | u16 mpt3sas_base_get_smid_hpr(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx); |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 7217218edbac..6a4df5a315e9 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c | |||
| @@ -2124,7 +2124,6 @@ _scsih_tm_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
| 2124 | return 1; | 2124 | return 1; |
| 2125 | if (ioc->tm_cmds.smid != smid) | 2125 | if (ioc->tm_cmds.smid != smid) |
| 2126 | return 1; | 2126 | return 1; |
| 2127 | mpt3sas_base_flush_reply_queues(ioc); | ||
| 2128 | ioc->tm_cmds.status |= MPT3_CMD_COMPLETE; | 2127 | ioc->tm_cmds.status |= MPT3_CMD_COMPLETE; |
| 2129 | mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply); | 2128 | mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply); |
| 2130 | if (mpi_reply) { | 2129 | if (mpi_reply) { |
| @@ -2309,6 +2308,9 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel, | |||
| 2309 | } | 2308 | } |
| 2310 | } | 2309 | } |
| 2311 | 2310 | ||
| 2311 | /* sync IRQs in case those were busy during flush. */ | ||
| 2312 | mpt3sas_base_sync_reply_irqs(ioc); | ||
| 2313 | |||
| 2312 | if (ioc->tm_cmds.status & MPT3_CMD_REPLY_VALID) { | 2314 | if (ioc->tm_cmds.status & MPT3_CMD_REPLY_VALID) { |
| 2313 | mpt3sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT); | 2315 | mpt3sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT); |
| 2314 | mpi_reply = ioc->tm_cmds.reply; | 2316 | mpi_reply = ioc->tm_cmds.reply; |
