Disabling interrupts and masking interrupts
Hello, what is the difference between disabling interrupts and masking interrupts ? Disabling interrupts is done, AFAIK, with irq_disable(). (see below) Can someone gives an example of how to mask interrupts with x86/x86_64 ? irq_disable() in x86 goes to native_irq_disable(), which eventually calls assembler "cli" command: CLI clears the IF bit in the flags. static inline void native_irq_disable(void) { asm volatile("cli": : :"memory"); } see arch/x86/include/asm/irqflags.h rgs, Kevin
On Thu, Mar 7, 2013 at 7:28 PM, Kevin Wilson <wkevils@gmail.com> wrote:
Hello, what is the difference between disabling interrupts and masking interrupts ? Disabling interrupts is done, AFAIK, with irq_disable(). Disabling interrupts means that you have disabled the source of interrupt. Masking means that you are not(CPU) going to handle the interrupts until it is unmasked. (see below) Can someone gives an example of how to mask interrupts with x86/x86_64 ? Not familiar with x86. Try asking in kernel mailing list.I guess you will get more help there.
irq_disable() in x86 goes to native_irq_disable(), which eventually calls assembler "cli" command:
CLI clears the IF bit in the flags.
static inline void native_irq_disable(void) { asm volatile("cli": : :"memory"); } see arch/x86/include/asm/irqflags.h
rgs, Kevin
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
Hi. First: Thanks, Anish, for your quick response. Does this mean that once you are disabling interrupts, these interrupts are lost ? even later, when we will enable interrupts, the interrupts from the past that should have been created (but interrupts were disabled at that time interval) are in fact lost? And once you mask interrupts, these interrupts are not lost, but these masked interrupts will be handled later when the interrupt is unmasked ? Did I understand correctly ? rgs Kevin On Thu, Mar 7, 2013 at 5:00 PM, anish singh <anish198519851985@gmail.com> wrote:
On Thu, Mar 7, 2013 at 7:28 PM, Kevin Wilson <wkevils@gmail.com> wrote:
Hello, what is the difference between disabling interrupts and masking interrupts ? Disabling interrupts is done, AFAIK, with irq_disable(). Disabling interrupts means that you have disabled the source of interrupt. Masking means that you are not(CPU) going to handle the interrupts until it is unmasked. (see below) Can someone gives an example of how to mask interrupts with x86/x86_64 ? Not familiar with x86. Try asking in kernel mailing list.I guess you will get more help there.
irq_disable() in x86 goes to native_irq_disable(), which eventually calls assembler "cli" command:
CLI clears the IF bit in the flags.
static inline void native_irq_disable(void) { asm volatile("cli": : :"memory"); } see arch/x86/include/asm/irqflags.h
rgs, Kevin
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
On Thu, Mar 7, 2013 at 8:47 PM, Kevin Wilson <wkevils@gmail.com> wrote:
Hi. First: Thanks, Anish, for your quick response.
Does this mean that once you are disabling interrupts, these interrupts are lost ? even later, when we will enable interrupts, the interrupts from the past that should have been created (but interrupts were disabled at that time interval) are in fact lost? When you disable the interrupt source that means that interrupt didn't happen itself.
And once you mask interrupts, these interrupts are not lost, but these masked interrupts will be handled later when the interrupt is unmasked ? yes.There are two kind of masking here one is at the interrupt controller side and other at the processor side. When you have masked in the interrupt controller than it is just that the controller will later send the interrupt to the processor when you have done unmask operation. Whereas for processor side masking, if the interrupt which you have raised is currently being handled and if the same interrupt has come then all you will do is to mark it pending and handle it later when you are done with the current interrupt. Have a look at handle_edge_irq in kernel/irq/
Did I understand correctly ? rgs Kevin
On Thu, Mar 7, 2013 at 5:00 PM, anish singh <anish198519851985@gmail.com> wrote:
On Thu, Mar 7, 2013 at 7:28 PM, Kevin Wilson <wkevils@gmail.com> wrote:
Hello, what is the difference between disabling interrupts and masking interrupts ? Disabling interrupts is done, AFAIK, with irq_disable(). Disabling interrupts means that you have disabled the source of interrupt. Masking means that you are not(CPU) going to handle the interrupts until it is unmasked. (see below) Can someone gives an example of how to mask interrupts with x86/x86_64 ? Not familiar with x86. Try asking in kernel mailing list.I guess you will get more help there.
irq_disable() in x86 goes to native_irq_disable(), which eventually calls assembler "cli" command:
CLI clears the IF bit in the flags.
static inline void native_irq_disable(void) { asm volatile("cli": : :"memory"); } see arch/x86/include/asm/irqflags.h
rgs, Kevin
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
On Thu, 07 Mar 2013 17:17:19 +0200, Kevin Wilson said:
Does this mean that once you are disabling interrupts, these interrupts are lost ? even later, when we will enable interrupts, the interrupts from the past that should have been created (but interrupts were disabled at that time interval) are in fact lost?
Level-triggered interruots will go off once interrupts are re-enabled, assuming that the device has kept the level set and not given up and timed out. Edge-trittered interrupts are gone. That's part of why most hardware doesn't use edge triggers - it's just too hard to guarantee proper device driver operation. Also, in common usage, "disabled interrupts" means that you're not listening to *any* interrupts, while "masked" means "we're not listening to *this* interrupt source, even if we *are* accepting interrupts from other sources". The difference is that sometimes the CPU is doing stuff that it would be potentially screwed if *any* interrupt happened, so we disable them. Other times we're busy inside a device driver, and we're in a critical section for that device - but it's safe for other devices to interrupt. So to improve latency we mask off just the one interrupt not all of them.
Hi, On Thu, Mar 7, 2013 at 8:53 AM, <Valdis.Kletnieks@vt.edu> wrote:
On Thu, 07 Mar 2013 17:17:19 +0200, Kevin Wilson said:
Does this mean that once you are disabling interrupts, these interrupts are lost ? even later, when we will enable interrupts, the interrupts from the past that should have been created (but interrupts were disabled at that time interval) are in fact lost?
Level-triggered interruots will go off once interrupts are re-enabled, assuming that the device has kept the level set and not given up and timed out.
Edge-trittered interrupts are gone. That's part of why most hardware doesn't use edge triggers - it's just too hard to guarantee proper device driver operation.
In my experience, edges triggered interrupts are always latched by the HW when they arrive. If another edge comes along between the initial edge and the time that the interrupt is cleared, then this second edge is lost. The fact that an interrupt is pending will still be retained though, and as soon as interrupts are enabled, then the interrupt handler will fire. So, it's quite often the case that you want to clear ("knock down") the interrupt as soon as possible inside your drive to help reduce the window where back-to-back edges will miss the second edge. You'll never miss the first edge.
Also, in common usage, "disabled interrupts" means that you're not listening to *any* interrupts, while "masked" means "we're not listening to *this* interrupt source, even if we *are* accepting interrupts from other sources".
Normally disabling interrupts is just another form of masking, it just happens to mask all of the interrupts rather than one particular one. Even when you disable interrupts, you typically still have access to the unmasked interrupt state. -- Dave Hylands Shuswap, BC, Canada http://www.davehylands.com
On Thu, 07 Mar 2013 09:28:58 -0800, Dave Hylands said:
In my experience, edges triggered interrupts are always latched by the HW when they arrive. If another edge comes along between the initial edge and the time that the interrupt is cleared, then this second edge is lost. The fact that an interrupt is pending will still be retained though, and as soon as interrupts are enabled, then the interrupt handler will fire.
Actually, what you're describing there is hardware that converts edge triggered to level triggered precisely because edge triggered stuff sucks otherwise. ;)
Also, in common usage, "disabled interrupts" means that you're not listening to *any* interrupts, while "masked" means "we're not listening to *this* interrupt source, even if we *are* accepting interrupts from other sources".
Normally disabling interrupts is just another form of masking, it just happens to mask all of the interrupts rather than one particular one. Even when you disable interrupts, you typically still have access to the unmasked interrupt state.
Yes, but it;'s still useful to distinguish between the two cases. Also, on many hardware architectures, the actual code to 'disable all' and 'disable one' is very different (on X86, 'cli' does "all" very fast, ignoring exactly one takes some more doing)
Hi, Sorry about my previous post in HTML. On Thu, Mar 7, 2013 at 9:40 AM, <Valdis.Kletnieks@vt.edu> wrote:
On Thu, 07 Mar 2013 09:28:58 -0800, Dave Hylands said:
In my experience, edges triggered interrupts are always latched by the
HW
when they arrive. If another edge comes along between the initial edge and the time that the interrupt is cleared, then this second edge is lost. The fact that an interrupt is pending will still be retained though, and as soon as interrupts are enabled, then the interrupt handler will fire.
Actually, what you're describing there is hardware that converts edge triggered to level triggered precisely because edge triggered stuff sucks otherwise. ;)
The HW is just a flipflop. All of the ARM/MIPS processors I've worked with include this. If there is a processor which doesn't include this, then yeah, edge triggered interrupts would be almost impossible to deal with reliably. One other difference between edge and level triggered interrupts is that with level triggered interrupts, if an interrupt is asserted while interrupts are disabled/masked and it becomes deasserted before interrupts are enabled/unmasked then that interrupt will be lost. This is pathalogical, since the interrupt shouldn't get deasserted on its own, it normally requires that the driver access some register or something to deassert the interrupt. I guess it could also happen if you have a device which generated a short pulse (typically what edge-triggered devices would do) and the processor was configured to use a level triggered interrupt. If you code the driver properly, there is really very little difference between edge and level triggered interrupts when you're dealing with a single device driving the interrupt line. A level triggered interrupt is really just an edge triggered interrupt with a long assertion time :) Both edge and level triggered will miss interrupts if the interrupt arrival rate is faster than the interrupt handler can deal with. I guess one place where things gets different is when you're dealing with offchip peripherals. Say you have an ADC chip sitting on a SPI bus. If it generated a level triggered interrupt, then you need to actually send a SPI command to the chip to clear the interrupt. With edge triggered interrupts you don't "need" to send a command, unless the chip otherwise requires it (it may still have some type of status register which requires clearing before the chip generates another interrupt). -- Dave Hylands Shuswap, BC, Canada http://www.davehylands.com
Hi, Are you sure about that Edge-triggered interrupts are gone and that most hardware doesn't use edge triggers ? For example, on my x86_64, I get 9 edge interrupts: 0: 127 0 IO-APIC-edge timer 1: 3 0 IO-APIC-edge i8042 4: 1 1 IO-APIC-edge 8: 0 1 IO-APIC-edge rtc0 12: 1 3 IO-APIC-edge i8042 14: 0 0 IO-APIC-edge ata_piix 15: 0 0 IO-APIC-edge ata_piix 43: 30897 7 PCI-MSI-edge em1 44: 306 308 PCI-MSI-edge snd_hda_intel Also I remember I saw in a book about Kernel that edge interrupts are more common than level interrupts. rgs Kevin On Thu, Mar 7, 2013 at 6:53 PM, <Valdis.Kletnieks@vt.edu> wrote:
On Thu, 07 Mar 2013 17:17:19 +0200, Kevin Wilson said:
Does this mean that once you are disabling interrupts, these interrupts are lost ? even later, when we will enable interrupts, the interrupts from the past that should have been created (but interrupts were disabled at that time interval) are in fact lost?
Level-triggered interruots will go off once interrupts are re-enabled, assuming that the device has kept the level set and not given up and timed out.
Edge-trittered interrupts are gone. That's part of why most hardware doesn't use edge triggers - it's just too hard to guarantee proper device driver operation.
Also, in common usage, "disabled interrupts" means that you're not listening to *any* interrupts, while "masked" means "we're not listening to *this* interrupt source, even if we *are* accepting interrupts from other sources".
The difference is that sometimes the CPU is doing stuff that it would be potentially screwed if *any* interrupt happened, so we disable them. Other times we're busy inside a device driver, and we're in a critical section for that device - but it's safe for other devices to interrupt. So to improve latency we mask off just the one interrupt not all of them.
participants (4)
-
anish singh -
Dave Hylands -
Kevin Wilson -
Valdis.Kletnieks@vt.edu