From: Eliav Farber <farbere@amazon.com>
To: <linux@armlinux.org.uk>, <catalin.marinas@arm.com>,
<will@kernel.org>, <mpe@ellerman.id.au>, <npiggin@gmail.com>,
<christophe.leroy@csgroup.eu>, <naveen@kernel.org>,
<maddy@linux.ibm.com>, <paul.walmsley@sifive.com>,
<palmer@dabbelt.com>, <aou@eecs.berkeley.edu>,
<tglx@linutronix.de>, <akpm@linux-foundation.org>,
<bhe@redhat.com>, <farbere@amazon.com>, <hbathini@linux.ibm.com>,
<sourabhjain@linux.ibm.com>, <adityag@linux.ibm.com>,
<songshuaishuai@tinylab.org>, <takakura@valinux.co.jp>,
<linux-arm-kernel@lists.infradead.org>,
<linux-kernel@vger.kernel.org>, <linuxppc-dev@lists.ozlabs.org>,
<linux-riscv@lists.infradead.org>
Cc: <jonnyc@amazon.com>
Subject: [PATCH v5 2/2] kexec: Prevent redundant IRQ masking by checking state before shutdown
Date: Sat, 30 Nov 2024 20:11:43 +0000 [thread overview]
Message-ID: <20241130201143.48808-3-farbere@amazon.com> (raw)
In-Reply-To: <20241130201143.48808-1-farbere@amazon.com>
During machine kexec, the function machine_kexec_mask_interrupts() is
responsible for disabling or masking all interrupts. While the irq_disable
hook ensures that an already-disabled IRQ is not disabled again, the
current implementation unconditionally invokes the irq_mask() function for
every interrupt descriptor, even when the interrupt is already masked.
A specific issue was observed in the crash kernel flow after unbinding a
device (prior to kexec) that used a GPIO as an IRQ source. The warning was
triggered by the gpiochip_disable_irq() function, which attempted to clear
the FLAG_IRQ_IS_ENABLED flag when FLAG_USED_AS_IRQ was not set:
```
void gpiochip_disable_irq(struct gpio_chip *gc, unsigned int offset)
{
struct gpio_desc *desc = gpiochip_get_desc(gc, offset);
if (!IS_ERR(desc) &&
!WARN_ON(!test_bit(FLAG_USED_AS_IRQ, &desc->flags)))
clear_bit(FLAG_IRQ_IS_ENABLED, &desc->flags);
}
```
This issue surfaced after commit a8173820f441 ("gpio: gpiolib: Allow GPIO
IRQs to lazy disable") introduced lazy disablement for GPIO IRQs. It
replaced disable/enable hooks with mask/unmask hooks. Unlike the disable
hook, the mask hook doesn't handle already-masked IRQs.
When a GPIO-IRQ driver is unbound, the IRQ is released, triggering
__irq_disable() and irq_state_set_masked(). A subsequent call to
machine_kexec_mask_interrupts() re-invokes chip->irq_mask(). This results
in a call chain, including gpiochip_irq_mask() and gpiochip_disable_irq().
Since FLAG_USED_AS_IRQ was cleared earlier, a warning occurs.
Replace calls to irq_mask() and irq_disable() hooks with a simplified call
to irq_shutdown(), and check if the interrupt is started (irqd_is_started)
before calling the shutdown.
Signed-off-by: Eliav Farber <farbere@amazon.com>
---
V4 -> V5:
- The phrase 'This patch' has been removed from the commit message.
kernel/irq/kexec.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/kernel/irq/kexec.c b/kernel/irq/kexec.c
index 0f9548c1708d..1a3deffe6b5b 100644
--- a/kernel/irq/kexec.c
+++ b/kernel/irq/kexec.c
@@ -17,7 +17,7 @@ void machine_kexec_mask_interrupts(void)
int check_eoi = 1;
chip = irq_desc_get_chip(desc);
- if (!chip)
+ if (!chip || !irqd_is_started(&desc->irq_data))
continue;
if (IS_ENABLED(CONFIG_GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD)) {
@@ -31,10 +31,6 @@ void machine_kexec_mask_interrupts(void)
if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
chip->irq_eoi(&desc->irq_data);
- if (chip->irq_mask)
- chip->irq_mask(&desc->irq_data);
-
- if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
- chip->irq_disable(&desc->irq_data);
+ irq_shutdown(desc);
}
}
--
2.40.1
WARNING: multiple messages have this Message-ID (diff)
From: Eliav Farber <farbere@amazon.com>
To: <linux@armlinux.org.uk>, <catalin.marinas@arm.com>,
<will@kernel.org>, <mpe@ellerman.id.au>, <npiggin@gmail.com>,
<christophe.leroy@csgroup.eu>, <naveen@kernel.org>,
<maddy@linux.ibm.com>, <paul.walmsley@sifive.com>,
<palmer@dabbelt.com>, <aou@eecs.berkeley.edu>,
<tglx@linutronix.de>, <akpm@linux-foundation.org>,
<bhe@redhat.com>, <farbere@amazon.com>, <hbathini@linux.ibm.com>,
<sourabhjain@linux.ibm.com>, <adityag@linux.ibm.com>,
<songshuaishuai@tinylab.org>, <takakura@valinux.co.jp>,
<linux-arm-kernel@lists.infradead.org>,
<linux-kernel@vger.kernel.org>, <linuxppc-dev@lists.ozlabs.org>,
<linux-riscv@lists.infradead.org>
Cc: <jonnyc@amazon.com>
Subject: [PATCH v5 2/2] kexec: Prevent redundant IRQ masking by checking state before shutdown
Date: Sat, 30 Nov 2024 20:11:43 +0000 [thread overview]
Message-ID: <20241130201143.48808-3-farbere@amazon.com> (raw)
In-Reply-To: <20241130201143.48808-1-farbere@amazon.com>
During machine kexec, the function machine_kexec_mask_interrupts() is
responsible for disabling or masking all interrupts. While the irq_disable
hook ensures that an already-disabled IRQ is not disabled again, the
current implementation unconditionally invokes the irq_mask() function for
every interrupt descriptor, even when the interrupt is already masked.
A specific issue was observed in the crash kernel flow after unbinding a
device (prior to kexec) that used a GPIO as an IRQ source. The warning was
triggered by the gpiochip_disable_irq() function, which attempted to clear
the FLAG_IRQ_IS_ENABLED flag when FLAG_USED_AS_IRQ was not set:
```
void gpiochip_disable_irq(struct gpio_chip *gc, unsigned int offset)
{
struct gpio_desc *desc = gpiochip_get_desc(gc, offset);
if (!IS_ERR(desc) &&
!WARN_ON(!test_bit(FLAG_USED_AS_IRQ, &desc->flags)))
clear_bit(FLAG_IRQ_IS_ENABLED, &desc->flags);
}
```
This issue surfaced after commit a8173820f441 ("gpio: gpiolib: Allow GPIO
IRQs to lazy disable") introduced lazy disablement for GPIO IRQs. It
replaced disable/enable hooks with mask/unmask hooks. Unlike the disable
hook, the mask hook doesn't handle already-masked IRQs.
When a GPIO-IRQ driver is unbound, the IRQ is released, triggering
__irq_disable() and irq_state_set_masked(). A subsequent call to
machine_kexec_mask_interrupts() re-invokes chip->irq_mask(). This results
in a call chain, including gpiochip_irq_mask() and gpiochip_disable_irq().
Since FLAG_USED_AS_IRQ was cleared earlier, a warning occurs.
Replace calls to irq_mask() and irq_disable() hooks with a simplified call
to irq_shutdown(), and check if the interrupt is started (irqd_is_started)
before calling the shutdown.
Signed-off-by: Eliav Farber <farbere@amazon.com>
---
V4 -> V5:
- The phrase 'This patch' has been removed from the commit message.
kernel/irq/kexec.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/kernel/irq/kexec.c b/kernel/irq/kexec.c
index 0f9548c1708d..1a3deffe6b5b 100644
--- a/kernel/irq/kexec.c
+++ b/kernel/irq/kexec.c
@@ -17,7 +17,7 @@ void machine_kexec_mask_interrupts(void)
int check_eoi = 1;
chip = irq_desc_get_chip(desc);
- if (!chip)
+ if (!chip || !irqd_is_started(&desc->irq_data))
continue;
if (IS_ENABLED(CONFIG_GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD)) {
@@ -31,10 +31,6 @@ void machine_kexec_mask_interrupts(void)
if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
chip->irq_eoi(&desc->irq_data);
- if (chip->irq_mask)
- chip->irq_mask(&desc->irq_data);
-
- if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
- chip->irq_disable(&desc->irq_data);
+ irq_shutdown(desc);
}
}
--
2.40.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
next prev parent reply other threads:[~2024-11-30 20:15 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-30 20:11 [PATCH v5 0/2] Improve interrupt handling during machine kexec Eliav Farber
2024-11-30 20:11 ` Eliav Farber
2024-11-30 20:11 ` [PATCH v5 1/2] kexec: Consolidate machine_kexec_mask_interrupts() implementation Eliav Farber
2024-11-30 20:11 ` Eliav Farber
2024-12-03 11:04 ` Thomas Gleixner
2024-12-03 11:04 ` Thomas Gleixner
2024-12-04 11:02 ` Jiri Slaby
2024-12-04 11:02 ` Jiri Slaby
2024-11-30 20:11 ` Eliav Farber [this message]
2024-11-30 20:11 ` [PATCH v5 2/2] kexec: Prevent redundant IRQ masking by checking state before shutdown Eliav Farber
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241130201143.48808-3-farbere@amazon.com \
--to=farbere@amazon.com \
--cc=adityag@linux.ibm.com \
--cc=akpm@linux-foundation.org \
--cc=aou@eecs.berkeley.edu \
--cc=bhe@redhat.com \
--cc=catalin.marinas@arm.com \
--cc=christophe.leroy@csgroup.eu \
--cc=hbathini@linux.ibm.com \
--cc=jonnyc@amazon.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=linux@armlinux.org.uk \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=maddy@linux.ibm.com \
--cc=mpe@ellerman.id.au \
--cc=naveen@kernel.org \
--cc=npiggin@gmail.com \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=songshuaishuai@tinylab.org \
--cc=sourabhjain@linux.ibm.com \
--cc=takakura@valinux.co.jp \
--cc=tglx@linutronix.de \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.