From: Thomas Gleixner <tglx@linutronix.de>
To: "Herrenschmidt\, Benjamin" <benh@amazon.com>,
"maz\@kernel.org" <maz@kernel.org>, "Saidi\,
Ali" <alisaidi@amazon.com>
Cc: "jason\@lakedaemon.net" <jason@lakedaemon.net>,
"linux-kernel\@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"linux-arm-kernel\@lists.infradead.org"
<linux-arm-kernel@lists.infradead.org>, "Woodhouse\,
David" <dwmw@amazon.co.uk>, "Zilberman\, Zeev" <zeev@amazon.com>,
"Machulsky\, Zorik" <zorik@amazon.com>
Subject: Re: [PATCH] irqchip/gic-v3-its: Don't try to move a disabled irq
Date: Mon, 08 Jun 2020 15:48:56 +0200 [thread overview]
Message-ID: <87mu5dacs7.fsf@nanos.tec.linutronix.de> (raw)
In-Reply-To: <f9e9d8c37eb92e4b9576bfcb4386ff6ef00eddce.camel@amazon.com>
"Herrenschmidt, Benjamin" <benh@amazon.com> writes:
> On Wed, 2020-06-03 at 16:16 +0100, Marc Zyngier wrote:
>> > My original patch should certain check activated and not disabled.
>> > With that do you still have reservations Marc?
>>
>> I'd still prefer it if we could do something in core code, rather
>> than spreading these checks in the individual drivers. If we can't,
>> fair enough. But it feels like the core set_affinity function could
>> just do the same thing in a single place (although the started vs
>> activated is yet another piece of the puzzle I didn't consider,
>> and the ITS doesn't need the "can_reserve" thing).
>
> For the sake of fixing the problem in a timely and backportable way I
> would suggest first merging the fix, *then* fixing the core core.
The "fix" is just wrong
> if (cpu != its_dev->event_map.col_map[id]) {
> target_col = &its_dev->its->collections[cpu];
> - its_send_movi(its_dev, target_col, id);
> +
> + /* If the IRQ is disabled a discard was sent so don't move */
> + if (!irqd_irq_disabled(d))
That check needs to be !irqd_is_activated() because enable_irq() does
not touch anything affinity related.
> + its_send_movi(its_dev, target_col, id);
> +
> its_dev->event_map.col_map[id] = cpu;
> irq_data_update_effective_affinity(d, cpumask_of(cpu));
And then these associtations are disconnected from reality in any case.
Something like the completely untested patch below should work.
Thanks,
tglx
---
arch/x86/kernel/apic/vector.c | 21 +++------------------
kernel/irq/manage.c | 37 +++++++++++++++++++++++++++++++++++--
2 files changed, 38 insertions(+), 20 deletions(-)
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -446,12 +446,10 @@ static int x86_vector_activate(struct ir
trace_vector_activate(irqd->irq, apicd->is_managed,
apicd->can_reserve, reserve);
- /* Nothing to do for fixed assigned vectors */
- if (!apicd->can_reserve && !apicd->is_managed)
- return 0;
-
raw_spin_lock_irqsave(&vector_lock, flags);
- if (reserve || irqd_is_managed_and_shutdown(irqd))
+ if (!apicd->can_reserve && !apicd->is_managed)
+ assign_irq_vector_any_locked(irqd);
+ else if (reserve || irqd_is_managed_and_shutdown(irqd))
vector_assign_managed_shutdown(irqd);
else if (apicd->is_managed)
ret = activate_managed(irqd);
@@ -775,21 +773,8 @@ void lapic_offline(void)
static int apic_set_affinity(struct irq_data *irqd,
const struct cpumask *dest, bool force)
{
- struct apic_chip_data *apicd = apic_chip_data(irqd);
int err;
- /*
- * Core code can call here for inactive interrupts. For inactive
- * interrupts which use managed or reservation mode there is no
- * point in going through the vector assignment right now as the
- * activation will assign a vector which fits the destination
- * cpumask. Let the core code store the destination mask and be
- * done with it.
- */
- if (!irqd_is_activated(irqd) &&
- (apicd->is_managed || apicd->can_reserve))
- return IRQ_SET_MASK_OK;
-
raw_spin_lock(&vector_lock);
cpumask_and(vector_searchmask, dest, cpu_online_mask);
if (irqd_affinity_is_managed(irqd))
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -195,9 +195,9 @@ void irq_set_thread_affinity(struct irq_
set_bit(IRQTF_AFFINITY, &action->thread_flags);
}
+#ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
static void irq_validate_effective_affinity(struct irq_data *data)
{
-#ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
const struct cpumask *m = irq_data_get_effective_affinity_mask(data);
struct irq_chip *chip = irq_data_get_irq_chip(data);
@@ -205,9 +205,19 @@ static void irq_validate_effective_affin
return;
pr_warn_once("irq_chip %s did not update eff. affinity mask of irq %u\n",
chip->name, data->irq);
-#endif
}
+static inline void irq_init_effective_affinity(struct irq_data *data,
+ const struct cpumask *mask)
+{
+ cpumask_copy(irq_data_get_effective_affinity_mask(data), mask);
+}
+#else
+static inline void irq_validate_effective_affinity(struct irq_data *data) { }
+static inline boot irq_init_effective_affinity(struct irq_data *data,
+ const struct cpumask *mask) { }
+#endif
+
int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask,
bool force)
{
@@ -304,6 +314,26 @@ static int irq_try_set_affinity(struct i
return ret;
}
+static bool irq_set_affinity_deactivated(struct irq_data *data,
+ const struct cpumask *mask, bool force)
+{
+ struct irq_desc *desc = irq_data_to_desc(data);
+
+ /*
+ * If the interrupt is not yet activated, just store the affinity
+ * mask and do not call the chip driver at all. On activation the
+ * driver has to make sure anyway that the interrupt is in a
+ * useable state so startup works.
+ */
+ if (!IS_ENABLED(CONFIG_IRQ_DOMAIN_HIERARCHY) || irqd_is_activated(data))
+ return false;
+
+ cpumask_copy(desc->irq_common_data.affinity, mask);
+ irq_init_effective_affinity(data, mask);
+ irqd_set(data, IRQD_AFFINITY_SET);
+ return true;
+}
+
int irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask,
bool force)
{
@@ -314,6 +344,9 @@ int irq_set_affinity_locked(struct irq_d
if (!chip || !chip->irq_set_affinity)
return -EINVAL;
+ if (irq_set_affinity_deactivated(data, mask, force))
+ return 0;
+
if (irq_can_move_pcntxt(data) && !irqd_is_setaffinity_pending(data)) {
ret = irq_try_set_affinity(data, mask, force);
} else {
next prev parent reply other threads:[~2020-06-08 13:49 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-02 18:47 [PATCH] irqchip/gic-v3-its: Don't try to move a disabled irq Saidi, Ali
2020-06-03 15:16 ` Marc Zyngier
2020-06-03 22:14 ` Herrenschmidt, Benjamin
2020-06-08 13:48 ` Thomas Gleixner [this message]
2020-06-08 21:59 ` Benjamin Herrenschmidt
2020-06-08 23:36 ` Thomas Gleixner
-- strict thread matches above, loose matches on Subject: below --
2020-06-11 17:44 Saidi, Ali
2020-05-29 1:55 Ali Saidi
2020-05-29 4:07 ` Zenghui Yu
2020-05-29 8:32 ` Marc Zyngier
2020-05-29 12:36 ` Saidi, Ali
2020-05-30 16:49 ` Marc Zyngier
2020-05-31 11:09 ` Marc Zyngier
2020-06-01 0:10 ` Saidi, Ali
2020-06-01 2:40 ` Herrenschmidt, Benjamin
2020-06-02 20:54 ` Thomas Gleixner
2020-06-03 12:44 ` Marc Zyngier
2020-05-31 2:53 ` kbuild test robot
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=87mu5dacs7.fsf@nanos.tec.linutronix.de \
--to=tglx@linutronix.de \
--cc=alisaidi@amazon.com \
--cc=benh@amazon.com \
--cc=dwmw@amazon.co.uk \
--cc=jason@lakedaemon.net \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maz@kernel.org \
--cc=zeev@amazon.com \
--cc=zorik@amazon.com \
/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).