From: "Björn Töpel" <bjorn@kernel.org>
To: Anup Patel <apatel@ventanamicro.com>
Cc: Palmer Dabbelt <palmer@dabbelt.com>,
Paul Walmsley <paul.walmsley@sifive.com>,
Thomas Gleixner <tglx@linutronix.de>,
Rob Herring <robh+dt@kernel.org>,
Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
Frank Rowand <frowand.list@gmail.com>,
Conor Dooley <conor+dt@kernel.org>, Marc Zyngier <maz@kernel.org>,
Atish Patra <atishp@atishpatra.org>,
Andrew Jones <ajones@ventanamicro.com>,
Sunil V L <sunilvl@ventanamicro.com>,
Saravana Kannan <saravanak@google.com>,
Anup Patel <anup@brainfault.org>,
linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org
Subject: Re: [PATCH v11 07/14] irqchip: Add RISC-V incoming MSI controller early driver
Date: Wed, 25 Oct 2023 18:05:08 +0200 [thread overview]
Message-ID: <875y2ug023.fsf@all.your.base.are.belong.to.us> (raw)
In-Reply-To: <CAK9=C2XpxYztxgD-5HQ+1kThBaRTv3pVk5eah4XHZ_8x62BwqQ@mail.gmail.com>
Hi!
Anup Patel <apatel@ventanamicro.com> writes:
> On Tue, Oct 24, 2023 at 6:35 PM Björn Töpel <bjorn@kernel.org> wrote:
>>
>> Hi Anup!
>>
>> Wow, I'm really happy to see that you're moving towards the 1-1 model!
>>
>> Anup Patel <apatel@ventanamicro.com> writes:
>>
>> > The RISC-V advanced interrupt architecture (AIA) specification
>> > defines a new MSI controller called incoming message signalled
>> > interrupt controller (IMSIC) which manages MSI on per-HART (or
>> > per-CPU) basis. It also supports IPIs as software injected MSIs.
>> > (For more details refer https://github.com/riscv/riscv-aia)
>> >
>> > Let us add an early irqchip driver for RISC-V IMSIC which sets
>> > up the IMSIC state and provide IPIs.
>>
>> It would help (reviewers, and future bugfixers) if you add (here or in
>> the cover) what design decisions you've taken instead of just saying
>> that you're now supporting IMSIC.
>
> I agree with the suggestion but this kind of information should be
> in the source itself rather than commit description.
I think the high-level flow, and why you made certain design decisions
should be in the commit message.
The "how" in the code, the "why" in the commit message. Regardless -- it
would make it easier for reviewers to get into your code faster.
[...]
>> > +
>> > + writel(IMSIC_IPI_ID, local->msi_va);
>>
>> Do you need the barriers here? If so, please document. If not, use the
>> _releaxed() version.
>
> We can't assume that _relaxed version of MMIO operations
> will work for RISC-V implementation so we conservatively
> use regular MMIO operations without _releaxed().
You'll need to expand on your thinking here, Anup. We can't just
sprinkle fences everywhere because of "we can't assume it'll work". Do
you need proper barriers for IPIs or not?
[...]
>> > + mvec = lpriv->ids_move[i];
>> > + lpriv->ids_move[i] = NULL;
>> > + if (mvec) {
>> > + if (__imsic_id_read_clear_pending(i)) {
>> > + mlocal = per_cpu_ptr(imsic->global.local,
>> > + mvec->cpu);
>> > + writel(mvec->local_id, mlocal->msi_va);
>>
>> Again, do you need all the barriers? If yes, document. No, then relax
>> the call.
>
> Same comment as above.
Dito for me! ;-)
>> > + }
>> > +
>> > + lpriv->vectors[i].hwirq = UINT_MAX;
>> > + lpriv->vectors[i].order = UINT_MAX;
>> > + clear_bit(i, lpriv->ids_used_bitmap);
>> > + }
>> > +
>> > + }
>> > + raw_spin_unlock_irqrestore(&lpriv->ids_lock, flags);
>> > +}
>> > +
>> > +void imsic_local_delivery(bool enable)
>> > +{
>> > + if (enable) {
>> > + imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_ENABLE_EITHRESHOLD);
>> > + imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_ENABLE_EIDELIVERY);
>> > + } else {
>> > + imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_DISABLE_EIDELIVERY);
>> > + imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_DISABLE_EITHRESHOLD);
>> > + }
>>
>> My regular "early exit" nit. I guess I really dislike indentation. ;-)
>
> -ENOPARSE
if (...) {
a();
b();
c();
} else {
d();
e();
}
vs
if (...) {
a();
b();
c();
return;
}
d();
e();
[...]
>> > +void imsic_vector_mask(struct imsic_vector *vec)
>> > +{
>> > + struct imsic_local_priv *lpriv;
>> > + unsigned long flags;
>> > +
>> > + lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
>> > + if (WARN_ON(&lpriv->vectors[vec->local_id] != vec))
>> > + return;
>> > +
>> > + raw_spin_lock_irqsave(&lpriv->ids_lock, flags);
>> > + bitmap_clear(lpriv->ids_enabled_bitmap, vec->local_id, 1);
>> > + raw_spin_unlock_irqrestore(&lpriv->ids_lock, flags);
>> > +
>> > + imsic_remote_sync(vec->cpu);
>>
>> x86 seems to set a timer instead, for the remote cpu cleanup, which can
>> be much cheaper, and less in instrusive. Is that applicable here?
>
> The issue with that approach is deciding the right duration
> of timer interrupt. There might be platforms who need
> immediate mask/unmask response. We can certainely
> keep improving/tuning this over-time.
Any concrete examples where this is an actual problem?
[...]
>> > +void imsic_vector_move(struct imsic_vector *old_vec,
>> > + struct imsic_vector *new_vec)
>> > +{
>> > + struct imsic_local_priv *old_lpriv, *new_lpriv;
>> > + struct imsic_vector *ovec, *nvec;
>> > + unsigned long flags, flags1;
>> > + unsigned int i;
>> > +
>> > + if (WARN_ON(old_vec->cpu == new_vec->cpu ||
>> > + old_vec->order != new_vec->order ||
>> > + (old_vec->local_id & IMSIC_VECTOR_MASK(old_vec)) ||
>> > + (new_vec->local_id & IMSIC_VECTOR_MASK(new_vec))))
>> > + return;
>> > +
>> > + old_lpriv = per_cpu_ptr(imsic->lpriv, old_vec->cpu);
>> > + if (WARN_ON(&old_lpriv->vectors[old_vec->local_id] != old_vec))
>> > + return;
>> > +
>> > + new_lpriv = per_cpu_ptr(imsic->lpriv, new_vec->cpu);
>> > + if (WARN_ON(&new_lpriv->vectors[new_vec->local_id] != new_vec))
>> > + return;
>> > +
>> > + raw_spin_lock_irqsave(&old_lpriv->ids_lock, flags);
>> > + raw_spin_lock_irqsave(&new_lpriv->ids_lock, flags1);
>> > +
>> > + /* Move the state of each vector entry */
>> > + for (i = 0; i < BIT(old_vec->order); i++) {
>> > + ovec = old_vec + i;
>> > + nvec = new_vec + i;
>> > +
>> > + /* Unmask the new vector entry */
>> > + if (test_bit(ovec->local_id, old_lpriv->ids_enabled_bitmap))
>> > + bitmap_set(new_lpriv->ids_enabled_bitmap,
>> > + nvec->local_id, 1);
>> > +
>> > + /* Mask the old vector entry */
>> > + bitmap_clear(old_lpriv->ids_enabled_bitmap, ovec->local_id, 1);
>> > +
>> > + /*
>> > + * Move and re-trigger the new vector entry based on the
>> > + * pending state of the old vector entry because we might
>> > + * get a device interrupt on the old vector entry while
>> > + * device was being moved to the new vector entry.
>> > + */
>> > + old_lpriv->ids_move[ovec->local_id] = nvec;
>> > + }
>>
>> Hmm, nested spinlocks, and reimplementing what the irq matrix allocator
>> does.
>>
>> Convince me why irq matrix is not a good fit to track the interrupts IDs
>> *and* get handling/tracking for managed/unmanaged interrupts. You said
>> that it was the power-of-two blocks for MSI, but can't that be enfored
>> on matrix alloc? Where are you doing the special handling of MSI?
>>
>> The reason I'm asking is because I'm pretty certain that x86 has proper
>> MSI support (Thomas Gleixner can answer for sure! ;-))
>>
>> IMSIC smells a lot like the the LAPIC. The implementation could probably
>> be *very* close to what arch/x86/kernel/apic/vector.c does.
>>
>> Am I completly off here?
>>
>
> The x86 APIC driver only supports MSI-X due to which the IRQ matrix
> allocator only supports ID/Vector allocation suitable for MSI-X whereas
> the ARM GICv3 driver supports both legacy MSI and MSI-X. In absence
> of legacy MSI support, Linux x86 will fallback to INTx for PCI devices
> with legacy MSI support but for RISC-V platforms we can't assume that
> INTx is available because we might be dealing with an IMSIC-only
> platform.
You're mixing up MSI and *multi-MSI* (multiple MSI vectors).
x86 support MSI-X, MSI, and multi-MSI with IOMMU.
Gleixner has a some insights on why one probably should *not* jump
through hoops to support multi-MSI:
https://lore.kernel.org/all/877d7yhve7.ffs@tglx/
Will we really see HW requiring multi-MSI support on RISC-V systems
without IOMMU? To me this sounds like a theoretical exercise.
> Refer, x86_vector_msi_parent_ops in arch/x86/kernel/apic/msi.c and
> X86_VECTOR_MSI_FLAGS_SUPPORTED in arch/x86/include/asm/msi.h
>
> Refer, its_pci_msi_domain_info in drivers/irqchip/irq-gic-v3-its-pci-msi.c
>
> The changes which I think are need in the IRQ matrix allocator before
> integrating it in the IMSIC driver are the following:
> 1) IRQ matrix allocator assumed NR_VECTORS to be a fixed define
> which the arch code provides but in RISC-V world the number of
> IDs are discovered from DT or ACPI.
Ok, let's try to be bit more explicit. Have you had a look at
kernel/irq/matrix.c?
You need to define the IRQ_MATRIX_BITS (which x86 sets to NR_VECTORS).
This is the size of the bitmap. For IMSIC this would be 2047.
The matrix allocator is an excellent fit, modulo multi-MSI. It's battle
proven code.
> 2) IRQ matrix allocator needs to be support allocator multiple vectors
> in power-of-2 which will allow IMSIC driver to support both legacy
> MSI and MSI-X. This will involve changing the way best CPU is
> found, the way bitmap APIs are used and adding some new APIs
> for allocate vectors in power-of-2
...and all the other things multi-MSI requires.
> Based on above, I suggest we keep the integration of IRQ matrix
> allocator in the IMSIC driver as a separate series which will allow
> us to unblock other series (such as AIA ACPI support, power
> managment related changes in AIA drivers, etc).
I suggest removing the multi-MSI support, and use the matrix allocator.
We have something that looks like what x86 has (IMSIC). We have a
battle-proven implementation, and helper function. In my view it would
be just weird not to piggy-back on that work, and benefit from years of
bugfixes/things we haven't thought of.
Finally; I don't see that you're handling managed interrupt in the
series (Oh, the matrix allocator has support for that! ;-)).
I realize it's some changes, but the interrupt handling is a central
piece.
If you agree with my input, LMK if you're time/work-constrained, and I
can take a stab at integrating it in the series.
Björn
next prev parent reply other threads:[~2023-10-25 16:05 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-23 17:27 [PATCH v11 00/14] Linux RISC-V AIA Support Anup Patel
2023-10-23 17:27 ` [PATCH v11 01/14] RISC-V: Don't fail in riscv_of_parent_hartid() for disabled HARTs Anup Patel
2023-10-24 11:55 ` Björn Töpel
2023-10-24 12:07 ` Anup Patel
2023-10-23 17:27 ` [PATCH v11 02/14] of: property: Add fw_devlink support for msi-parent Anup Patel
2023-10-23 17:27 ` [PATCH v11 03/14] irqchip/sifive-plic: Fix syscore registration for multi-socket systems Anup Patel
2023-10-23 17:27 ` [PATCH v11 04/14] irqchip/sifive-plic: Convert PLIC driver into a platform driver Anup Patel
2023-10-23 17:27 ` [PATCH v11 05/14] irqchip/riscv-intc: Add support for RISC-V AIA Anup Patel
2023-10-24 12:17 ` Andrew Jones
2023-10-23 17:27 ` [PATCH v11 06/14] dt-bindings: interrupt-controller: Add RISC-V incoming MSI controller Anup Patel
2023-10-24 12:30 ` Andrew Jones
2023-10-23 17:27 ` [PATCH v11 07/14] irqchip: Add RISC-V incoming MSI controller early driver Anup Patel
2023-10-24 9:25 ` Conor Dooley
2023-10-24 12:08 ` Anup Patel
2023-10-24 13:05 ` Björn Töpel
2023-10-25 5:08 ` Anup Patel
2023-10-25 16:05 ` Björn Töpel [this message]
2023-10-25 17:25 ` Anup Patel
2023-10-26 8:51 ` Björn Töpel
2023-10-28 18:18 ` Thomas Gleixner
2023-10-28 18:34 ` Thomas Gleixner
2023-10-23 17:27 ` [PATCH v11 08/14] irqchip/riscv-imsic: Add support for platform MSI irqdomain Anup Patel
2023-10-25 19:56 ` Thomas Gleixner
2023-10-23 17:27 ` [PATCH v11 09/14] irqchip/riscv-imsic: Add support for PCI " Anup Patel
2023-10-24 13:09 ` Björn Töpel
2023-10-25 5:08 ` Anup Patel
2023-10-25 8:55 ` Björn Töpel
2023-10-28 18:36 ` Thomas Gleixner
2023-10-29 19:53 ` Björn Töpel
2023-10-25 19:59 ` Thomas Gleixner
2023-10-23 17:27 ` [PATCH v11 10/14] dt-bindings: interrupt-controller: Add RISC-V advanced PLIC Anup Patel
2023-10-23 17:27 ` [PATCH v11 11/14] irqchip: Add RISC-V advanced PLIC driver for direct-mode Anup Patel
2023-10-23 17:27 ` [PATCH v11 12/14] irqchip/riscv-aplic: Add support for MSI-mode Anup Patel
2023-10-24 5:31 ` Sunil V L
2023-11-02 6:38 ` Ben
[not found] ` <210e2757.3169.18b8eb4495c.Coremail.figure1802@126.com>
2023-11-02 12:37 ` [PATCH " Anup Patel
2023-11-03 9:39 ` Ben
2023-11-03 11:04 ` Anup Patel
2023-11-04 0:58 ` Ben
2023-11-08 14:20 ` Ben
2023-11-08 14:43 ` [PATCH " Anup Patel
2023-11-08 14:51 ` Ben
2023-11-08 14:56 ` Anup Patel
2023-11-08 15:32 ` Ben
2023-11-14 9:21 ` Anup Patel
2023-10-23 17:27 ` [PATCH v11 13/14] RISC-V: Select APLIC and IMSIC drivers Anup Patel
2023-10-23 17:28 ` [PATCH v11 14/14] MAINTAINERS: Add entry for RISC-V AIA drivers Anup Patel
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=875y2ug023.fsf@all.your.base.are.belong.to.us \
--to=bjorn@kernel.org \
--cc=ajones@ventanamicro.com \
--cc=anup@brainfault.org \
--cc=apatel@ventanamicro.com \
--cc=atishp@atishpatra.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=frowand.list@gmail.com \
--cc=krzysztof.kozlowski+dt@linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=maz@kernel.org \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=robh+dt@kernel.org \
--cc=saravanak@google.com \
--cc=sunilvl@ventanamicro.com \
--cc=tglx@linutronix.de \
/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
all inboxes | Powered by JetHome®