mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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, &regs, 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];

             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®