gic_set_affinity

Robert Beckett bob.beckett at gmail.com
Wed Nov 7 12:18:48 EST 2012


On 7 November 2012 17:13, Will Deacon <will.deacon at arm.com> wrote:
> On Wed, Nov 07, 2012 at 05:08:36PM +0000, Robert Beckett wrote:
>> On 5 November 2012 12:05, Will Deacon <will.deacon at arm.com> wrote:
>> > On Fri, Nov 02, 2012 at 11:32:50AM +0000, Robert Beckett wrote:
>> >> (CC maintainers)
>> >>
>> >> On 1 November 2012 17:54, Robert Beckett <bob.beckett at gmail.com> wrote:
>> >> > Hello,
>> >> >
>> >> > I was looking through the arm gic code while debugging a problem I am
>> >> > having, and noticed something in gic_set_affinity.
>> >> >
>> >> > When something comes along and setts an irq affinity mask (e.g.
>> >> > through /proc/irq/<irq>/smp_affinity_mask), the calls goes like so :
>> >> >
>> >> > ...
>> >> > 1. irq_set_affinity : grabs the desc->lock
>> >> > 2. __irq_set_affinity_locked : calls chip->irq_set_affinity
>> >> > 3. gic_set_affinity : writes a new mask to the gic distributor
>> >> >
>> >> > my question is, what happens if an interrupt is raised between 1 and 3?
>> >> > To me, it looks like the interrupt could end up being handled on 2
>> >> > cpus. When it is raised, the handler will be called and sit spinning
>> >> > for desc->lock (e.g. in handle_fasteoi_irq). The mask will be set to
>> >> > set the affinity to the new cpu, the new cpu will receive the
>> >> > interrupt as it has not been ackd or disabled yet
>> >
>> > The interrupt will have been acked in gic_handle_irq before the flow handler
>> > is invoked, so it will transition to the active state and will not get
>> > signalled to another CPU. Since we never set more than one target CPU at the
>> > distributor level, the interrupt will only be forwarded to one CPU interface
>> > at any given time.
>> >
>> > Will
>>
>> Thanks for the response,
>>
>> I cant see anything in gic_handle_irq that would ack the interrupt
>> (unless it is an IPI interrupt).
>> For irqnr > 15, it just calls handle_IRQ, which would call the desc
>> handler, which would sit and wait on the desc->lock at the top of
>> handle_fasteoi_irq.
>> Which code are you referring to that is meant to ack the interrupt?
>
> Reading the interrupt ID signifies an ACK in GIC terminology:
>
>   irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK);
>
> Will

Ah, I see. I hadnt realised that is was an ack on read (yuck!)
Thanks for clearing it up for me.

Bob



More information about the linux-arm-kernel mailing list