* gic_set_affinity
@ 2012-11-01 17:54 Robert Beckett
2012-11-02 11:32 ` gic_set_affinity Robert Beckett
0 siblings, 1 reply; 6+ messages in thread
From: Robert Beckett @ 2012-11-01 17:54 UTC (permalink / raw)
To: linux-arm-kernel
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, and the handler
will be called on the second cpu and will wait for the same lock in
the handler. Once the affinity setting calls have finished, the lock
is released, and whichever cpu gets the lock will handle the interrupt
while still locking out the other cpu. Once it finishes, the other cpu
will try to handle it leading to an interrupt handler call for an
interrupt that no longer exists, which could lead to spurious
interrupt if it returns IRQ_NONE because it cant see that the
interrupt is raised.
Is this what will happen? If so, the interrupt should be masked across
the affinity setting so that it cant be raised on both cpus.
if I have just missed something obvious, then please let me know...
Cheers.
Bob
^ permalink raw reply [flat|nested] 6+ messages in thread
* gic_set_affinity
2012-11-01 17:54 gic_set_affinity Robert Beckett
@ 2012-11-02 11:32 ` Robert Beckett
2012-11-05 12:05 ` gic_set_affinity Will Deacon
0 siblings, 1 reply; 6+ messages in thread
From: Robert Beckett @ 2012-11-02 11:32 UTC (permalink / raw)
To: linux-arm-kernel
(CC maintainers)
On 1 November 2012 17:54, Robert Beckett <bob.beckett@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, and the handler
> will be called on the second cpu and will wait for the same lock in
> the handler. Once the affinity setting calls have finished, the lock
> is released, and whichever cpu gets the lock will handle the interrupt
> while still locking out the other cpu. Once it finishes, the other cpu
> will try to handle it leading to an interrupt handler call for an
> interrupt that no longer exists, which could lead to spurious
> interrupt if it returns IRQ_NONE because it cant see that the
> interrupt is raised.
>
> Is this what will happen? If so, the interrupt should be masked across
> the affinity setting so that it cant be raised on both cpus.
> if I have just missed something obvious, then please let me know...
>
> Cheers.
>
> Bob
^ permalink raw reply [flat|nested] 6+ messages in thread
* gic_set_affinity
2012-11-02 11:32 ` gic_set_affinity Robert Beckett
@ 2012-11-05 12:05 ` Will Deacon
2012-11-07 17:08 ` gic_set_affinity Robert Beckett
0 siblings, 1 reply; 6+ messages in thread
From: Will Deacon @ 2012-11-05 12:05 UTC (permalink / raw)
To: linux-arm-kernel
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@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
^ permalink raw reply [flat|nested] 6+ messages in thread
* gic_set_affinity
2012-11-05 12:05 ` gic_set_affinity Will Deacon
@ 2012-11-07 17:08 ` Robert Beckett
2012-11-07 17:13 ` gic_set_affinity Will Deacon
0 siblings, 1 reply; 6+ messages in thread
From: Robert Beckett @ 2012-11-07 17:08 UTC (permalink / raw)
To: linux-arm-kernel
On 5 November 2012 12:05, Will Deacon <will.deacon@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@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?
Bob
^ permalink raw reply [flat|nested] 6+ messages in thread
* gic_set_affinity
2012-11-07 17:08 ` gic_set_affinity Robert Beckett
@ 2012-11-07 17:13 ` Will Deacon
2012-11-07 17:18 ` gic_set_affinity Robert Beckett
0 siblings, 1 reply; 6+ messages in thread
From: Will Deacon @ 2012-11-07 17:13 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Nov 07, 2012 at 05:08:36PM +0000, Robert Beckett wrote:
> On 5 November 2012 12:05, Will Deacon <will.deacon@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@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
^ permalink raw reply [flat|nested] 6+ messages in thread
* gic_set_affinity
2012-11-07 17:13 ` gic_set_affinity Will Deacon
@ 2012-11-07 17:18 ` Robert Beckett
0 siblings, 0 replies; 6+ messages in thread
From: Robert Beckett @ 2012-11-07 17:18 UTC (permalink / raw)
To: linux-arm-kernel
On 7 November 2012 17:13, Will Deacon <will.deacon@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@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@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
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2012-11-07 17:18 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-01 17:54 gic_set_affinity Robert Beckett
2012-11-02 11:32 ` gic_set_affinity Robert Beckett
2012-11-05 12:05 ` gic_set_affinity Will Deacon
2012-11-07 17:08 ` gic_set_affinity Robert Beckett
2012-11-07 17:13 ` gic_set_affinity Will Deacon
2012-11-07 17:18 ` gic_set_affinity Robert Beckett
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox