From: gregory.clement@free-electrons.com (Gregory CLEMENT)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/8] irqchip: armada-370-xp: Simplify interrupt map, mask and unmask
Date: Thu, 26 Feb 2015 13:52:50 +0100 [thread overview]
Message-ID: <54EF1722.8090201@free-electrons.com> (raw)
In-Reply-To: <20150226110919.GC29241@lukather>
Hi Maxime,
On 26/02/2015 12:09, Maxime Ripard wrote:
> Hi Gregory,
>
> On Thu, Feb 26, 2015 at 11:41:00AM +0100, Gregory CLEMENT wrote:
>> Hi Maxime,
>>
>> On 26/02/2015 11:13, Maxime Ripard wrote:
>>> From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
>>>
>>> The map, mask and unmask is unnecessarily complicated, with a different
>>> implementation for shared and per CPU interrupts. The current code does
>>> the following:
>>>
>>> At probe time, all interrupts are disabled and masked on all CPUs.
>>>
>>> Shared interrupts:
>>>
>>> * When the interrupt is mapped(), it gets disabled and unmasked on the
>>> calling CPU.
>>>
>>> * When the interrupt is unmasked(), masked(), it gets enabled and
>>> disabled.
>>>
>>> Per CPU interrupts:
>>>
>>> * When the interrupt is mapped, it gets masked on the calling CPU and
>>> enabled.
>>>
>>> * When the interrupt is unmasked(), masked(), it gets unmasked and masked,
>>> on the calling CPU.
>>>
>>> This commit simplifies this code, with a much simpler implementation, common
>>> to shared and per CPU interrupts.
>>>
>>> * When the interrupt is mapped, it's enabled.
>>>
>>> * When the interrupt is unmasked(), masked(), it gets unmasked and masked,
>>> on the calling CPU.
>>>
>>> Tested on a Armada XP SoC with SMP and UP configurations, with chained and
>>> regular interrupts.
>>
>> This patch doesn't only simplify the driver it changes also its
>> behavior and especially for the affinity.
>
> The affinity itself is not changed by that patch. The default CPU the
> interrupt handler is running on might, but as far as I know, there's
> no guarantee on the affinity of an interrupt when irq_set_affinity has
> not been called.
Actually as soon as a driver do a request_irq the affinity is set in the
__setup_irq function.
>
>> If a driver call irq_enable() then this functions will call
>> irq_enable() and as we didn't implement a .enable() operation, it will
>> call only our unmask() function.
>>
>> So if the IRQ was unmasked on a CPU and a driver call an irq_enable()
>> from an other CPU then we will end up with the IRQ enabled on 2
>> different CPUs. It is a problem for 2 reasons:
>
> I guess you're talking about SPIs here, right?
yes
>
>> - the hardware don't handle a IRQ enable on more than one CPU
>
> Oh. I would have expected one CPU to get a spurious interrupt, and the
> other to handle the interrupt as expected.
Unfortunately it is not the case and the behavior is unpredictable if an
IRQ is set for more than one CPU.
>
>> - it will modify the affinity at the hardware level because a new CPU
>> will be able to receive an IRQ whereas we setup the affinity on only
>> one CPU.
>
> I'm not seure what you mean here.
>
> The affinity is controlled by the INT_SOURCE_CTL register set, that is
> left untouched by this patch.
INT_SOURCE_CTL register and ARMADA_370_XP_INT_*_MASK_OFFS register are two
way to access exactly the same value. So as you modify the use of the
ARMADA_370_XP_INT_*_MASK_OFFS register you modify the affinity.
With ARMADA_370_XP_INT_*_MASK_OFFS you have one register per CPU and you
write the number of the IRQ you want to enable or disable for this CPU. Whereas
you have one INT_SOURCE_CTL register per interrupt and there you write the CPU
mask. But in the hardware you modify the same thing.
In the case has an SPI the interrupt masks are controlled by two register, one
at a global level and the other at the CPU level.
CPU0--INT_*_MASK_OFFS--|
|
CPU1--INT_*_MASK_OFFS--|
|---INT_*_ENABLE_OFFS----IRQ
CPU2--INT_*_MASK_OFFS--|
|
CPU3--INT_*_MASK_OFFS--|
So currently we only modify the INT_*_ENABLE_OFFS register for the irq_mask/unmask
operation. And we only modify INT_*_MASK_OFFS(or INT_SOURCE_CTL as it modifies the
same value) for the affinity.
With this patch, the INT_*_ENABLE_OFFS is removed and INT_*_MASK_OFFS are modified
in the same time for affinity and for irq_mask/unmask which could lead to some
unexpected behaviors.
For the PPI, there is no INT_*_ENABLE_OFFS register but for them we don't use
affinity. That why the way to handle them is different from the SPI.
By the way the current code in irq_mask/unmask is bogus, instead of
if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ)
we should have
if (hwirq > ARMADA_370_XP_MAX_PER_CPU_IRQS)
Thanks,
Gregory
>
>> By only using the mask and unmask the affinity behavior is no more
>> reliable. I agree that the current code is not trivial, but adding
>> more comment instead of removing this capability should be better.
>
> That can be done too. Especially using the second patch that makes it
> a lot easier to extend the list of supported PPIs.
>
> Maxime
>
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
next prev parent reply other threads:[~2015-02-26 12:52 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-26 10:13 [PATCH 0/8] ARM: mvebu: Enable perf support Maxime Ripard
2015-02-26 10:13 ` [PATCH 1/8] irqchip: armada-370-xp: Simplify interrupt map, mask and unmask Maxime Ripard
2015-02-26 10:41 ` Gregory CLEMENT
2015-02-26 11:09 ` Maxime Ripard
2015-02-26 12:52 ` Gregory CLEMENT [this message]
2015-02-28 10:48 ` Maxime Ripard
2015-02-26 10:13 ` [PATCH 2/8] irqchip: armada-370-xp: Initialize per cpu registers when CONFIG_SMP=N Maxime Ripard
2015-02-26 10:13 ` [PATCH 3/8] irqchip: armada-370-xp: Introduce a is_percpu_irq() helper for readability Maxime Ripard
2015-02-26 10:13 ` [PATCH 4/8] irqchip: armada-370-xp: Enable the PMU interrupts Maxime Ripard
2015-02-26 10:13 ` [PATCH 5/8] ARM: mvebu: Enable Performance Monitor Unit on Armada XP/370 SoCs Maxime Ripard
2015-02-26 10:13 ` [PATCH 6/8] ARM: mvebu: Enable Performance Monitor Unit on Armada 375 SoC Maxime Ripard
2015-02-26 10:13 ` [PATCH 7/8] ARM: mvebu: Enable Performance Monitor Unit on Armada 380/385 SoC Maxime Ripard
2015-02-26 10:13 ` [PATCH 8/8] ARM: mvebu: Enable perf support in mvebu_v7_defconfig Maxime Ripard
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=54EF1722.8090201@free-electrons.com \
--to=gregory.clement@free-electrons.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).