提交 62f109ec 编写于 作者: C Chandrakanth Patil 提交者: Zheng Zengkai

scsi: megaraid_sas: Handle missing interrupts while re-enabling IRQs

stable inclusion
from stable-5.10.52
commit 5ac2428f2b9636b507970ce0ab4e7a71a53daaf1
bugzilla: 175542 https://gitee.com/openeuler/kernel/issues/I4DTKU

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=5ac2428f2b9636b507970ce0ab4e7a71a53daaf1

--------------------------------

[ Upstream commit 9bedd36e ]

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 the
driver will not see the interrupts which leads to I/O timeout.

This issue only happens when there are many I/O completions on a single
reply queue. This forces the driver to switch between the interrupt and IRQ
context.

Make the driver process the reply queue one more time after enabling the
IRQ.

Link: https://lore.kernel.org/linux-scsi/20201102072746.27410-1-sreekanth.reddy@broadcom.com/
Link: https://lore.kernel.org/r/20210528131307.25683-5-chandrakanth.patil@broadcom.com
Cc: Tomas Henzl <thenzl@redhat.com>
Reported-by: Nkernel test robot <lkp@intel.com>
Signed-off-by: NChandrakanth Patil <chandrakanth.patil@broadcom.com>
Signed-off-by: NSumit Saxena <sumit.saxena@broadcom.com>
Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: NSasha Levin <sashal@kernel.org>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Acked-by: NWeilong Chen <chenweilong@huawei.com>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 10c49686
......@@ -3670,6 +3670,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);
}
}
}
......@@ -3701,6 +3702,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;
......@@ -3717,6 +3719,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;
......@@ -3725,8 +3728,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++)
complete_cmd_fusion(instance, MSIxIndex, NULL);
for (MSIxIndex = 0 ; MSIxIndex < count; MSIxIndex++) {
irq_ctx = &instance->irq_context[MSIxIndex];
complete_cmd_fusion(instance, MSIxIndex, irq_ctx);
}
}
/**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册