]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
scsi: ufs: core: Revert "Delegate the interrupt service routine to a threaded IRQ...
authorBart Van Assche <bvanassche@acm.org>
Wed, 15 Jul 2026 17:12:28 +0000 (10:12 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 29 Jul 2026 01:52:09 +0000 (21:52 -0400)
There have been multiple reports of performance regressions caused by
commit 3c7ac40d7322 ("scsi: ufs: core: Delegate the interrupt service
routine to a threaded IRQ handler"). Hence this revert.

This patch reverts most of the following commits:

 * 3c7ac40d7322 ("scsi: ufs: core: Delegate the interrupt service
   routine to a threaded IRQ handler")

 * 6475cfb81fc4 ("scsi: ufs: core: Avoid IRQ thread wakeup during active
   UIC command")

This patch preserves the following commits:

 * 034d319c8899 ("scsi: ufs: core: Fix interrupt handling for MCQ Mode")

 * eabcac808ca3 ("scsi: ufs: core: Fix IRQ lock inversion for the SCSI
   host lock")

Cc: Neil Armstrong <neil.armstrong@linaro.org>
Cc: 孙魁 (Kui Sun) <kui.sun@unisoc.com>
Cc: André Draszik <andre.draszik@linaro.org>
Cc: Gregory CLEMENT <gregory.clement@bootlin.com>
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Fixes: 3c7ac40d7322 ("scsi: ufs: core: Delegate the interrupt service routine to a threaded IRQ handler")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Tested-by: André Draszik <andre.draszik@linaro.org> # on Pixel 6
Reviewed-by: André Draszik <andre.draszik@linaro.org>
Link: https://patch.msgid.link/b70eb60a01f971bed68c42c5b555929db5f835df.1784135511.git.bvanassche@acm.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/ufs/core/ufshcd.c

index c3b105b2678e4f2acd95f3731d9ecb951fae2897..34228beb3f59f83ed2d7107ad86d723506d41507 100644 (file)
@@ -7357,7 +7357,7 @@ static irqreturn_t ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status)
 }
 
 /**
- * ufshcd_threaded_intr - Threaded interrupt service routine
+ * ufshcd_intr - Main interrupt service routine
  * @irq: irq number
  * @__hba: pointer to adapter instance
  *
@@ -7365,7 +7365,7 @@ static irqreturn_t ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status)
  *  IRQ_HANDLED - If interrupt is valid
  *  IRQ_NONE    - If invalid interrupt
  */
-static irqreturn_t ufshcd_threaded_intr(int irq, void *__hba)
+static irqreturn_t ufshcd_intr(int irq, void *__hba)
 {
        u32 last_intr_status, intr_status, enabled_intr_status = 0;
        irqreturn_t retval = IRQ_NONE;
@@ -7404,38 +7404,6 @@ static irqreturn_t ufshcd_threaded_intr(int irq, void *__hba)
        return retval;
 }
 
-/**
- * ufshcd_intr - Main interrupt service routine
- * @irq: irq number
- * @__hba: pointer to adapter instance
- *
- * Return:
- *  IRQ_HANDLED     - If interrupt is valid
- *  IRQ_WAKE_THREAD - If handling is moved to threaded handled
- *  IRQ_NONE        - If invalid interrupt
- */
-static irqreturn_t ufshcd_intr(int irq, void *__hba)
-{
-       struct ufs_hba *hba = __hba;
-       u32 intr_status, enabled_intr_status;
-
-       /*
-        * Handle interrupt in thread if MCQ or ESI is disabled,
-        * and no active UIC command.
-        */
-       if ((!hba->mcq_enabled || !hba->mcq_esi_enabled) &&
-           !hba->active_uic_cmd)
-               return IRQ_WAKE_THREAD;
-
-       intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS);
-       enabled_intr_status = intr_status & ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
-
-       ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS);
-
-       /* Directly handle interrupts since MCQ ESI handlers does the hard job */
-       return ufshcd_sl_intr(hba, enabled_intr_status);
-}
-
 static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag)
 {
        int err = 0;
@@ -11238,8 +11206,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
        ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
 
        /* IRQ registration */
-       err = devm_request_threaded_irq(dev, irq, ufshcd_intr, ufshcd_threaded_intr,
-                                       IRQF_ONESHOT | IRQF_SHARED, UFSHCD, hba);
+       err = devm_request_irq(dev, irq, ufshcd_intr, IRQF_SHARED, UFSHCD, hba);
        if (err) {
                dev_err(hba->dev, "request irq failed\n");
                goto out_disable;