Re: [patch] voluntary-preempt-2.6.8.1-P2

Takashi Iwai
2004-08-18T15:48:39Z

At Wed, 18 Aug 2004 17:26:16 +0200,
Thomas Charbonnel wrote:
>
> I was thinking more of something like this :
>
> --- irq.c.orig 2004-08-16 14:26:34.000000000 +0200
> +++ irq.c 2004-08-18 17:23:18.011059064 +0200
> @@ -955,11 +955,16 @@
> return -EBUSY;
> }
>
> - /* add new interrupt at end of irq queue */
> - do {
> - p = &old->next;
> - old = *p;
> - } while (old);
> + if (new->flags & SA_INTERRUPT)
> + /* add interrupt at the start of the queue */
> + new->next = old;
> + else
> + /* add new interrupt at end of irq queue */
> + do {
> + p = &old->next;
> + old = *p;
> + } while (old);
> +
> shared = 1;
> }

Ok, how about this one? Together with your patch, the irq is turned
on for handlers without SA_INTERRUPT.

Takashi

--- linux/arch/i386/kernel/irq.c 2004-08-18 15:15:18.000000000 +0200
+++ linux/arch/i386/kernel/irq.c 2004-08-18 17:42:57.454819403 +0200
@@ -219,15 +219,23 @@ inline void synchronize_irq(unsigned int
asmlinkage int handle_IRQ_event(unsigned int irq,
struct pt_regs *regs, struct irqaction *action)
{
- int status = 1; /* Force the "do bottom halves" bit */
- int retval = 0;
-
- if (!(action->flags & SA_INTERRUPT))
- local_irq_enable();
+ int status;
+ int ret, retval = 0;
+ int irq_off = 1;

+ status = 0;
do {
- status |= action->flags;
- retval |= action->handler(irq, action->dev_id, regs);
+ /* Assume that all SA_INTERRUPT handlers are at the head
+ * of the irq queue
+ */
+ if (irq_off && ! (action->flags & SA_INTERRUPT)) {
+ local_irq_enable();
+ irq_off = 0;
+ }
+ ret = action->handler(irq, action->dev_id, regs);
+ if (ret)
+ status |= action->flags;
+ retval |= ret;
action = action->next;
} while (action);
if (status & SA_SAMPLE_RANDOM)
@@ -955,11 +963,16 @@ int setup_irq(unsigned int irq, struct i
return -EBUSY;
}

- /* add new interrupt at end of irq queue */
- do {
- p = &old->next;
- old = *p;
- } while (old);
+ if (new->flags & SA_INTERRUPT)
+ /* add interrupt at the start of the queue */
+ new->next = old;
+ else
+ /* add new interrupt at end of irq queue */
+ do {
+ p = &old->next;
+ old = *p;
+ } while (old);
+
shared = 1;
}