The generic request_irq/setup_irq code should support the SA_PERCPU_IRQ flag.
This patch was posted previously, but this one should build on all arch's.
Signed-off-by: Dimitri Sivanich <[email protected]>
Index: linux-2.6.15/kernel/irq/manage.c
===================================================================
--- linux-2.6.15.orig/kernel/irq/manage.c 2006-03-20 13:11:01.766522017 -0600
+++ linux-2.6.15/kernel/irq/manage.c 2006-03-21 15:26:12.305876769 -0600
@@ -206,6 +206,10 @@ int setup_irq(unsigned int irq, struct i
* The following block of code has to be executed atomically
*/
spin_lock_irqsave(&desc->lock,flags);
+#if defined(ARCH_HAS_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ)
+ if (new->flags & SA_PERCPU_IRQ)
+ desc->status |= IRQ_PER_CPU;
+#endif
p = &desc->action;
if ((old = *p) != NULL) {
/* Can't share interrupts unless both agree to */
Dimitri Sivanich <[email protected]> wrote:
>
> The generic request_irq/setup_irq code should support the SA_PERCPU_IRQ flag.
>
> This patch was posted previously, but this one should build on all arch's.
>
> Signed-off-by: Dimitri Sivanich <[email protected]>
>
> Index: linux-2.6.15/kernel/irq/manage.c
> ===================================================================
> --- linux-2.6.15.orig/kernel/irq/manage.c 2006-03-20 13:11:01.766522017 -0600
> +++ linux-2.6.15/kernel/irq/manage.c 2006-03-21 15:26:12.305876769 -0600
> @@ -206,6 +206,10 @@ int setup_irq(unsigned int irq, struct i
> * The following block of code has to be executed atomically
> */
> spin_lock_irqsave(&desc->lock,flags);
> +#if defined(ARCH_HAS_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ)
> + if (new->flags & SA_PERCPU_IRQ)
> + desc->status |= IRQ_PER_CPU;
> +#endif
> p = &desc->action;
> if ((old = *p) != NULL) {
> /* Can't share interrupts unless both agree to */
hm. Last time around I pointed out that we should be checking that all
handlers for this IRQ agree about the percpuness. What happened to
that?
On Tue, 21 Mar 2006, Andrew Morton wrote:
> hm. Last time around I pointed out that we should be checking that all
> handlers for this IRQ agree about the percpuness. What happened to
> that?
Maybe simply add this patch on top?
Index: linux-2.6.16-rc6-mm2/kernel/irq/manage.c
===================================================================
--- linux-2.6.16-rc6-mm2.orig/kernel/irq/manage.c 2006-03-21 15:41:26.000000000 -0800
+++ linux-2.6.16-rc6-mm2/kernel/irq/manage.c 2006-03-21 15:43:15.000000000 -0800
@@ -204,6 +204,8 @@ int setup_irq(unsigned int irq, struct i
#if defined(ARCH_HAS_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ)
if (new->flags & SA_PERCPU_IRQ)
desc->status |= IRQ_PER_CPU;
+ else
+ BUG_ON(desc->status & IRQ_PER_CPU);
#endif
p = &desc->action;
if ((old = *p) != NULL) {
On Tue, Mar 21, 2006 at 03:37:47PM -0800, Andrew Morton wrote:
> hm. Last time around I pointed out that we should be checking that all
> handlers for this IRQ agree about the percpuness. What happened to
> that?
I believe this version has what you are looking for.
Signed-off-by: Dimitri Sivanich <[email protected]>
Index: linux-2.6.15/kernel/irq/manage.c
===================================================================
--- linux-2.6.15.orig/kernel/irq/manage.c 2006-03-20 13:11:01.766522017 -0600
+++ linux-2.6.15/kernel/irq/manage.c 2006-03-21 18:44:52.297990979 -0600
@@ -209,10 +209,14 @@ int setup_irq(unsigned int irq, struct i
p = &desc->action;
if ((old = *p) != NULL) {
/* Can't share interrupts unless both agree to */
- if (!(old->flags & new->flags & SA_SHIRQ)) {
- spin_unlock_irqrestore(&desc->lock,flags);
- return -EBUSY;
- }
+ if (!(old->flags & new->flags & SA_SHIRQ))
+ goto mismatch;
+
+#if defined(ARCH_HAS_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ)
+ /* All handlers must agree on per-cpuness */
+ if ((old->flags & IRQ_PER_CPU) != (new->flags & IRQ_PER_CPU))
+ goto mismatch;
+#endif
/* add new interrupt at end of irq queue */
do {
@@ -223,7 +227,10 @@ int setup_irq(unsigned int irq, struct i
}
*p = new;
-
+#if defined(ARCH_HAS_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ)
+ if (new->flags & SA_PERCPU_IRQ)
+ desc->status |= IRQ_PER_CPU;
+#endif
if (!shared) {
desc->depth = 0;
desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT |
@@ -241,6 +248,12 @@ int setup_irq(unsigned int irq, struct i
register_handler_proc(irq, new);
return 0;
+
+mismatch:
+ spin_unlock_irqrestore(&desc->lock, flags);
+ printk(KERN_ERR "%s: irq handler mismatch\n", __FUNCTION__);
+ dump_stack();
+ return -EBUSY;
}
/*
> + else
> + BUG_ON(desc->status & IRQ_PER_CPU);
I see that you are a member of the school of brutalism ! :)
Ben.