RE: Interrupt Handling Doubts ....

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I agree with you that, do_IRQ() is called for each hardware interrupt
generated, but in case of shared interrupts one interrupt line can be
shared between different driver (devices), so in shared interrupt case
each entry in irq_desc[] array will point to queue of handlers which
will be called one by one when the interrupt occurs.

>From do_IRQ() function, handle_IRQ_event() function is called to invoke
all the handlers in queue for that IRQ (see the code of do_IRQ()
http://lxr.linux.no/source/arch/i386/kernel/irq.c?v=2.4.21#L563).
handle_IRQ_event() function is responsible for invoking all the handlers
registered for that IRQ by different drivers. 

What I am saying is that, in handle_IRQ_event() function
(http://lxr.linux.no/source/arch/i386/kernel/irq.c?v=2.4.21#L437) code
is only checking the flag of first handler in this queue of handlers,
that means it is only checking the flag of handler pointed by
'irq_desc[irq]" and does not check the flag of each handler in queue
before invoking the handler. 

This can lead to some problems, like if the first handler for that IRQ
number wants itself to be invoked as a slow interrupt handler (handler
flag not set to SA_INTERRUPT), the kernel will call __sti() function to
enable the interrupts on local CPU before invoking the interrupt
handler. Now for the second, third or any other handler in queue want
itself to be invoked as fast interrupt handler (flag set to
SA_INTERRUPT), kernel should call __cli() before invoking that
particular handler, which it is not doing right now.


In 2.4 kernel, the code in handle_IRQ_event is like this"

    if (!(action->flags & SA_INTERRUPT))
                __sti();
 
     do {
             status |= action->flags;
              action->handler(irq, action->dev_id, regs);
              action = action->next;
     } while (action);


Where as what I think the code should be as follows to check the flag of
each handler before actually invoking it:

     do {
	        if (!(action->flags & SA_INTERRUPT))
                  __sti();
		  else
		      __cli();
              status |= action->flags;
              action->handler(irq, action->dev_id, regs);
              action = action->next;
     } while (action);



I clarified the same thing with Rubini also, he also agrees to it that
it might be a bug.
I hope I made my things clear.

Cheers !!
Gaurav
 


-----Original Message-----
From: manish regmi [mailto:manish_regmi@xxxxxxxxxxx] 
Sent: Wednesday, September 15, 2004 2:36 PM
To: Dhiman, Gaurav
Cc: kernelnewbies@xxxxxxxxxxxx; drizzd@xxxxxx
Subject: RE: Interrupt Handling Doubts ....


>
>I think the bug is that we are checking the flag of only first handler
>and not checking the flags of other handlers in queue. But I don't
agree
>to your point that if there are arbitrary number f handlers of an IRQ,
>we can not handle them fast. We can do that enabling or disabling the
>interrupts according to the flag of each handler in queue.
>
>Gaurav
>
>
>-----Original Message-----
>From: Clemens Buchacher [mailto:drizzd@xxxxxx]
>Sent: Wednesday, September 15, 2004 9:50 PM
>To: Dhiman, Gaurav; kernelnewbies@xxxxxxxxxxxx
>Subject: Re: Interrupt Handling Doubts ....
>
>On Fri, Sep 10, 2004 at 01:47:44PM +0200, Clemens Buchacher wrote:
> > > -          In handle_IRQ_event() function
> > > (http://lxr.linux.no/source/arch/i386/kernel/irq.c?v=2.4.21#L437),
> > > before calling the actual interrupt handler why are we checking
the
>flag
> > > of only first handler in list.
> >
> > Good point. I guess that's a bug then.
>
>OTOH, using both SA_INTERRUPT _and_ SA_SHIRQ is a bug anyhow, because
>the interrupt handler cannot guarantee to be fast any more if an
>arbitrary number of interrupt handlers can be run. The kernel could
>issue a warning though...
>

I dont understand  what first handler are you talking about.
(continuation form my last post.)
As you know each irq is handles through do_irq() function. This function

runs when any hardware interrupt occurs. and there are irqaction
structures 
for each hardware. so, the kernel runs  handler corresponding to the 
hardware.
eg, irq_desc[0] is for timer interrupt because in pc 8259a chips irq 0
is 
for timer.
SO, it is cheking the flags of that irq_action only and it calls its
handler 
only.

to learn about interrupts, first you need to see 8259a chip and inter
system 
programmers manual.
for PIC,
http://www.nondot.org/~sabre/os/articles/MiscellaneousDevices/

for intel manual,
http://www.x86.org/intel.doc/686manuals.htm (see system programing
guide)
http://developer.intel.com

regards manish

_________________________________________________________________
Add photos to your e-mail with MSN 8. Get 2 months FREE*. 
http://join.msn.com/?page=features/featuredemail



--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/



[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux