Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Tushar Nimkar <tunimkar@amd.com>
To: Thomas Gleixner <tglx@linutronix.de>,
	Tushar Nimkar <tushar.nimkar@amd.com>,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
Cc: Michal Simek <michal.simek@amd.com>,
	"Sarangi, Anirudha" <anirudha.sarangi@amd.com>,
	git@amd.com
Subject: Re: [PATCH 2/2] irqchip: Add Xilinx Versal NET SMMU CSR interrupt controller driver
Date: Mon, 24 Aug 2026 14:55:37 +0530	[thread overview]
Message-ID: <41587817-c7dd-4fb2-aad7-772f85dedd6d@amd.com> (raw)
In-Reply-To: <87ik55kirt.ffs@fw13>

Hi Thomas,

thanks for reviewing.

On 8/20/2026 1:03 AM, Thomas Gleixner wrote:
> Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or responding.
>
>
> On Mon, Aug 17 2026 at 16:22, Tushar Nimkar wrote:
>> +/**
>> + * struct xilinx_smmu_csr - SMMU CSR interrupt controller context
>> + * @base: MMIO base address of the CSR registers
>> + * @domain: IRQ domain for the child interrupts
>> + * @parent_irq: parent (GIC) IRQ this block is chained to
>> + * @lock: protects the SMMU_CSR_IER/IDR/ISR read and writes
> Please make the member descriptions tabular aligned
>
>      @base:      MMIO ...
>      @domain:    Interrupt domain
>
> And yes, use interrupt and not IRQ. This is not twitter.
sure.
>> +static void xilinx_smmu_csr_irq_mask(struct irq_data *d)
>> +{
>> +     struct xilinx_smmu_csr *csr = irq_data_get_irq_chip_data(d);
>> +     u32 mask = xilinx_smmu_csr_hwirq_mask(d->hwirq);
>> +
>> +     if (!mask)
>> +             return;
>> +
>> +     raw_spin_lock(&csr->lock);
>    guard(raw_spinlock)(&crs->lock);

okay

>
>> +     writel(mask, csr->base + SMMU_CSR_IDR);
>> +     raw_spin_unlock(&csr->lock);
>> +}
>> +
>> +static void xilinx_smmu_csr_irq_unmask(struct irq_data *d)
>> +{
>> +     struct xilinx_smmu_csr *csr = irq_data_get_irq_chip_data(d);
>> +     u32 mask = xilinx_smmu_csr_hwirq_mask(d->hwirq);
>> +
>> +     if (!mask)
>> +             return;
>> +
>> +     raw_spin_lock(&csr->lock);
> Ditto
okay
>> +     writel(mask, csr->base + SMMU_CSR_IER);
>> +     raw_spin_unlock(&csr->lock);
>> +}
>> +
>> +static void xilinx_smmu_csr_irq_ack(struct irq_data *d)
>> +{
>> +     struct xilinx_smmu_csr *csr = irq_data_get_irq_chip_data(d);
>> +     u32 mask = xilinx_smmu_csr_hwirq_mask(d->hwirq);
>> +
>> +     if (!mask)
>> +             return;
>> +
>> +     raw_spin_lock(&csr->lock);
> Ditto.
okay
>
>> +     writel(mask, csr->base + SMMU_CSR_ISR);
>> +     raw_spin_unlock(&csr->lock);
>> +}
>> +
>> +static struct irq_chip xilinx_smmu_csr_chip = {
>> +     .name           = "xlnx-smmu-csr",
>> +     .irq_mask       = xilinx_smmu_csr_irq_mask,
>> +     .irq_unmask     = xilinx_smmu_csr_irq_unmask,
>> +     .irq_ack        = xilinx_smmu_csr_irq_ack,
>> +};
>> +
>> +static void xilinx_smmu_csr_irq_handler(struct irq_desc *desc)
>> +{
>> +     struct xilinx_smmu_csr *csr = irq_desc_get_handler_data(desc);
>> +     struct irq_chip *chip = irq_desc_get_chip(desc);
>> +     u32 status, pending;
>> +
>> +     chained_irq_enter(chip, desc);
>> +     raw_spin_lock(&csr->lock);
> scoped_guard() if you can explain what the lock is actually protecting
> here ...
will remove seems not needed.
>> +     status = readl(csr->base + SMMU_CSR_ISR);
>> +     raw_spin_unlock(&csr->lock);
>> +
>> +     /* Only service sources we support; SMMU_CSR_ISR latches raw status */
>> +     pending = status & SMMU_INTR_ALL;
>> +
>> +     while (pending) {
>> +             irq_hw_number_t hwirq = __ffs(pending);
>> +             int ret;
>> +
>> +             ret = generic_handle_domain_irq(csr->domain, hwirq);
>> +             if (ret) {
>> +                     raw_spin_lock(&csr->lock);
>> +                     writel(BIT(hwirq), csr->base + SMMU_CSR_ISR);
>> +                     raw_spin_unlock(&csr->lock);
> ... and here. There is _ONE_ chained demultiplex handler per chip, so where
> is the concurrency vs. the read and write from/to SMMU_CSR_ISR?
>
> The irq_ack() callback of the demultiplexed interrupts cannot happen
> concurrently because that happens in the context of the demultiplexed
> handler invoked by generic_handle_domain_irq(). No?
I agree! Locking part will be removed.
>
> Not that I care about the performance of your code, but I care about
> code clarity. If there is a reason for this magic lock voodoo here, then
> please explain it in a comment.
>
> Also this write here wants a comment. Why is the pending bit written
> back in the failure case? I assume to acknowlegde the interrupt. How are
> the interrupts which are handled acknowledged?

The original intention was to handle cases where an interrupt source is 
asserted but the ARM SMMUv3 driver has not registered a corresponding 
handler yet. In that case generic_handle_domain_irq() returns an error 
and the interrupt remains pending, which can lead to an interrupt storm.
The write-back was added to clear the pending status in that failure path.
However, with the current implementation we only process interrupt 
sources covered by SMMU_INTR_ALL:
...

         /* Only service sources we support; SMMU_CSR_ISR latches raw 
status */
         pending = status & SMMU_INTR_ALL;
...

and those are expected to have registered handlers. Therefore the 
failure case should not be reachable today. Given that, I agree the 
extra locking/acknowledgement logic is not justified and can be removed 
for clarity.
We could always reintroduce it if support for additional interrupt 
sources is added in the future.

>
> Also if this happens, then this code should make sure to mask this
> interrupt line because if something left it unmasked it will come back
> forever.
Shall we mask still ?
>> +                     pr_err_ratelimited("xilinx-smmu-csr: Failed to handle domain IRQ %lu: %d\n",
>> +                                        hwirq, ret);
>> +             }
>> +
>> +             pending &= ~BIT(hwirq);
>> +     }
>> +static int __init xilinx_smmu_csr_init(struct device_node *node,
>> +                                    struct device_node *parent)
> No line break required. You have 100 characters. Please fix that up all over the place.
okay
>> +{
>> +     struct xilinx_smmu_csr *csr;
>> +     int ret;
>> +
>> +     if (WARN_ON_ONCE(!parent))
>> +             return -EINVAL;
>> +
>> +     if (irq_find_matching_fwnode(of_fwnode_handle(node),
>> +                                  DOMAIN_BUS_ANY))
>> +             return -ENODEV;
>> +
>> +     csr = kzalloc(sizeof(*csr), GFP_KERNEL);
> devm_kzalloc()
okay
>
>> +     if (!csr)
>> +             return -ENOMEM;
>> +
>> +     raw_spin_lock_init(&csr->lock);
>> +
>> +     csr->base = of_iomap(node, 0);
> devm_of_iomap()
okay
>
>> +     if (!csr->base) {
>> +             ret = -ENOMEM;
>> +             goto free;
>> +     }
>> +
>> +     /* Start from a known state: all sources disabled, latches cleared. */
>> +     writel(SMMU_INTR_ALL, csr->base + SMMU_CSR_IDR);
>> +     writel(SMMU_INTR_ALL, csr->base + SMMU_CSR_ISR);
>> +
>> +     csr->domain = irq_domain_create_linear(of_fwnode_handle(node), SMMU_CSR_IRQ_NR,
>> +                                            &xilinx_smmu_csr_domain_ops,
>> +                                            csr);
> devm_irq_domain_instantiate() or use this one:
>
>   https://lore.kernel.org/lkml/20260819090543.585131-2-Zhipeng.wang_1@oss.nxp.com/
>
> It's not merged into tip yet, but it will be.
okay sure,  let me re-base.
>
>> +     if (!csr->domain) {
>> +             pr_err("%pOF: failed to create irq domain\n", node);
>> +             ret = -ENOMEM;
>> +             goto unmap;
> with that all these 'ret = -ERROR; goto foo;' go away.
did not get you here,
>
> Thanks,
>
>          tglx

Thanks,
Tushar



      reply	other threads:[~2026-08-24  9:26 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-17 10:52 [PATCH 2/2] irqchip: Add Xilinx Versal NET SMMU CSR interrupt controller driver Tushar Nimkar
2026-08-19 19:33 ` Thomas Gleixner
2026-08-24  9:25   ` Tushar Nimkar [this message]

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=41587817-c7dd-4fb2-aad7-772f85dedd6d@amd.com \
    --to=tunimkar@amd.com \
    --cc=anirudha.sarangi@amd.com \
    --cc=git@amd.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=michal.simek@amd.com \
    --cc=tglx@linutronix.de \
    --cc=tushar.nimkar@amd.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