From: Nicolin Chen <nicolinc@nvidia.com>
To: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Cc: <will@kernel.org>, <robin.murphy@arm.com>, <jgg@nvidia.com>,
<joro@8bytes.org>, <bhelgaas@google.com>, <praan@google.com>,
<kevin.tian@intel.com>, <kees@kernel.org>, <smostafa@google.com>,
<baolu.lu@linux.intel.com>,
<linux-arm-kernel@lists.infradead.org>, <iommu@lists.linux.dev>,
<linux-kernel@vger.kernel.org>, <linux-pci@vger.kernel.org>,
<skaestle@nvidia.com>, <mmarrid@nvidia.com>,
<skolothumtho@nvidia.com>, <bbiber@nvidia.com>,
<harsha.v@oss.qualcomm.com>
Subject: Re: [PATCH v3 03/13] iommu/arm-smmu-v3: Drain in-flight fault events on domain detach
Date: Fri, 4 Sep 2026 14:42:40 -0700 [thread overview]
Message-ID: <aps7UJktq3IlO5lT@nvidia.com> (raw)
In-Reply-To: <178846311316.1308030.6266899352044838554.b4-review@b4>
On Thu, Sep 03, 2026 at 12:18:33PM -0700, Jonathan Cameron wrote:
> > +/**
> > + * arm_smmu_drain_queue - Drain an SMMU queue
> > + * @smmu: the SMMU device
> > + * @q: the queue to drain
> > + * @until_empty: target selection
> > + *
> > + * With @until_empty == true (for CMDQ), exit once the queue is observed empty:
> > + *
> > + * cons0 cons prod
> > + * | | |
> > + * ---+###################+=====================+=============+--->
> > + * |<--------- undrained==0? --------->|
> ^
> What is the + indicating? Seems where prod0 that isn't relevant here
> would have been - that is a little confusing so maybe drop?
Yes. I drew the other graph first that has prod0, and forgot to
drop it here with prod0 after I copied.
> > + *
> > + * With @until_empty == false (for EVTQ/PRIQ), exit once "drained" reaches its
> > + * target: "pending" (i.e. prod0 - cons0, frozen at the entry time):
> > + *
> > + * cons0 cons prod0 (prod)
> > + * |<---- drained ---->| | |
> > + * ---+###################+=====================+=============+--->
> > + * |<--------------- pending --------------->|
> > + *
> > + * Note that a drained entry is dequeued, but not necessarily handled: the
> > + * EVTQ/PRIQ callers must follow up with a synchronize_irq() to wait for the
> > + * threaded IRQ handler to finish handling the dequeued entries.
> > + *
> > + * Context: Process context; may sleep.
> > + * Return: 0 on success or a negative errno on timeout.
> > + */
> > +static int arm_smmu_drain_queue(struct arm_smmu_device *smmu,
> > + struct arm_smmu_queue *q, bool until_empty)
>
> That name suggests this is doing the draining rather than waiting
> for it to happen elsewhere.
I changed it to "arm_smmu_wait_for_queue_drained".
> > +{
> > + ktime_t timeout = ktime_add_us(ktime_get(), ARM_SMMU_POLL_TIMEOUT_US);
> > + u32 cons, prod, prev, undrained;
> > + u32 drained = 0, pending;
>
> Pet irritation. Prefer splitting the elements that assign and those
> that don't onto seeprate lines. Here that just means moving pending
> up one line.
Done.
+ u32 cons, prod, pending;
+ u32 drained = 0;
> > +
> > + might_sleep();
> > +
> > + cons = readl_relaxed(q->cons_reg);
> > + prod = readl_relaxed(q->prod_reg);
> > + /* The exit target: the number of entries in the queue at entry */
> > + pending = Q_POS(&q->llq, prod - cons);
>
> Applying a macro called Q_POS to a difference is a bit confusing to
> me given the output isn't a position of anything. Maybe just needs
> a wrapper Q_DIFF(q->llq, prod, cons) Can use Q_POS underneath
> but avoid that naming out here well away from the macro definitions.
Sure:
+/* Entries between two positions, i.e. how far @b leads @a */
+#define Q_DIFF(llq, a, b) Q_POS(llq, (b) - (a))
[...]
+ /* The exit target: the number of entries in the queue at entry */
+ pending = Q_DIFF(&q->llq, cons, prod);
[...]
+ cons = readl_relaxed(q->cons_reg);
+ drained += Q_DIFF(&q->llq, prev, cons);
+
+ prod = readl_relaxed(q->prod_reg);
+ undrained = Q_DIFF(&q->llq, cons, prod);
> > +
> > + while (true) {
>
> Maybe pull defintion of prev and undrained in here so it is clear
> they aren't state maintained across iternations.
Done.
+ u32 prev, undrained;
> > + /* Accumulate the entries consumed since the last poll */
> > + prev = cons;
> > + cons = readl_relaxed(q->cons_reg);
> > + drained += Q_POS(&q->llq, cons - prev);
> > +
> > + prod = readl_relaxed(q->prod_reg);
> > + undrained = Q_POS(&q->llq, prod - cons);
> > +
> > + /* Exit on an empty queue, regardless of until_empty */
> > + if (!undrained)
>
> Given you don't use undrained again (maybe in later patches, in which
> case ignore me.)
> if (Q_DIFF(&q->llq, prod, cons) == 0)
> perhaps. This one entirely up to you as maybe the named local does
> help with readability a little.
It's indeed for readability: this matches the graph in the kdocs.
> > + return 0;
> > +
> > + /* Snapshot mode: exit once the pending entries are drained */
> > + if (!until_empty && drained >= pending)
> > + return 0;
> > +
> > + /*
> > + * A timeout means the consumer might be stuck. In theory, if it
> > + * moves 2 * qsize entries or more within a single poll interval
> > + * Q_POS() would wrap and undercount drained: that could trigger
> > + * a spurious warning too, if the queue was never once observed
> > + * empty. Yet, that much consumption in such a short interval is
> > + * unrealistic. WARN it only, as a stuck consumer is a real bug.
>
> I don't like 'unrealisitic' based defenses (even though I agree it is pretty
> unlikely). Is there a way to bound this? Maybe future systems will
> be much quicker.
I can't see one..
I think this is already an extreme corner case. Sashiko found it,
FWIW.
If you have a better word than "unrealistic", I can change that.
> > + */
> > + if (WARN_ON(ktime_compare(ktime_get(), timeout) > 0))
>
> Why WARN_ON here then a dev_warn_ratelimited() below?
I dropped WARN_ON.
+ if (ktime_compare(ktime_get(), timeout) > 0)
+ break;
> > + /* The consumer might be a threaded IRQ handler. Yield to it */
> > + usleep_range(100, 200);
>
> fsleep() perhaps then we don't get to argue why that slack.
Done.
+ /* The consumer might be a threaded IRQ handler. Yield to it */
+ fsleep(100);
Thanks
Nicolin
next prev parent reply other threads:[~2026-09-04 21:43 UTC|newest]
Thread overview: 59+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-01 0:33 [PATCH v3 00/13] iommu/arm-smmu-v3: Add PRI support Nicolin Chen
2026-09-01 0:33 ` [PATCH v3 01/13] iommu/arm-smmu-v3: Add arm_smmu_attach_release() Nicolin Chen
2026-09-01 0:46 ` sashiko-bot
2026-09-03 19:18 ` Jonathan Cameron
2026-09-04 20:16 ` Nicolin Chen
2026-09-01 0:33 ` [PATCH v3 02/13] iommu/arm-smmu-v3: Add Q_POS() macro Nicolin Chen
2026-09-01 0:38 ` sashiko-bot
2026-09-01 0:33 ` [PATCH v3 03/13] iommu/arm-smmu-v3: Drain in-flight fault events on domain detach Nicolin Chen
2026-09-01 0:48 ` sashiko-bot
2026-09-03 19:18 ` Jonathan Cameron
2026-09-04 14:09 ` Jason Gunthorpe
2026-09-04 22:57 ` Nicolin Chen
2026-09-08 16:36 ` Jason Gunthorpe
2026-09-08 21:01 ` Nicolin Chen
2026-09-04 21:42 ` Nicolin Chen [this message]
2026-09-01 0:33 ` [PATCH v3 04/13] iommu/arm-smmu-v3: Flush in-flight fault work " Nicolin Chen
2026-09-01 0:55 ` sashiko-bot
2026-09-03 19:18 ` Jonathan Cameron
2026-09-05 0:54 ` Nicolin Chen
2026-09-01 0:33 ` [PATCH v3 05/13] iommu/arm-smmu-v3: Allocate IOPF queue without FEAT_SVA Nicolin Chen
2026-09-01 0:46 ` sashiko-bot
2026-09-03 19:18 ` Jonathan Cameron
2026-09-01 0:33 ` [PATCH v3 06/13] iommu/arm-smmu-v3: Submit CMDQ_OP_PRI_RESP for IOPF event Nicolin Chen
2026-09-01 0:53 ` sashiko-bot
2026-09-03 19:18 ` Jonathan Cameron
2026-09-05 1:15 ` Nicolin Chen
2026-09-09 17:54 ` Jonathan Cameron
2026-09-01 0:33 ` [PATCH v3 07/13] iommu/arm-smmu-v3: Disable the queue IRQs before disabling the SMMU Nicolin Chen
2026-09-01 0:55 ` sashiko-bot
2026-09-03 19:18 ` Jonathan Cameron
2026-09-05 3:24 ` Nicolin Chen
2026-09-09 17:58 ` Jonathan Cameron
2026-09-01 0:33 ` [PATCH v3 08/13] iommu/arm-smmu-v3: Disable PRI when no IRQ handler is registered Nicolin Chen
2026-09-01 0:47 ` sashiko-bot
2026-09-03 19:18 ` Jonathan Cameron
2026-09-04 14:15 ` Jason Gunthorpe
2026-09-09 17:59 ` Jonathan Cameron
2026-09-09 19:05 ` Nicolin Chen
2026-09-01 0:33 ` [PATCH v3 09/13] iommu/arm-smmu-v3: Support PRI Page Request in arm_smmu_handle_ppr() Nicolin Chen
2026-09-01 0:50 ` sashiko-bot
2026-09-03 19:18 ` Jonathan Cameron
2026-09-05 5:08 ` Nicolin Chen
2026-09-09 18:01 ` Jonathan Cameron
2026-09-09 19:09 ` Nicolin Chen
2026-09-01 0:33 ` [PATCH v3 10/13] iommu/arm-smmu-v3: Allocate IOPF queue for ARM_SMMU_FEAT_PRI Nicolin Chen
2026-09-01 0:43 ` sashiko-bot
2026-09-03 19:18 ` Jonathan Cameron
2026-09-01 0:33 ` [PATCH v3 11/13] PCI/ATS: Add PRI stubs Nicolin Chen
2026-09-01 0:42 ` sashiko-bot
2026-09-03 19:18 ` Jonathan Cameron
2026-09-01 0:33 ` [PATCH v3 12/13] PCI/ATS: Export pci_enable_pri() and pci_reset_pri() Nicolin Chen
2026-09-01 0:44 ` sashiko-bot
2026-09-03 19:18 ` Jonathan Cameron
2026-09-01 0:33 ` [PATCH v3 13/13] iommu/arm-smmu-v3: Enable PRI for PCI device in arm_smmu_probe_device() Nicolin Chen
2026-09-01 0:51 ` sashiko-bot
2026-09-03 19:18 ` Jonathan Cameron
2026-09-05 5:53 ` Nicolin Chen
2026-09-03 19:18 ` [PATCH v3 00/13] iommu/arm-smmu-v3: Add PRI support Jonathan Cameron
2026-09-04 14:10 ` Jason Gunthorpe
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=aps7UJktq3IlO5lT@nvidia.com \
--to=nicolinc@nvidia.com \
--cc=baolu.lu@linux.intel.com \
--cc=bbiber@nvidia.com \
--cc=bhelgaas@google.com \
--cc=harsha.v@oss.qualcomm.com \
--cc=iommu@lists.linux.dev \
--cc=jgg@nvidia.com \
--cc=jonathan.cameron@oss.qualcomm.com \
--cc=joro@8bytes.org \
--cc=kees@kernel.org \
--cc=kevin.tian@intel.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=mmarrid@nvidia.com \
--cc=praan@google.com \
--cc=robin.murphy@arm.com \
--cc=skaestle@nvidia.com \
--cc=skolothumtho@nvidia.com \
--cc=smostafa@google.com \
--cc=will@kernel.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 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.