From: Andrew Morton <akpm@digeo.com>
To: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: shrybman@sympatico.ca, linux-kernel@vger.kernel.org
Subject: Re: 2.5.68-mmX: Drowning in irq 7: nobody cared!
Date: Tue, 6 May 2003 08:17:16 -0700 [thread overview]
Message-ID: <20030506081716.60de29d1.akpm@digeo.com> (raw)
In-Reply-To: <1052213733.28797.1.camel@dhcp22.swansea.linux.org.uk>
Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
>
> With APIC at least it doesnt suprise me the least. The IRQ hack seems
> extremely racey.
Good point. How about we do something like "if half of the past 1000
interrupts weren't handled then try to kill the IRQ"?
arch/i386/kernel/irq.c | 55 +++++++++++++++++++++++++++++++++++++++----------
include/linux/irq.h | 2 +
2 files changed, 46 insertions(+), 11 deletions(-)
diff -puN arch/i386/kernel/irq.c~irq-check-rate-limit arch/i386/kernel/irq.c
--- 25/arch/i386/kernel/irq.c~irq-check-rate-limit 2003-05-06 07:54:17.000000000 -0700
+++ 25-akpm/arch/i386/kernel/irq.c 2003-05-06 08:16:15.000000000 -0700
@@ -66,8 +66,12 @@
/*
* Controller mappings for all interrupt sources:
*/
-irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
- { [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
+irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
+ [0 ... NR_IRQS-1] = {
+ .handler = &no_irq_type,
+ .lock = SPIN_LOCK_UNLOCKED
+ }
+};
static void register_irq_proc (unsigned int irq);
@@ -209,7 +213,6 @@ int handle_IRQ_event(unsigned int irq,
{
int status = 1; /* Force the "do bottom halves" bit */
int retval = 0;
- struct irqaction *first_action = action;
if (!(action->flags & SA_INTERRUPT))
local_irq_enable();
@@ -222,19 +225,43 @@ int handle_IRQ_event(unsigned int irq,
if (status & SA_SAMPLE_RANDOM)
add_interrupt_randomness(irq);
local_irq_disable();
- if (retval != 1) {
+ return status;
+}
+
+/*
+ * If 500 of the previous 1000 interrupts have not been handled then assume
+ * that the IRQ is stuck in some manner. Drop a diagnostic and try to turn the
+ * IRQ off.
+ *
+ * Called under desc->lock
+ */
+static void note_interrupt(irq_desc_t *desc, int irq, int status)
+{
+ if (status != IRQ_HANDLED)
+ desc->irqs_unhandled++;
+ desc->irq_count++;
+ if (desc->irq_count < 1000)
+ return;
+
+ desc->irq_count = 0;
+ if (desc->irqs_unhandled > 500) {
+ /*
+ * The interrupt is stuck
+ */
static int count = 100;
+ struct irqaction *action;
+
if (count) {
count--;
- if (retval) {
+ if (status) {
printk("irq event %d: bogus retval mask %x\n",
- irq, retval);
+ irq, status);
} else {
printk("irq %d: nobody cared!\n", irq);
}
dump_stack();
printk("handlers:\n");
- action = first_action;
+ action = desc->action;
do {
printk("[<%p>]", action->handler);
print_symbol(" (%s)",
@@ -243,9 +270,13 @@ int handle_IRQ_event(unsigned int irq,
action = action->next;
} while (action);
}
+ /*
+ * Now kill the IRQ
+ */
+ desc->status |= IRQ_DISABLED;
+ desc->handler->disable(irq);
}
-
- return status;
+ desc->irqs_unhandled = 0;
}
/*
@@ -418,10 +449,12 @@ asmlinkage unsigned int do_IRQ(struct pt
* SMP environment.
*/
for (;;) {
+ int status;
+
spin_unlock(&desc->lock);
- handle_IRQ_event(irq, ®s, action);
+ status = handle_IRQ_event(irq, ®s, action);
spin_lock(&desc->lock);
-
+ note_interrupt(desc, irq, status);
if (likely(!(desc->status & IRQ_PENDING)))
break;
desc->status &= ~IRQ_PENDING;
diff -puN include/linux/irq.h~irq-check-rate-limit include/linux/irq.h
--- 25/include/linux/irq.h~irq-check-rate-limit 2003-05-06 07:56:03.000000000 -0700
+++ 25-akpm/include/linux/irq.h 2003-05-06 08:05:17.000000000 -0700
@@ -61,6 +61,8 @@ typedef struct {
hw_irq_controller *handler;
struct irqaction *action; /* IRQ action list */
unsigned int depth; /* nested irq disables */
+ unsigned int irq_count; /* For detecting broken interrupts */
+ unsigned int irqs_unhandled;
spinlock_t lock;
} ____cacheline_aligned irq_desc_t;
_
next prev parent reply other threads:[~2003-05-06 15:03 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-05-05 13:23 Shane Shrybman
2003-05-05 21:30 ` Andrew Morton
2003-05-06 9:35 ` Alan Cox
2003-05-06 10:41 ` Zwane Mwaikambo
2003-05-06 11:17 ` Alan Cox
2003-05-06 15:17 ` Andrew Morton [this message]
2003-05-06 15:07 ` Alan Cox
2003-05-06 16:12 ` Andrew Morton
2003-05-07 22:10 ` Shane Shrybman
2003-05-06 21:44 Chuck Ebbert
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=20030506081716.60de29d1.akpm@digeo.com \
--to=akpm@digeo.com \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=linux-kernel@vger.kernel.org \
--cc=shrybman@sympatico.ca \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®