Message ID | 1410444228-3134-3-git-send-email-jiang.liu@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, 11 Sep 2014, Jiang Liu wrote: > +#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY > +void irq_chip_ack_parent(struct irq_data *data) > +{ > + data = data->parent_data; > + if (data && data->chip && data->chip->irq_ack) > + data->chip->irq_ack(data); Why is this restricted to a single parent level and does not go down the whole stack? Thanks, tglx
On 2014/9/17 1:45, Thomas Gleixner wrote: > On Thu, 11 Sep 2014, Jiang Liu wrote: >> +#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY >> +void irq_chip_ack_parent(struct irq_data *data) >> +{ >> + data = data->parent_data; >> + if (data && data->chip && data->chip->irq_ack) >> + data->chip->irq_ack(data); > > Why is this restricted to a single parent level and does not go down > the whole stack? Hi Thomas, It happens to work on x86, and we want to achieve a bit performance advantage by not walking down the whole stack. If preferred, I will change it to walk the whole stack. Regards! Gerry > > Thanks, > > tglx >
On Wed, 17 Sep 2014, Jiang Liu wrote: > On 2014/9/17 1:45, Thomas Gleixner wrote: > > On Thu, 11 Sep 2014, Jiang Liu wrote: > >> +#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY > >> +void irq_chip_ack_parent(struct irq_data *data) > >> +{ > >> + data = data->parent_data; > >> + if (data && data->chip && data->chip->irq_ack) > >> + data->chip->irq_ack(data); > > > > Why is this restricted to a single parent level and does not go down > > the whole stack? > Hi Thomas, > It happens to work on x86, and we want to achieve a bit > performance advantage by not walking down the whole stack. > If preferred, I will change it to walk the whole stack. Happens to work on my machine is always a bad argument :) Now, I can see why you want to do that, but if we do an optimization like that then we should really get rid of the conditional. You surely need a conditional on data->chip and data->chip->callback for a full stackq walk, but for an explicit request to use the parents ack the parent better has a chip with an ack function, right? void irq_chip_ack_parent(struct irq_data *data) { data = data->parent_data; data->chip->irq_ack(data); } Thanks, tglx
On 2014/9/18 4:58, Thomas Gleixner wrote: > On Wed, 17 Sep 2014, Jiang Liu wrote: >> On 2014/9/17 1:45, Thomas Gleixner wrote: >>> On Thu, 11 Sep 2014, Jiang Liu wrote: >>>> +#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY >>>> +void irq_chip_ack_parent(struct irq_data *data) >>>> +{ >>>> + data = data->parent_data; >>>> + if (data && data->chip && data->chip->irq_ack) >>>> + data->chip->irq_ack(data); >>> >>> Why is this restricted to a single parent level and does not go down >>> the whole stack? >> Hi Thomas, >> It happens to work on x86, and we want to achieve a bit >> performance advantage by not walking down the whole stack. >> If preferred, I will change it to walk the whole stack. > > Happens to work on my machine is always a bad argument :) > > Now, I can see why you want to do that, but if we do an optimization > like that then we should really get rid of the conditional. > > You surely need a conditional on data->chip and data->chip->callback > for a full stackq walk, but for an explicit request to use the parents > ack the parent better has a chip with an ack function, right? > > void irq_chip_ack_parent(struct irq_data *data) > { > data = data->parent_data; > data->chip->irq_ack(data); > } Sure, will optimize it further as above code. Regards! Gerry > > Thanks, > > tglx >
diff --git a/include/linux/irq.h b/include/linux/irq.h index 4b74565690ce..bfa027f6814a 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -433,6 +433,11 @@ extern void handle_percpu_devid_irq(unsigned int irq, struct irq_desc *desc); extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc); extern void handle_nested_irq(unsigned int irq); +#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY +extern void irq_chip_ack_parent(struct irq_data *data); +extern int irq_chip_retrigger_hierarchy(struct irq_data *data); +#endif + /* Handling of unhandled and spurious interrupts: */ extern void note_interrupt(unsigned int irq, struct irq_desc *desc, irqreturn_t action_ret); diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 46bd5e2190c3..b8ee27efde73 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -821,3 +821,21 @@ void irq_cpu_offline(void) raw_spin_unlock_irqrestore(&desc->lock, flags); } } + +#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY +void irq_chip_ack_parent(struct irq_data *data) +{ + data = data->parent_data; + if (data && data->chip && data->chip->irq_ack) + data->chip->irq_ack(data); +} + +int irq_chip_retrigger_hierarchy(struct irq_data *data) +{ + for (data = data->parent_data; data; data = data->parent_data) + if (data->chip && data->chip->irq_retrigger) + return data->chip->irq_retrigger(data); + + return -ENOSYS; +} +#endif
Now we already support hierarchy irq_datas, so introduce several helpers to support stacked irq_chips. Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com> --- include/linux/irq.h | 5 +++++ kernel/irq/chip.c | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+)