From: Lorenzo Pieralisi <lpieralisi@kernel.org>
To: Marc Zyngier <maz@kernel.org>
Cc: linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org,
"Toan Le" <toan@os.amperecomputing.com>,
"Krzysztof Wilczyński" <kwilczynski@kernel.org>,
"Manivannan Sadhasivam" <mani@kernel.org>,
"Rob Herring" <robh@kernel.org>,
"Bjorn Helgaas" <bhelgaas@google.com>,
"Thomas Gleixner" <tglx@linutronix.de>
Subject: Re: [PATCH v2 09/13] PCI: xgene-msi: Sanitise MSI allocation and affinity setting
Date: Fri, 11 Jul 2025 12:11:02 +0200 [thread overview]
Message-ID: <aHDjNr59aMzVQ5iA@lpieralisi> (raw)
In-Reply-To: <aHDfhVRa1lhu7qPg@lpieralisi>
On Fri, Jul 11, 2025 at 11:55:17AM +0200, Lorenzo Pieralisi wrote:
> On Tue, Jul 08, 2025 at 06:34:00PM +0100, Marc Zyngier wrote:
[...]
> We could use MSInRx_HWIRQ_MASK, I can update it.
>
> More importantly, what code would set data->hwirq[6:4] (and
> data->hwirq[7:7] below) ?
Forget it. It is the hwirq allocation itself that sets those bits,
256 HWIRQs you use the effective cpu affinity to steer the frame,
it makes sense now.
I can update the code to use the mask above and merge it.
Sorry for the noise,
Lorenzo
> > + frame = FIELD_PREP(BIT(3), FIELD_GET(BIT(7), data->hwirq)) | cpu;
> >
> > -/*
> > - * X-Gene v1 only has 16 MSI GIC IRQs for 2048 MSI vectors. To maintain
> > - * the expected behaviour of .set_affinity for each MSI interrupt, the 16
> > - * MSI GIC IRQs are statically allocated to 8 X-Gene v1 cores (2 GIC IRQs
> > - * for each core). The MSI vector is moved from 1 MSI GIC IRQ to another
> > - * MSI GIC IRQ to steer its MSI interrupt to correct X-Gene v1 core. As a
> > - * consequence, the total MSI vectors that X-Gene v1 supports will be
> > - * reduced to 256 (2048/8) vectors.
> > - */
> > -static int hwirq_to_cpu(unsigned long hwirq)
> > -{
> > - return (hwirq % num_possible_cpus());
> > -}
> > + target_addr = msi->msi_addr;
> > + target_addr += (FIELD_PREP(MSI_GROUP_MASK, frame) |
> > + FIELD_PREP(MSI_INTR_MASK, msir));
> >
> > -static unsigned long hwirq_to_canonical_hwirq(unsigned long hwirq)
> > -{
> > - return (hwirq - hwirq_to_cpu(hwirq));
> > + msg->address_hi = upper_32_bits(target_addr);
> > + msg->address_lo = lower_32_bits(target_addr);
> > + msg->data = FIELD_GET(DATA_HWIRQ_MASK, data->hwirq);
> > }
> >
> > static int xgene_msi_set_affinity(struct irq_data *irqdata,
> > const struct cpumask *mask, bool force)
> > {
> > int target_cpu = cpumask_first(mask);
> > - int curr_cpu;
> > -
> > - curr_cpu = hwirq_to_cpu(irqdata->hwirq);
> > - if (curr_cpu == target_cpu)
> > - return IRQ_SET_MASK_OK_DONE;
> >
> > - /* Update MSI number to target the new CPU */
> > - irqdata->hwirq = hwirq_to_canonical_hwirq(irqdata->hwirq) + target_cpu;
> > + irq_data_update_effective_affinity(irqdata, cpumask_of(target_cpu));
> >
> > + /* Force the core code to regenerate the message */
> > return IRQ_SET_MASK_OK;
> > }
> >
> > @@ -173,23 +167,20 @@ static int xgene_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
> > unsigned int nr_irqs, void *args)
> > {
> > struct xgene_msi *msi = domain->host_data;
> > - int msi_irq;
> > + irq_hw_number_t hwirq;
> >
> > mutex_lock(&msi->bitmap_lock);
> >
> > - msi_irq = bitmap_find_next_zero_area(msi->bitmap, NR_MSI_VEC, 0,
> > - num_possible_cpus(), 0);
> > - if (msi_irq < NR_MSI_VEC)
> > - bitmap_set(msi->bitmap, msi_irq, num_possible_cpus());
> > - else
> > - msi_irq = -ENOSPC;
> > + hwirq = find_first_zero_bit(msi->bitmap, NR_MSI_VEC);
> > + if (hwirq < NR_MSI_VEC)
> > + set_bit(hwirq, msi->bitmap);
> >
> > mutex_unlock(&msi->bitmap_lock);
> >
> > - if (msi_irq < 0)
> > - return msi_irq;
> > + if (hwirq >= NR_MSI_VEC)
> > + return -ENOSPC;
> >
> > - irq_domain_set_info(domain, virq, msi_irq,
> > + irq_domain_set_info(domain, virq, hwirq,
> > &xgene_msi_bottom_irq_chip, domain->host_data,
> > handle_simple_irq, NULL, NULL);
>
> This is something I don't get. We alloc an MSI, set a bit in the bitmap
> and the hwirq to that value, when we handle the IRQ below in
>
> xgene_msi_isr()
>
> hwirq = compute_hwirq(msi_grp, msir_idx, intr_idx);
> ret = generic_handle_domain_irq(xgene_msi->inner_domain, hwirq);
>
> imagining that we changed the affinity for the IRQ so that the computed
> HWIRQ does not have zeros in bits[7:4], how would the domain HWIRQ
> matching work ?
>
> Actually, how would an IRQ fire causing the hwirq[7:4] bits to be != 0
> in the first place ?
>
> Forgive me if I am missing something obvious, the *current* MSI handling
> is very hard to grok, it is certain I misunderstood it entirely.
>
> Thanks,
> Lorenzo
>
> > @@ -201,12 +192,10 @@ static void xgene_irq_domain_free(struct irq_domain *domain,
> > {
> > struct irq_data *d = irq_domain_get_irq_data(domain, virq);
> > struct xgene_msi *msi = irq_data_get_irq_chip_data(d);
> > - u32 hwirq;
> >
> > mutex_lock(&msi->bitmap_lock);
> >
> > - hwirq = hwirq_to_canonical_hwirq(d->hwirq);
> > - bitmap_clear(msi->bitmap, hwirq, num_possible_cpus());
> > + clear_bit(d->hwirq, msi->bitmap);
> >
> > mutex_unlock(&msi->bitmap_lock);
> >
> > @@ -263,55 +252,30 @@ static void xgene_msi_isr(struct irq_desc *desc)
> > unsigned int *irqp = irq_desc_get_handler_data(desc);
> > struct irq_chip *chip = irq_desc_get_chip(desc);
> > struct xgene_msi *xgene_msi = xgene_msi_ctrl;
> > - int msir_index, msir_val, hw_irq, ret;
> > - u32 intr_index, grp_select, msi_grp;
> > + unsigned long grp_pending;
> > + int msir_idx;
> > + u32 msi_grp;
> >
> > chained_irq_enter(chip, desc);
> >
> > msi_grp = irqp - xgene_msi->gic_irq;
> >
> > - /*
> > - * MSIINTn (n is 0..F) indicates if there is a pending MSI interrupt
> > - * If bit x of this register is set (x is 0..7), one or more interrupts
> > - * corresponding to MSInIRx is set.
> > - */
> > - grp_select = xgene_msi_int_read(xgene_msi, msi_grp);
> > - while (grp_select) {
> > - msir_index = ffs(grp_select) - 1;
> > - /*
> > - * Calculate MSInIRx address to read to check for interrupts
> > - * (refer to termination address and data assignment
> > - * described in xgene_compose_msi_msg() )
> > - */
> > - msir_val = xgene_msi_ir_read(xgene_msi, msi_grp, msir_index);
> > - while (msir_val) {
> > - intr_index = ffs(msir_val) - 1;
> > - /*
> > - * Calculate MSI vector number (refer to the termination
> > - * address and data assignment described in
> > - * xgene_compose_msi_msg function)
> > - */
> > - hw_irq = (((msir_index * IRQS_PER_IDX) + intr_index) *
> > - NR_HW_IRQS) + msi_grp;
> > - /*
> > - * As we have multiple hw_irq that maps to single MSI,
> > - * always look up the virq using the hw_irq as seen from
> > - * CPU0
> > - */
> > - hw_irq = hwirq_to_canonical_hwirq(hw_irq);
> > - ret = generic_handle_domain_irq(xgene_msi->inner_domain, hw_irq);
> > + grp_pending = xgene_msi_int_read(xgene_msi, msi_grp);
> > +
> > + for_each_set_bit(msir_idx, &grp_pending, IDX_PER_GROUP) {
> > + unsigned long msir;
> > + int intr_idx;
> > +
> > + msir = xgene_msi_ir_read(xgene_msi, msi_grp, msir_idx);
> > +
> > + for_each_set_bit(intr_idx, &msir, IRQS_PER_IDX) {
> > + irq_hw_number_t hwirq;
> > + int ret;
> > +
> > + hwirq = compute_hwirq(msi_grp, msir_idx, intr_idx);
> > + ret = generic_handle_domain_irq(xgene_msi->inner_domain,
> > + hwirq);
> > WARN_ON_ONCE(ret);
> > - msir_val &= ~(1 << intr_index);
> > - }
> > - grp_select &= ~(1 << msir_index);
> > -
> > - if (!grp_select) {
> > - /*
> > - * We handled all interrupts happened in this group,
> > - * resample this group MSI_INTx register in case
> > - * something else has been made pending in the meantime
> > - */
> > - grp_select = xgene_msi_int_read(xgene_msi, msi_grp);
> > }
> > }
> >
> > --
> > 2.39.2
> >
next prev parent reply other threads:[~2025-07-11 12:29 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-08 17:33 [PATCH v2 00/13] PCI: xgene: Fix and simplify the MSI driver Marc Zyngier
2025-07-08 17:33 ` [PATCH v2 01/13] genirq: Teach handle_simple_irq() to resend an in-progress interrupt Marc Zyngier
2025-07-08 17:33 ` [PATCH v2 02/13] PCI: xgene: Defer probing if the MSI widget driver hasn't probed yet Marc Zyngier
2025-07-08 17:33 ` [PATCH v2 03/13] PCI: xgene: Drop useless conditional compilation Marc Zyngier
2025-07-08 17:33 ` [PATCH v2 04/13] PCI: xgene: Drop XGENE_PCIE_IP_VER_UNKN Marc Zyngier
2025-07-08 17:33 ` [PATCH v2 05/13] PCI: xgene-msi: Make per-CPU interrupt setup robust Marc Zyngier
2025-07-08 17:33 ` [PATCH v2 06/13] PCI: xgene-msi: Drop superfluous fields from xgene_msi structure Marc Zyngier
2025-07-17 11:24 ` Markus Elfring
2025-07-08 17:33 ` [PATCH v2 07/13] PCI: xgene-msi: Use device-managed memory allocations Marc Zyngier
2025-07-08 17:33 ` [PATCH v2 08/13] PCI: xgene-msi: Get rid of intermediate tracking structure Marc Zyngier
2025-07-08 17:34 ` [PATCH v2 09/13] PCI: xgene-msi: Sanitise MSI allocation and affinity setting Marc Zyngier
2025-07-11 9:55 ` Lorenzo Pieralisi
2025-07-11 10:11 ` Lorenzo Pieralisi [this message]
2025-07-11 10:51 ` Marc Zyngier
2025-07-11 10:50 ` Marc Zyngier
2025-07-08 17:34 ` [PATCH v2 10/13] PCI: xgene-msi: Resend an MSI racing with itself on a different CPU Marc Zyngier
2025-07-08 17:34 ` [PATCH v2 11/13] PCI: xgene-msi: Probe as a standard platform driver Marc Zyngier
2025-07-17 11:45 ` Markus Elfring
2025-07-17 13:18 ` Lorenzo Pieralisi
2025-07-08 17:34 ` [PATCH v2 12/13] PCI: xgene-msi: Restructure handler setup/teardown Marc Zyngier
2025-07-08 17:34 ` [PATCH v2 13/13] cpu/hotplug: Remove unused cpuhp_state CPUHP_PCI_XGENE_DEAD Marc Zyngier
2025-07-11 13:15 ` Lorenzo Pieralisi
2025-07-17 9:52 ` [PATCH v2 00/13] PCI: xgene: Fix and simplify the MSI driver Lorenzo Pieralisi
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=aHDjNr59aMzVQ5iA@lpieralisi \
--to=lpieralisi@kernel.org \
--cc=bhelgaas@google.com \
--cc=kwilczynski@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=mani@kernel.org \
--cc=maz@kernel.org \
--cc=robh@kernel.org \
--cc=tglx@linutronix.de \
--cc=toan@os.amperecomputing.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.