diff options
-rw-r--r-- | drivers/scsi/mpi3mr/mpi3mr.h | 3 | ||||
-rw-r--r-- | drivers/scsi/mpi3mr/mpi3mr_fw.c | 10 |
2 files changed, 12 insertions, 1 deletions
diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h index ab36aa2dfdc4..3348797bc73f 100644 --- a/drivers/scsi/mpi3mr/mpi3mr.h +++ b/drivers/scsi/mpi3mr/mpi3mr.h @@ -1032,6 +1032,8 @@ struct scmd_priv { * @admin_reply_base: Admin reply queue base virtual address * @admin_reply_dma: Admin reply queue base dma address * @admin_reply_q_in_use: Queue is handled by poll/ISR + * @admin_pend_isr: Count of unprocessed admin ISR/poll calls + * due to another thread processing replies * @ready_timeout: Controller ready timeout * @intr_info: Interrupt cookie pointer * @intr_info_count: Number of interrupt cookies @@ -1206,6 +1208,7 @@ struct mpi3mr_ioc { void *admin_reply_base; dma_addr_t admin_reply_dma; atomic_t admin_reply_q_in_use; + atomic_t admin_pend_isr; u32 ready_timeout; diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c index f83d5c9f29a2..3fcb1ad3b070 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_fw.c +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c @@ -446,8 +446,10 @@ int mpi3mr_process_admin_reply_q(struct mpi3mr_ioc *mrioc) u16 threshold_comps = 0; struct mpi3_default_reply_descriptor *reply_desc; - if (!atomic_add_unless(&mrioc->admin_reply_q_in_use, 1, 1)) + if (!atomic_add_unless(&mrioc->admin_reply_q_in_use, 1, 1)) { + atomic_inc(&mrioc->admin_pend_isr); return 0; + } reply_desc = (struct mpi3_default_reply_descriptor *)mrioc->admin_reply_base + admin_reply_ci; @@ -2757,6 +2759,12 @@ static void mpi3mr_watchdog_work(struct work_struct *work) return; } + if (atomic_read(&mrioc->admin_pend_isr)) { + ioc_err(mrioc, "Unprocessed admin ISR instance found\n" + "flush admin replies\n"); + mpi3mr_process_admin_reply_q(mrioc); + } + if (!(mrioc->facts.ioc_capabilities & MPI3_IOCFACTS_CAPABILITY_NON_SUPERVISOR_IOC) && (mrioc->ts_update_counter++ >= mrioc->ts_update_interval)) { |