ARM: gic: use handle_fasteoi_irq for SPIs
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Currently, the gic uses handle_level_irq for handling SPIs (Shared Peripheral Interrupts), requiring active interrupts to be masked at the distributor level during IRQ handling.
On a virtualised system, only the CPU interfaces are virtualised in hardware. Accesses to the distributor must be trapped by the hypervisor, adding latency to the critical interrupt path in Linux.
This patch modifies the GIC code to use handle_fasteoi_irq for handling interrupts, which only requires us to signal EOI to the CPU interface when handling is complete. Cascaded IRQ handling is also updated so that EOI is signalled after handling.
Note that commit 846afbd1 ("GIC: Dont disable INT in ack callback") broke cascading interrupts by forgetting to add IRQ masking. This is no longer an issue because the unmask call is now unnecessary.
Tested on Versatile Express and Realview EB (1176 w/ cascaded GICs).
---
Reposting because I forgot the CCs the first time round...
arch/arm/common/gic.c | 23 +++++++++-------------- 1 files changed, 9 insertions(+), 14 deletions(-)
arch/arm/common/gic.c +9 -14
@@ -71,13 +71,6 @@ static inline unsigned int gic_irq(struct irq_data *d)/* * Routines to acknowledge, disable and enable interrupts */ -static void gic_ack_irq (struct irq_data *d) -{ -spin_lock (&irq_controller_lock); -writel (gic_irq (d),gic_cpu_base (d) +GIC_CPU_EOI ); -spin_unlock (&irq_controller_lock); -} -static void gic_mask_irq (struct irq_data *d) {u32 mask =1 << (d->irq %32 );
@@ -96,6 +89,11 @@ static void gic_unmask_irq(struct irq_data *d)spin_unlock (&irq_controller_lock); } +static void gic_eoi_irq (struct irq_data *d) +{ +writel (gic_irq (d),gic_cpu_base (d) +GIC_CPU_EOI ); +} +static int gic_set_type (struct irq_data *d,unsigned int type) {void __iomem *base =gic_dist_base (d);
@@ -174,9 +172,6 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)unsigned int cascade_irq, gic_irq;unsigned long status; -/* primary controller ack'ing */ - chip->irq_ack (&desc->irq_data); -spin_lock (&irq_controller_lock); status =readl (chip_data->cpu_base +GIC_CPU_INTACK );spin_unlock (&irq_controller_lock);
@@ -192,15 +187,15 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)generic_handle_irq (cascade_irq); out: -/* primary controller unmasking */ - chip->irq_unmask (&desc->irq_data); +/* primary controller EOI */ + chip->irq_eoi (&desc->irq_data); }static struct irq_chip gic_chip = { .name ="GIC" , - .irq_ack = gic_ack_irq, .irq_mask = gic_mask_irq, .irq_unmask = gic_unmask_irq, + .irq_eoi = gic_eoi_irq, .irq_set_type = gic_set_type, #ifdef CONFIG_SMP .irq_set_affinity = gic_set_cpu,
@@ -275,7 +270,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic,for (i = irq_start; i < irq_limit; i++) {set_irq_chip (i, &gic_chip);set_irq_chip_data (i, gic); -set_irq_handler (i, handle_level_irq); +set_irq_handler (i, handle_fasteoi_irq);set_irq_flags (i,IRQF_VALID |IRQF_PROBE ); }
Signature · 1 line
1.7.0.4
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Quoted 4 lines · Will Deacon
Currently, the gic uses
handle_level_irqfor handling SPIs (Shared Peripheral Interrupts), requiring active interrupts to be masked at the distributor level during IRQ handling.
Quoted 8 lines
On a virtualised system, only the CPU interfaces are virtualised in hardware. Accesses to the distributor must be trapped by the hypervisor, adding latency to the critical interrupt path in Linux.
This patch modifies the GIC code to use
handle_fasteoi_irqfor handling interrupts, which only requires us to signal EOI to the CPU interface when handling is complete. Cascaded IRQ handling is also updated so that EOI is signalled after handling.
Several of the platforms using the GIC also have GPIO code which uses set_irq_chained_handler(). I think you will have to modify all of these to call irq_eoi() appropriately and not the other functions. Some of these will also likely be used with other interrupt handlers than the GIC, though.
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Hi Rabin,
Quoted 14 lines · Will Deacon
Quoted 4 lines
Currently, the gic uses
handle_level_irqfor handling SPIs (Shared Peripheral Interrupts), requiring active interrupts to be masked at the distributor level during IRQ handling.Quoted 8 lines
On a virtualised system, only the CPU interfaces are virtualised in hardware. Accesses to the distributor must be trapped by the hypervisor, adding latency to the critical interrupt path in Linux.
This patch modifies the GIC code to use
handle_fasteoi_irqfor handling interrupts, which only requires us to signal EOI to the CPU interface when handling is complete. Cascaded IRQ handling is also updated so that EOI is signalled after handling.
Quoted 5 lines
Several of the platforms using the GIC also have GPIO code which uses
set_irq_chained_handler(). I think you will have to modify all of these to callirq_eoi()appropriately and not the other functions. Some of these will also likely be used with other interrupt handlers than the GIC, though.
Hmm, I had a quick look at some platforms that do this (mach-dove and plat-spear) and I don't see what the problem is. They use their own irq_chip structures, with their own function pointers, so this doesn't seem to relate to the GIC at all. What am I missing?!
Cheers,
Will
A message that is not in the archive (sent off-list or not yet received): -4413647205110644369@unknownmsgid
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Quoted 12 lines · Will Deacon
Quoted 11 lines · Will Deacon
Quoted 4 lines
This patch modifies the GIC code to use
handle_fasteoi_irqfor handling interrupts, which only requires us to signal EOI to the CPU interface when handling is complete. Cascaded IRQ handling is also updated so that EOI is signalled after handling.Several of the platforms using the GIC also have GPIO code which uses
set_irq_chained_handler(). ?I think you will have to modify all of these to callirq_eoi()appropriately and not the other functions. Some of these will also likely be used with other interrupt handlers than the GIC, though.
Quoted 4 lines
Hmm, I had a quick look at some platforms that do this (mach-dove and plat-spear) and I don't see what the problem is. They use their own
irq_chipstructures, with their own function pointers, so this doesn't seem to relate to the GIC at all. What am I missing?!
The chained handlers are usually installed on GIC interrupts. So, when a chained handler does something like this
desc->irq_data.chip->irq_unmask(&desc->irq_data);
the desc->irq_data.chip refers to the gic_chip. These handlers are written with the knowledge of what flow handler the GIC uses and what functions it implements, so when you change that, the chained handler code will not work correctly, and they'll need to be updated just like you've updated the cascade IRQ handler.
In fact, I think that 846afbd1 ("GIC: Dont disable INT in ack callback") has broken not just GIC cascading interrupts but assumptions in several of these chained handlers, since several of them seem to have been written assuming (invalidly) that irq_ack() masks the interrupt, but this is no longer the case with the GIC after that commit.
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Hi Rabin,
Quoted 14 lines
Quoted 10 lines
Quoted 5 lines
Several of the platforms using the GIC also have GPIO code which uses
set_irq_chained_handler(). I think you will have to modify all of these to callirq_eoi()appropriately and not the other functions. Some of these will also likely be used with other interrupt handlers than the GIC, though.Hmm, I had a quick look at some platforms that do this (mach-dove and plat-spear) and I don't see what the problem is. They use their own
irq_chipstructures, with their own function pointers, so this doesn't seem to relate to the GIC at all. What am I missing?!The chained handlers are usually installed on GIC interrupts. So, when a chained handler does something like this
Quoted 7 lines
desc->irq_data.chip->irq_unmask(&desc->irq_data);the
desc->irq_data.chiprefers to thegic_chip. These handlers are written with the knowledge of what flow handler the GIC uses and what functions it implements, so when you change that, the chained handler code will not work correctly, and they'll need to be updated just like you've updated the cascade IRQ handler.
Ah yes, thanks for the explanation. After looking at the plat-omap code I finally understand what's going on and I can't help but feel that the chained GPIO handlers are terminally broken! The generic irq chip high-level handlers (handle_{edge,level}_irq for example) at least check to see if the irq_chip functions are non-NULL before calling them.
Ideally, the chained handler would be able to query the irq_chip to find out what types of IRQ flow-control it supports and then assume that behaviour.
Quoted 5 lines
In fact, I think that
846afbd1("GIC: Dont disable INT in ack callback") has broken not just GIC cascading interrupts but assumptions in several of these chained handlers, since several of them seem to have been written assuming (invalidly) thatirq_ack()masks the interrupt, but this is no longer the case with the GIC after that commit.
Yep - it was further reaching that I originally thought. The question now is:
is it worth changing all of these handlers or are we better off hacking the gic code so that .irq_ack calls .irq_eoi? In the case of the latter, your performance will suck in a virtualised environment, but that's better than broken.
Cheers,
Will
A message that is not in the archive (sent off-list or not yet received): 146267380211262372@unknownmsgid
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
(adding tglx)
Quoted 22 lines · Will Deacon
Quoted 14 lines
Quoted 10 lines
Quoted 5 lines
Several of the platforms using the GIC also have GPIO code which uses
set_irq_chained_handler(). ?I think you will have to modify all of these to callirq_eoi()appropriately and not the other functions. Some of these will also likely be used with other interrupt handlers than the GIC, though.Hmm, I had a quick look at some platforms that do this (mach-dove and plat-spear) and I don't see what the problem is. They use their own
irq_chipstructures, with their own function pointers, so this doesn't seem to relate to the GIC at all. What am I missing?!The chained handlers are usually installed on GIC interrupts. ?So, when a chained handler does something like this
Quoted 7 lines
? ? ?
desc->irq_data.chip->irq_unmask(&desc->irq_data);the
desc->irq_data.chiprefers to thegic_chip. ?These handlers are written with the knowledge of what flow handler the GIC uses and what functions it implements, so when you change that, the chained handler code will not work correctly, and they'll need to be updated just like you've updated the cascade IRQ handler.
Quoted 8 lines
Ah yes, thanks for the explanation. After looking at the plat-omap code I finally understand what's going on and I can't help but feel that the chained GPIO handlers are terminally broken! The generic irq chip high-level handlers (handle_{edge,level}_irq for example) at least check to see if the
irq_chipfunctions are non-NULL before calling them.Ideally, the chained handler would be able to query the
irq_chipto find out what types of IRQ flow-control it supports and then assume that behaviour.
Thomas, suggestions on how best to handle this? (Some of these chained handlers are the ones in plat-omap/gpio.c, plat-nomadik/gpio.c, and mach-s5pv310/irq-combiner.c.)
Quoted 11 lines
Quoted 6 lines
In fact, I think that
846afbd1("GIC: Dont disable INT in ack callback") has broken not just GIC cascading interrupts but assumptions in several of these chained handlers, since several of them seem to have been written assuming (invalidly) thatirq_ack()masks the interrupt, but this is no longer the case with the GIC after that commit.Yep - it was further reaching that I originally thought. The question now is:
is it worth changing all of these handlers or are we better off hacking the gic code so that .irq_ack calls .irq_eoi? In the case of the latter, your performance will suck in a virtualised environment, but that's better than broken.
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Quoted 7 lines · Rabin Vincent
Quoted 6 lines · Will Deacon
Ah yes, thanks for the explanation. After looking at the plat-omap code I finally understand what's going on and I can't help but feel that the chained GPIO handlers are terminally broken! The generic irq chip high-level handlers (handle_{edge,level}_irq for example) at least check to see if the
irq_chipfunctions are non-NULL before calling them.
Quoted 6 lines
Quoted 2 lines
Ideally, the chained handler would be able to query the
irq_chipto find out what types of IRQ flow-control it supports and then assume that behaviour.Thomas, suggestions on how best to handle this? (Some of these chained handlers are the ones in
plat-omap/gpio.c,plat-nomadik/gpio.c, andmach-s5pv310/irq-combiner.c.)
I'm not much of a fan of those chained handlers. They work fine, when they are tied into the irq_chip implementation of a SoC where the chained handler code is 1:1 related to that irq_chip.
Once you start assigning those handlers somewhere else or even using the same handler for different underlying primary irq chips, then it's a lost case and wreckage like this is just lurking around the corner.
The only sane way to deal with this is to install a regular interrupt handler with request/setup_irq() and do the demultiplexing from there. That way the demux handler does not have to worry about the underlying primary chip at all. It does not have to worry whether this chip uses level, fasteoi, edge or whatever. It just works.
The runtime overhead of going through that path is minimal and really not worth the pain.
Thanks,
tglx
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Quoted 15 lines · Thomas Gleixner
Quoted 7 lines · Rabin Vincent
Quoted 6 lines · Will Deacon
Ah yes, thanks for the explanation. After looking at the plat-omap code I finally understand what's going on and I can't help but feel that the chained GPIO handlers are terminally broken! The generic irq chip high-level handlers (handle_{edge,level}_irq for example) at least check to see if the
irq_chipfunctions are non-NULL before calling them.Quoted 6 lines
Quoted 2 lines
Ideally, the chained handler would be able to query the
irq_chipto find out what types of IRQ flow-control it supports and then assume that behaviour.Thomas, suggestions on how best to handle this? (Some of these chained handlers are the ones in
plat-omap/gpio.c,plat-nomadik/gpio.c, andmach-s5pv310/irq-combiner.c.)
Quoted 7 lines
I'm not much of a fan of those chained handlers. They work fine, when they are tied into the
irq_chipimplementation of a SoC where the chained handler code is 1:1 related to thatirq_chip.Once you start assigning those handlers somewhere else or even using the same handler for different underlying primary irq chips, then it's a lost case and wreckage like this is just lurking around the corner.
That's a result of genirq. With the ARM non-genirq implementation where we had just ack, mask and unmask, it all turned out much easier. In fact, we hardly ever called any of these functions in chained handlers (except ack) - the only time when mask and unmask were called was when we had an IRQ multiplexer which didn't allow us to mask the individual interrupts.
With the advent of genirq and its expansion of the irq chip methods it's become much more complicated. That's one of the faults of trying to generalize this across different architectures.
You can't do without chained handlers on ARM - we used to do it without them and it was proven to be a complete disaster. Dropped interrupts and various drivers just didn't work with chained interrupt controllers.
So getting rid of it is also a 'lost cause'.
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Quoted 31 lines · Russell King - ARM Linux
Quoted 15 lines · Thomas Gleixner
Quoted 7 lines · Rabin Vincent
Quoted 6 lines · Will Deacon
Ah yes, thanks for the explanation. After looking at the plat-omap code I finally understand what's going on and I can't help but feel that the chained GPIO handlers are terminally broken! The generic irq chip high-level handlers (handle_{edge,level}_irq for example) at least check to see if the
irq_chipfunctions are non-NULL before calling them.Quoted 6 lines
Quoted 2 lines
Ideally, the chained handler would be able to query the
irq_chipto find out what types of IRQ flow-control it supports and then assume that behaviour.Thomas, suggestions on how best to handle this? (Some of these chained handlers are the ones in
plat-omap/gpio.c,plat-nomadik/gpio.c, andmach-s5pv310/irq-combiner.c.)Quoted 7 lines
I'm not much of a fan of those chained handlers. They work fine, when they are tied into the
irq_chipimplementation of a SoC where the chained handler code is 1:1 related to thatirq_chip.Once you start assigning those handlers somewhere else or even using the same handler for different underlying primary irq chips, then it's a lost case and wreckage like this is just lurking around the corner.
That's a result of genirq. With the ARM non-genirq implementation where we had just ack, mask and unmask, it all turned out much easier. In fact, we hardly ever called any of these functions in chained handlers (except ack) - the only time when mask and unmask were called was when we had an IRQ multiplexer which didn't allow us to mask the individual interrupts.
Quoted 7 lines
With the advent of genirq and its expansion of the irq chip methods it's become much more complicated. That's one of the faults of trying to generalize this across different architectures.
You can't do without chained handlers on ARM - we used to do it without them and it was proven to be a complete disaster. Dropped interrupts and various drivers just didn't work with chained interrupt controllers.
I really have a hard time to see the difference between doing:
chained_handler()
fiddle_with_primary_chip() demux() fiddle_with_primary_chip()
and
handle_xxxx_irq()
fiddle_with_primary_chip() chained_handler() demux() fiddle_with_primary_chip()
Why should that drop more interrupt? The only difference is that you make the demux handler oblivious of the underlying primary chip and let the chip chose the appropriate flow handler which issues the right chip methods.
Quoted 1 line
So getting rid of it is also a 'lost cause'.
I didn't say that we need to get rid of chained handlers. You just have to be very careful about them. Nothing new - with or without genirq.
Thanks,
tglx
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Quoted 33 lines · Thomas Gleixner
Quoted 7 lines · Russell King - ARM Linux
That's a result of genirq. With the ARM non-genirq implementation where we had just ack, mask and unmask, it all turned out much easier. In fact, we hardly ever called any of these functions in chained handlers (except ack) - the only time when mask and unmask were called was when we had an IRQ multiplexer which didn't allow us to mask the individual interrupts.
Quoted 7 lines
With the advent of genirq and its expansion of the irq chip methods it's become much more complicated. That's one of the faults of trying to generalize this across different architectures.
You can't do without chained handlers on ARM - we used to do it without them and it was proven to be a complete disaster. Dropped interrupts and various drivers just didn't work with chained interrupt controllers.
I really have a hard time to see the difference between doing:
chained_handler()fiddle_with_primary_chip() demux() fiddle_with_primary_chip()and
handle_xxxx_irq()fiddle_with_primary_chip() chained_handler() demux() fiddle_with_primary_chip()
Quoted 4 lines
Why should that drop more interrupt? The only difference is that you make the demux handler oblivious of the underlying primary chip and let the chip chose the appropriate flow handler which issues the right chip methods.
The difference is that properly implemented chained handlers do *not* mask the interrupt on the parent IRQ controller, thereby allowing other interrupts to be serviced as appropriate.
The issue that this whole implementation was designed in the first place to fix was lost IDE interrupts for CF cards connected to the PCMCIA/CF interfaces of SA1111 devices. These were lost because the CF interrupt output is a level-based output, but the SA11xx interrupt inputs are all edge based.
When the CF interrupt is connected to a SA1111 GPIO, and using the old interrupt system, edge transitions were _often_ missed resulting in frequent 'lost interrupt' complaints from the IDE layer. Exactly why this was could never be ascertained (probably because the hardware combination I had at the time did not allow me to setup this scenario.)
With the chained interrupt handler implementation, things were setup to ensure that as much of the interrupt levels were left enabled so that there was symetrical handling across the entire interrupt tree, and the result of that was no more lost interrupts.
There is a lot of difference between using a conventional 'flow' handler which does masking/unmasking of the parent interrupt and a properly written chained handler which avoids that masking.
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Quoted 22 lines · Russell King - ARM Linux
Quoted 4 lines · Thomas Gleixner
Why should that drop more interrupt? The only difference is that you make the demux handler oblivious of the underlying primary chip and let the chip chose the appropriate flow handler which issues the right chip methods.
The difference is that properly implemented chained handlers do *not* mask the interrupt on the parent IRQ controller, thereby allowing other interrupts to be serviced as appropriate.
The issue that this whole implementation was designed in the first place to fix was lost IDE interrupts for CF cards connected to the PCMCIA/CF interfaces of SA1111 devices. These were lost because the CF interrupt output is a level-based output, but the SA11xx interrupt inputs are all edge based.
When the CF interrupt is connected to a SA1111 GPIO, and using the old interrupt system, edge transitions were _often_ missed resulting in frequent 'lost interrupt' complaints from the IDE layer. Exactly why this was could never be ascertained (probably because the hardware combination I had at the time did not allow me to setup this scenario.)
Quoted 8 lines
With the chained interrupt handler implementation, things were setup to ensure that as much of the interrupt levels were left enabled so that there was symetrical handling across the entire interrupt tree, and the result of that was no more lost interrupts.
There is a lot of difference between using a conventional 'flow' handler which does masking/unmasking of the parent interrupt and a properly written chained handler which avoids that masking.
Depends on the underlying flow handler. fasteoi does not mask, but I can see your point. If you have that oddball SA11xx thing, you are forced to do that, but that is tied into SA11xx and confined.
But if you start to bolt that across platforms with various underlying chips it simply does not work at all.
For sane primary irq chip implementations it should not matter at all whether you do it with a chained handler directly or from a regular requested interrupt.
Thanks,
tglx
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Quoted 28 lines · Thomas Gleixner
Quoted 27 lines · Russell King - ARM Linux
Quoted 4 lines · Thomas Gleixner
Why should that drop more interrupt? The only difference is that you make the demux handler oblivious of the underlying primary chip and let the chip chose the appropriate flow handler which issues the right chip methods.
The difference is that properly implemented chained handlers do *not* mask the interrupt on the parent IRQ controller, thereby allowing other interrupts to be serviced as appropriate.
The issue that this whole implementation was designed in the first place to fix was lost IDE interrupts for CF cards connected to the PCMCIA/CF interfaces of SA1111 devices. These were lost because the CF interrupt output is a level-based output, but the SA11xx interrupt inputs are all edge based.
When the CF interrupt is connected to a SA1111 GPIO, and using the old interrupt system, edge transitions were _often_ missed resulting in frequent 'lost interrupt' complaints from the IDE layer. Exactly why this was could never be ascertained (probably because the hardware combination I had at the time did not allow me to setup this scenario.)
With the chained interrupt handler implementation, things were setup to ensure that as much of the interrupt levels were left enabled so that there was symetrical handling across the entire interrupt tree, and the result of that was no more lost interrupts.
Quoted 7 lines
Quoted 3 lines
There is a lot of difference between using a conventional 'flow' handler which does masking/unmasking of the parent interrupt and a properly written chained handler which avoids that masking.
Depends on the underlying flow handler. fasteoi does not mask, but I can see your point. If you have that oddball SA11xx thing, you are forced to do that, but that is tied into SA11xx and confined.
It isn't - what I highlight above is the correct way to deal with chained interrupts - which is to leave the parent interrupt enabled _unless_ there is a good reason not to.
It also needs to be symetrical otherwise you unbalance the interrupt handling such that those interrupts which are downstream of the primary controller become less likely to be handled, and you end up with some interrupts being soo pessimistic its untrue. This commonly happens when people don't think and just throw loop after loop into their flow handlers.
The last reason for this is to ensure that IRQ handling is *fast* and *efficient*. Using the standard handlers adds a hell of a lot of unnecessary overhead which just isn't required.
Look, I put a lot of time and effort into giving ARM an interrupt handling subsystem which actually _works_ for the hardware that we commonly have, and I'm not having all that thrown out in the name of 'generalization'. If genirq can't cope with it, then ARM needs to avoid genirq.
Chained flow handlers are here to stay on ARM.
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Quoted 24 lines · Russell King - ARM Linux
Quoted 7 lines · Thomas Gleixner
Quoted 3 lines
There is a lot of difference between using a conventional 'flow' handler which does masking/unmasking of the parent interrupt and a properly written chained handler which avoids that masking.
Depends on the underlying flow handler. fasteoi does not mask, but I can see your point. If you have that oddball SA11xx thing, you are forced to do that, but that is tied into SA11xx and confined.
It isn't - what I highlight above is the correct way to deal with chained interrupts - which is to leave the parent interrupt enabled _unless_ there is a good reason not to.
It also needs to be symetrical otherwise you unbalance the interrupt handling such that those interrupts which are downstream of the primary controller become less likely to be handled, and you end up with some interrupts being soo pessimistic its untrue. This commonly happens when people don't think and just throw loop after loop into their flow handlers.
The last reason for this is to ensure that IRQ handling is *fast* and *efficient*. Using the standard handlers adds a hell of a lot of unnecessary overhead which just isn't required.
Quoted 6 lines
Look, I put a lot of time and effort into giving ARM an interrupt handling subsystem which actually _works_ for the hardware that we commonly have, and I'm not having all that thrown out in the name of 'generalization'. If genirq can't cope with it, then ARM needs to avoid genirq.
Chained flow handlers are here to stay on ARM.
I have no intention to remove them. If they are done correct they are not a problem at all. And correct means: tied to the underlying primary chip.
The shit hits the fan when a chained handler implementation is trying to be agnostic about the actual underlying primary chip. That won't ever work and is broken. The only way to make a demux handler agnostic is to use a regular requested interrupt handler. That's all what I'm saying.
You have to actually use your brain when implementing a chained handler. Looking through a bunch of implementations I found stuff, which is basically a poorly implemented flow handler. Worst example:fsl_msi_cascade().
ARM ones are mostly sane, but e.g. nmk_gpio_irq_handler() is not really one which fits your description. It's trying to deal with different underlying primary chips obviously, which is wrong in the first place.
Thanks,
tglx
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Quoted 9 lines
You have to actually use your brain when implementing a chained handler. Looking through a bunch of implementations I found stuff, which is basically a poorly implemented flow handler. Worst example:
fsl_msi_cascade().ARM ones are mostly sane, but e.g.
nmk_gpio_irq_handler()is not really one which fits your description. It's trying to deal with different underlying primary chips obviously, which is wrong in the first place.
Right, so to get back to the original discussion about how to handle chained handlers if the high-level flow type of the IRQ chip is altered it seems that there are two options:
1.) Update all of the chained handlers to use the new flow-control 2.) Retain backwards compatibility if a chained handler decides to
use the old method of flow control (specifically, leave an ack implementation in the GIC code after moving to fasteoi).
Obviously, I'd rather go with option (2) and let platforms migrate over time if they choose to. Now, given that the ack function is really not something you want to do in a virtualised environment (because it pokes the distributor), is it worth sticking a WARN_ON_ONCE(cpu_has_virtualisation()); in the ack code?
Cheers,
Will
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Quoted 19 lines · Will Deacon
Quoted 9 lines
You have to actually use your brain when implementing a chained handler. Looking through a bunch of implementations I found stuff, which is basically a poorly implemented flow handler. Worst example:
fsl_msi_cascade().ARM ones are mostly sane, but e.g.
nmk_gpio_irq_handler()is not really one which fits your description. It's trying to deal with different underlying primary chips obviously, which is wrong in the first place.Right, so to get back to the original discussion about how to handle chained handlers if the high-level flow type of the IRQ chip is altered it seems that there are two options:
1.) Update all of the chained handlers to use the new flow-control 2.) Retain backwards compatibility if a chained handler decides to
use the old method of flow control (specifically, leave an ack implementation in the GIC code after moving to fasteoi).
Quoted 5 lines
Obviously, I'd rather go with option (2) and let platforms migrate over time if they choose to. Now, given that the ack function is really not something you want to do in a virtualised environment (because it pokes the distributor), is it worth sticking a WARN_ON_ONCE(cpu_has_virtualisation()); in the ack code?
#2 is less painful and just works. The fasteoi stuff does not use ack IIRC so it wont hurt.
vs. the WARN_ON_ONCE(), I have no real opinion.
Thanks,
tglx
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Quoted 10 lines
Quoted 10 lines
Right, so to get back to the original discussion about how to handle chained handlers if the high-level flow type of the IRQ chip is altered it seems that there are two options:
1.) Update all of the chained handlers to use the new flow-control 2.) Retain backwards compatibility if a chained handler decides to
use the old method of flow control (specifically, leave an ack implementation in the GIC code after moving to fasteoi).
Quoted 8 lines
Quoted 5 lines
Obviously, I'd rather go with option (2) and let platforms migrate over time if they choose to. Now, given that the ack function is really not something you want to do in a virtualised environment (because it pokes the distributor), is it worth sticking a WARN_ON_ONCE(cpu_has_virtualisation()); in the ack code?
#2 is less painful and just works. The fasteoi stuff does not use ack IIRC so it wont hurt.
On an MSM we use handle_percpu_irq for PPIs, if we have ack and eoi we will end up EOI ing the interrupt twice so #2 wont work. Also all the cascaded handlers would have assumed that the ack function masks the interrupt, it is best we fix all of them to use eoi at the end (just like handle_fasteoi_irq). Please tell me how you guys locate such cascaded handlers?
Sorry for my earlier patch - didnt realize that the chaging the ack will break the chained handler. My board doesnt have cascaded gics. The only chained handler I knew was gpio-v2.c and it does the correct thing of calling an desc->chip->ack at the end.
BTW, I am all in favor of using handle_fasteoi_irq for shared PPIs , It will fix a problem I pointed out here.
http://kerneltrap.org/mailarchive/linux-kernel/2010/12/30/4664338
--
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Quoted 18 lines
Quoted 9 lines
Quoted 9 lines
Right, so to get back to the original discussion about how to handle chained handlers if the high-level flow type of the IRQ chip is altered it seems that there are two options:
1.) Update all of the chained handlers to use the new flow-control 2.) Retain backwards compatibility if a chained handler decides to
use the old method of flow control (specifically, leave an ack implementation in the GIC code after moving to fasteoi).Quoted 8 lines
Quoted 5 lines
Obviously, I'd rather go with option (2) and let platforms migrate over time if they choose to. Now, given that the ack function is really not something you want to do in a virtualised environment (because it pokes the distributor), is it worth sticking a WARN_ON_ONCE(cpu_has_virtualisation()); in the ack code?
#2 is less painful and just works. The fasteoi stuff does not use ack IIRC so it wont hurt.
Quoted 6 lines
On an MSM we use
handle_percpu_irqfor PPIs, if we have ack and eoi we will end up EOI ing the interrupt twice so #2 wont work. Also all the cascaded handlers would have assumed that the ack function masks the interrupt, it is best we fix all of them to use eoi at the end (just likehandle_fasteoi_irq). Please tell me how you guys locate such cascaded handlers?
I don't think the cascaded handlers would have assumed that because ack just sends EOI - it doesn't do any masking. We do have a problem with the percpu_irq flow though (the GIC reference manual says that EOIing a non-active interrupt is UNPREDICTABLE).
Another easy hack is to set IRQ_PER_CPU in the irq_desc->status for PPI interrupts and then check this in the ack routine. It's pretty ugly, but it doesn't affect the common case and it at least postpones the platform changes.
Will
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Quoted 30 lines · Will Deacon
Quoted 18 lines
Quoted 9 lines
Quoted 9 lines
Right, so to get back to the original discussion about how to handle chained handlers if the high-level flow type of the IRQ chip is altered it seems that there are two options:
1.) Update all of the chained handlers to use the new flow-control 2.) Retain backwards compatibility if a chained handler decides to
use the old method of flow control (specifically, leave an ack implementation in the GIC code after moving to fasteoi).Quoted 8 lines
Quoted 5 lines
Obviously, I'd rather go with option (2) and let platforms migrate over time if they choose to. Now, given that the ack function is really not something you want to do in a virtualised environment (because it pokes the distributor), is it worth sticking a WARN_ON_ONCE(cpu_has_virtualisation()); in the ack code?
#2 is less painful and just works. The fasteoi stuff does not use ack IIRC so it wont hurt.
Quoted 6 lines
On an MSM we use
handle_percpu_irqfor PPIs, if we have ack and eoi we will end up EOI ing the interrupt twice so #2 wont work. Also all the cascaded handlers would have assumed that the ack function masks the interrupt, it is best we fix all of them to use eoi at the end (just likehandle_fasteoi_irq). Please tell me how you guys locate such cascaded handlers?I don't think the cascaded handlers would have assumed that because ack just sends EOI - it doesn't do any masking. We do have a problem with the
percpu_irqflow though (the GIC reference manual says that EOIing a non-active interrupt is UNPREDICTABLE).
Quoted 4 lines
Another easy hack is to set
IRQ_PER_CPUin theirq_desc->statusfor PPI interrupts and then check this in the ack routine. It's pretty ugly, but it doesn't affect the common case and it at least postpones the platform changes.
Conditionals in irq_chip callbacks are almost always a sign of doom. Don't do that.
How many chained handlers need to be fixed, when the whole gic stuff switches to eoi ?
Thanks,
tglx
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Quoted 5 lines
Quoted 5 lines
I don't think the cascaded handlers would have assumed that because ack just sends EOI - it doesn't do any masking. We do have a problem with the
percpu_irqflow though (the GIC reference manual says that EOIing a non-active interrupt is UNPREDICTABLE).
Quoted 7 lines
Quoted 4 lines
Another easy hack is to set
IRQ_PER_CPUin theirq_desc->statusfor PPI interrupts and then check this in the ack routine. It's pretty ugly, but it doesn't affect the common case and it at least postpones the platform changes.Conditionals in
irq_chipcallbacks are almost always a sign of doom. Don't do that.
Ok, that was a hack too far! Let's fix this properly.
Quoted 2 lines
How many chained handlers need to be fixed, when the whole gic stuff switches to eoi ?
Well, grepping for set_chained_irq_handler yields a whole bunch of platforms but the set of these which appear to use the gic is only:
mach-msm
mach-s5pv310
mach-shmobile
mach-tegra
I'll have a look through the code there and post some patches next week. Hopefully if I've missed anybody, they'll shout then.
Cheers,
Will
A message that is not in the archive (sent off-list or not yet received): -8083923411736601789@unknownmsgid
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Quoted 21 lines · Will Deacon
Quoted 5 lines
Quoted 5 lines
I don't think the cascaded handlers would have assumed that because ack just sends EOI - it doesn't do any masking. We do have a problem with the
percpu_irqflow though (the GIC reference manual says that EOIing a non-active interrupt is UNPREDICTABLE).Quoted 7 lines
Quoted 4 lines
Another easy hack is to set
IRQ_PER_CPUin theirq_desc->statusfor PPI interrupts and then check this in the ack routine. It's pretty ugly, but it doesn't affect the common case and it at least postpones the platform changes.Conditionals in
irq_chipcallbacks are almost always a sign of doom. Don't do that.Ok, that was a hack too far! Let's fix this properly.
Quoted 2 lines
How many chained handlers need to be fixed, when the whole gic stuff switches to eoi ?
Well, grepping for
set_chained_irq_handleryields a whole bunch of platforms but the set of these which appear to use the gic is only:
Quoted 7 lines
mach-msm
mach-s5pv310
mach-shmobile
mach-tegraI'll have a look through the code there and post some patches next week. Hopefully if I've missed anybody, they'll shout then.
omap4 uses the gic, and uses chained handlers in plat-omap/gpio.c. plat-omap/gpio.c seems to handle similar gpio hardware connected to different IRQ controllers on different SoCs - non-gic on omap2-3, and gic on omap4.
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
Quoted 45 lines
-----Original Message-----
From: Colin Cross [mailto:ccross at google.com]
Sent: Saturday, February 19, 2011 12:01 AM
To: Will Deacon
Cc: Thomas Gleixner; Rabin Vincent; Abhijeet Dharmapurikar; Russell King - ARM Linux; linux-arm-kernel at lists.infradead.org; Santosh Shilimkar
Subject: Re: [PATCH] ARM: gic: usehandle_fasteoi_irqfor SPIsQuoted 1 line · Will Deacon
Quoted 1 line
Quoted 1 line
I don't think the cascaded handlers would have assumed that
because ack
Quoted 1 line
Quoted 1 line
Quoted 1 line
just sends EOI - it doesn't do any masking. We do have a
problem with
Quoted 1 line
Quoted 1 line
Quoted 1 line
the
percpu_irqflow though (the GIC reference manual says thatEOIing a
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
non-active interrupt is UNPREDICTABLE).
Another easy hack is to set
IRQ_PER_CPUin theirq_desc->statusfor PPI
Quoted 1 line
Quoted 1 line
Quoted 1 line
interrupts and then check this in the ack routine. It's pretty
ugly, but
Quoted 1 line
Quoted 1 line
Quoted 1 line
it doesn't affect the common case and it at least postpones the
platform
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
changes.
Conditionals in
irq_chipcallbacks are almost always a sign of doom. Don't do that.Ok, that was a hack too far! Let's fix this properly.
Quoted 1 line
How many chained handlers need to be fixed, when the whole gic
stuff
Quoted 3 lines
Quoted 1 line
switches to eoi ?
Well, grepping for
set_chained_irq_handleryields a whole bunch ofplatforms
Quoted 7 lines
but the set of these which appear to use the gic is only:
mach-msm
mach-s5pv310
mach-shmobile
mach-tegra
Quoted 8 lines
Quoted 1 line
I'll have a look through the code there and post some patches next
week.
Quoted 1 line
Hopefully if I've missed anybody, they'll shout then.
omap4 uses the gic, and uses chained handlers in
plat-omap/gpio.c.plat-omap/gpio.cseems to handle similar gpio hardware connected to different IRQ controllers on different SoCs - non-gic on omap2-3, and gic on omap4.
That's right.
Thanks Colin for pointing it. I almost missed this thread.
Regards,
Santosh
PATCH 1/1 ARM: gic: use handle_fasteoi_irq for SPIs
In reply to Colin CrossQuoted 8 lines
Quoted 8 lines
Well, grepping for
set_chained_irq_handleryields a whole bunch of platforms but the set of these which appear to use the gic is only:mach-msm
mach-s5pv310
mach-shmobile
mach-tegra
Quoted 7 lines
Quoted 2 lines
I'll have a look through the code there and post some patches next week. Hopefully if I've missed anybody, they'll shout then.
omap4 uses the gic, and uses chained handlers in
plat-omap/gpio.c.plat-omap/gpio.cseems to handle similar gpio hardware connected to different IRQ controllers on different SoCs - non-gic on omap2-3, and gic on omap4.
Thanks for spotting this Colin. My grep-fu failed me because the gic initialisation for omap is under a different directory to the GPIO cascaded IRQ stuff (plat- vs mach-).
I'll add OMAP to the list.
Will