While reenabling the IRQ after irq poll there may be a small window for the firmware to post the replies with interrupts raised. In that case, driver will not see the interrupts which lead to IOs timeout. This issue hits only when there is a high IOs completion on a single reply queue, which forces the driver to switch between the interrupt and IRQ context. To fix this, driver will process the reply queue one more time after enabling the IRQ. Link: https://lore.kernel.org/linux-scsi/20201102072746.27410-1-sreekanth.reddy@xxxxxxxxxxxx/ Cc: Tomas Henzl <thenzl@xxxxxxxxxx> Signed-off-by: Chandrakanth Patil <chandrakanth.patil@xxxxxxxxxxxx> Signed-off-by: Sumit Saxena <sumit.saxena@xxxxxxxxxxxx> --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index f79c19010c92..8b8d68e75318 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3745,6 +3745,7 @@ static void megasas_sync_irqs(unsigned long instance_addr) if (irq_ctx->irq_poll_scheduled) { irq_ctx->irq_poll_scheduled = false; enable_irq(irq_ctx->os_irq); + complete_cmd_fusion(instance, irq_ctx->MSIxIndex, irq_ctx); } } } @@ -3776,6 +3777,7 @@ int megasas_irqpoll(struct irq_poll *irqpoll, int budget) irq_poll_complete(irqpoll); irq_ctx->irq_poll_scheduled = false; enable_irq(irq_ctx->os_irq); + complete_cmd_fusion(instance, irq_ctx->MSIxIndex, irq_ctx); } return num_entries; @@ -3792,6 +3794,7 @@ megasas_complete_cmd_dpc_fusion(unsigned long instance_addr) { struct megasas_instance *instance = (struct megasas_instance *)instance_addr; + struct megasas_irq_context *irq_ctx = NULL; u32 count, MSIxIndex; count = instance->msix_vectors > 0 ? instance->msix_vectors : 1; @@ -3800,8 +3803,10 @@ megasas_complete_cmd_dpc_fusion(unsigned long instance_addr) if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) return; - for (MSIxIndex = 0 ; MSIxIndex < count; MSIxIndex++) + for (MSIxIndex = 0 ; MSIxIndex < count; MSIxIndex++) { + irq_ctx = &instance->irq_context[MSIxIndex]; complete_cmd_fusion(instance, MSIxIndex, NULL); + } } /** -- 2.18.1
Attachment:
smime.p7s
Description: S/MIME Cryptographic Signature