From: zwane@mwaikambo.name
To: Ingo Molnar <mingo@elte.hu>
Cc: Robert Love <rml@tech9.net>, Linux Kernel <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH][RFC] per isr in_progress markers
Date: Mon, 9 Sep 2002 05:49:59 -0400 (EDT) [thread overview]
Message-ID: <20020909094959.5A955BC51@hemi.commfireservices.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 10267 bytes --]
Hi,
I sent you a bad patch yesterday.
Zwane
Index: linux-2.5.33/arch/i386/kernel/io_apic.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.33/arch/i386/kernel/io_apic.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 io_apic.c
--- linux-2.5.33/arch/i386/kernel/io_apic.c 31 Aug 2002 22:31:11 -0000 1.1.1.1
+++ linux-2.5.33/arch/i386/kernel/io_apic.c 8 Sep 2002 17:45:32 -0000
@@ -1292,15 +1292,14 @@
#define shutdown_edge_ioapic_irq disable_edge_ioapic_irq
/*
- * Once we have recorded IRQ_PENDING already, we can mask the
+ * Once we have recorded irq pending already, we can mask the
* interrupt for real. This prevents IRQ storms from unhandled
* devices.
*/
static void ack_edge_ioapic_irq(unsigned int irq)
{
balance_irq(irq);
- if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED))
- == (IRQ_PENDING | IRQ_DISABLED))
+ if (irq_desc[irq].pending && (irq_desc[irq].status & IRQ_DISABLED))
mask_IO_APIC_irq(irq);
ack_APIC_irq();
}
Index: linux-2.5.33/arch/i386/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.33/arch/i386/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.33/arch/i386/kernel/irq.c 31 Aug 2002 22:31:11 -0000 1.1.1.1
+++ linux-2.5.33/arch/i386/kernel/irq.c 8 Sep 2002 22:46:56 -0000
@@ -66,7 +66,7 @@
* 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}};
+ { [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED, 0}};
static void register_irq_proc (unsigned int irq);
@@ -186,11 +186,29 @@
#if CONFIG_SMP
inline void synchronize_irq(unsigned int irq)
{
+ /* We can still synchronize with IRQ_INPROGRESS even
+ * with asynchronous handlers since it encapsulates
+ * the handlers
+ */
while (irq_desc[irq].status & IRQ_INPROGRESS)
cpu_relax();
}
#endif
+/* This should be called from ISRs to enable
+ * their interrupt line once they've acked
+ * the device interrupt they are handling.
+ */
+
+void isr_unmask_irq(unsigned int irq)
+{
+ irq_desc_t *desc = irq_desc + irq;
+
+ /* check for an IOAPIC wired interrupt */
+ if ((desc->action->flags & SA_UNMASKIRQ) && !memcmp(desc->handler, "IO", 2))
+ desc->handler->ack(irq);
+}
+
/*
* This should really return information about whether
* we should do bottom half handling etc. Right now we
@@ -200,21 +218,27 @@
*/
int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
{
- int status = 1; /* Force the "do bottom halves" bit */
+ int ret = 1; /* Force the "do bottom halves" bit */
if (!(action->flags & SA_INTERRUPT))
local_irq_enable();
+ /* Ease irq sharing by allowing other handlers to be run instead
+ * of blocking all with IRQ_INPROGRESS */
+
do {
- status |= action->flags;
- action->handler(irq, action->dev_id, regs);
+ if (test_and_set_bit(ISR_INPROGRESS, &action->status) == 0) {
+ action->handler(irq, action->dev_id, regs);
+ clear_bit(ISR_INPROGRESS, &action->status);
+ }
+ ret |= action->flags;
action = action->next;
} while (action);
- if (status & SA_SAMPLE_RANDOM)
+ if (ret & SA_SAMPLE_RANDOM)
add_interrupt_randomness(irq);
local_irq_disable();
- return status;
+ return ret;
}
/*
@@ -289,9 +313,10 @@
case 1: {
unsigned int status = desc->status & ~IRQ_DISABLED;
desc->status = status;
- if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
+
+ if (!(status & IRQ_REPLAY) && desc->pending) {
desc->status = status | IRQ_REPLAY;
- hw_resend_irq(desc->handler,irq);
+ hw_resend_irq(desc->handler, irq);
}
desc->handler->enable(irq);
/* fall-through */
@@ -338,16 +363,19 @@
WAITING is used by probe to mark irqs that are being tested
*/
status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
- status |= IRQ_PENDING; /* we _want_ to handle it */
+ desc->pending++; /* we _want_ to handle it */
/*
* If the IRQ is disabled for whatever reason, we cannot
- * use the action we have.
+ * use the action we have. Note that we don't check for
+ * IRQ_INPROGRESS, we allow multiple ISRs from a shared
+ * interrupt to be run concurrently, but still not allowing
+ * the same handler to be run asynchronously.
*/
action = NULL;
- if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
+ if (likely(!(status & IRQ_DISABLED))) {
action = desc->action;
- status &= ~IRQ_PENDING; /* we commit to handling */
+ desc->pending--; /* we commit to handling */
status |= IRQ_INPROGRESS; /* we are handling it */
}
desc->status = status;
@@ -376,9 +404,9 @@
handle_IRQ_event(irq, ®s, action);
spin_lock(&desc->lock);
- if (likely(!(desc->status & IRQ_PENDING)))
+ if (likely(!desc->pending))
break;
- desc->status &= ~IRQ_PENDING;
+ desc->pending--;
}
out:
desc->status &= ~IRQ_INPROGRESS;
@@ -424,6 +452,7 @@
*
* SA_SAMPLE_RANDOM The interrupt can be used for entropy
*
+ * SA_UNMASKIRQ Unmask irq line whilst processing
*/
int request_irq(unsigned int irq,
@@ -463,6 +492,7 @@
action->mask = 0;
action->name = devname;
action->next = NULL;
+ action->status = 0;
action->dev_id = dev_id;
retval = setup_irq(irq, action);
@@ -563,14 +593,14 @@
desc = irq_desc + i;
spin_lock_irq(&desc->lock);
- if (!irq_desc[i].action)
- irq_desc[i].handler->startup(i);
+ if (!desc->action)
+ desc->handler->startup(i);
spin_unlock_irq(&desc->lock);
}
/* Wait for longstanding interrupts to trigger. */
for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
- /* about 20ms delay */ barrier();
+ /* about 20ms delay */ cpu_relax();
/*
* enable any unassigned irqs
@@ -584,7 +614,7 @@
if (!desc->action) {
desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
if (desc->handler->startup(i))
- desc->status |= IRQ_PENDING;
+ desc->pending++;
}
spin_unlock_irq(&desc->lock);
}
@@ -593,7 +623,7 @@
* Wait for spurious interrupts to trigger
*/
for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
- /* about 100ms delay */ barrier();
+ /* about 100ms delay */ cpu_relax();
/*
* Now filter out any obviously spurious interrupts
@@ -756,6 +786,14 @@
return -EBUSY;
}
+ if (!(old->flags & new->flags & SA_UNMASKIRQ)) {
+ printk(KERN_DEBUG
+ "Unable to unmask irqs with isrs old:%s new:%s\n",
+ old->name, new->name);
+ old->flags &= ~SA_UNMASKIRQ;
+ new->flags &= ~SA_UNMASKIRQ;
+ }
+
/* add new interrupt at end of irq queue */
do {
p = &old->next;
Index: linux-2.5.33/include/asm-i386/hw_irq.h
===================================================================
RCS file: /build/cvsroot/linux-2.5.33/include/asm-i386/hw_irq.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 hw_irq.h
--- linux-2.5.33/include/asm-i386/hw_irq.h 31 Aug 2002 22:31:04 -0000 1.1.1.1
+++ linux-2.5.33/include/asm-i386/hw_irq.h 8 Sep 2002 20:29:58 -0000
@@ -43,6 +43,7 @@
extern void mask_irq(unsigned int irq);
extern void unmask_irq(unsigned int irq);
+extern void isr_unmask_irq(unsigned int irq);
extern void disable_8259A_irq(unsigned int irq);
extern void enable_8259A_irq(unsigned int irq);
extern int i8259A_irq_pending(unsigned int irq);
Index: linux-2.5.33/include/asm-i386/signal.h
===================================================================
RCS file: /build/cvsroot/linux-2.5.33/include/asm-i386/signal.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 signal.h
--- linux-2.5.33/include/asm-i386/signal.h 31 Aug 2002 22:31:04 -0000 1.1.1.1
+++ linux-2.5.33/include/asm-i386/signal.h 8 Sep 2002 17:47:11 -0000
@@ -120,6 +120,7 @@
#define SA_PROBE SA_ONESHOT
#define SA_SAMPLE_RANDOM SA_RESTART
#define SA_SHIRQ 0x04000000
+#define SA_UNMASKIRQ SA_NOMASK
#endif
#define SIG_BLOCK 0 /* for blocking signals */
Index: linux-2.5.33/include/linux/interrupt.h
===================================================================
RCS file: /build/cvsroot/linux-2.5.33/include/linux/interrupt.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 interrupt.h
--- linux-2.5.33/include/linux/interrupt.h 31 Aug 2002 22:30:51 -0000 1.1.1.1
+++ linux-2.5.33/include/linux/interrupt.h 8 Sep 2002 17:45:31 -0000
@@ -13,6 +13,8 @@
#include <asm/system.h>
#include <asm/ptrace.h>
+#define ISR_INPROGRESS 1 /* ISR currently being executed */
+
struct irqaction {
void (*handler)(int, void *, struct pt_regs *);
unsigned long flags;
@@ -20,6 +22,7 @@
const char *name;
void *dev_id;
struct irqaction *next;
+ unsigned long status;
};
Index: linux-2.5.33/include/linux/irq.h
===================================================================
RCS file: /build/cvsroot/linux-2.5.33/include/linux/irq.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.h
--- linux-2.5.33/include/linux/irq.h 31 Aug 2002 22:30:53 -0000 1.1.1.1
+++ linux-2.5.33/include/linux/irq.h 8 Sep 2002 17:45:32 -0000
@@ -24,13 +24,12 @@
*/
#define IRQ_INPROGRESS 1 /* IRQ handler active - do not enter! */
#define IRQ_DISABLED 2 /* IRQ disabled - do not enter! */
-#define IRQ_PENDING 4 /* IRQ pending - replay on enable */
-#define IRQ_REPLAY 8 /* IRQ has been replayed but not acked yet */
-#define IRQ_AUTODETECT 16 /* IRQ is being autodetected */
-#define IRQ_WAITING 32 /* IRQ not yet seen - for autodetection */
-#define IRQ_LEVEL 64 /* IRQ level triggered */
-#define IRQ_MASKED 128 /* IRQ masked - shouldn't be seen again */
-#define IRQ_PER_CPU 256 /* IRQ is per CPU */
+#define IRQ_REPLAY 4 /* IRQ has been replayed but not acked yet */
+#define IRQ_AUTODETECT 8 /* IRQ is being autodetected */
+#define IRQ_WAITING 16 /* IRQ not yet seen - for autodetection */
+#define IRQ_LEVEL 32 /* IRQ level triggered */
+#define IRQ_MASKED 64 /* IRQ masked - shouldn't be seen again */
+#define IRQ_PER_CPU 128 /* IRQ is per CPU */
/*
* Interrupt controller descriptor. This is all we need
@@ -62,6 +61,7 @@
struct irqaction *action; /* IRQ action list */
unsigned int depth; /* nested irq disables */
spinlock_t lock;
+ unsigned int pending;
} ____cacheline_aligned irq_desc_t;
extern irq_desc_t irq_desc [NR_IRQS];
next reply other threads:[~2002-09-09 9:46 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-09-09 9:49 zwane [this message]
2002-09-09 14:34 ` Robert Love
2002-09-09 18:23 ` Zwane Mwaikambo
-- strict thread matches above, loose matches on Subject: below --
2002-09-09 10:13 zwane
2002-09-07 22:34 Zwane Mwaikambo
2002-09-08 7:55 ` Ingo Molnar
2002-09-08 8:15 ` Ingo Molnar
2002-09-08 10:38 ` Zwane Mwaikambo
2002-09-08 13:31 ` Zwane Mwaikambo
2002-09-08 16:59 ` Zwane Mwaikambo
2002-09-08 22:01 ` Linus Torvalds
2002-09-08 23:03 ` Jeff Garzik
2002-09-09 6:49 ` bert hubert
2002-09-09 16:24 ` Linus Torvalds
2002-09-09 10:06 ` Ingo Molnar
2002-09-09 15:06 ` Linus Torvalds
2002-09-09 18:44 ` Ingo Molnar
2002-09-09 18:53 ` Linus Torvalds
2002-09-09 19:37 ` Zwane Mwaikambo
2002-09-09 19:23 ` Ingo Molnar
2002-09-09 20:05 ` Zwane Mwaikambo
2002-09-09 20:08 ` Andrew Morton
2002-09-10 15:05 ` David Woodhouse
2002-09-10 15:32 ` Alan Cox
2002-09-10 22:37 ` Gérard Roudier
2002-09-09 19:38 ` Maciej W. Rozycki
2002-09-10 11:55 ` Stephan von Krawczynski
2002-09-10 18:07 ` Gunther Mayer
2002-09-10 18:38 ` Zwane Mwaikambo
2002-09-10 7:46 ` Rogier Wolff
2002-09-08 10:57 ` Zwane Mwaikambo
2002-09-09 20:40 ` Alan Cox
2002-09-09 20:48 ` Andre Hedrick
2002-09-10 17:47 ` Zwane Mwaikambo
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=20020909094959.5A955BC51@hemi.commfireservices.com \
--to=zwane@mwaikambo.name \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=rml@tech9.net \
/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®