From: Jaidev Shastri via B4 Relay <devnull+jaidevshastri.vt.edu@kernel.org>
To: Ioana Ciornei <ioana.ciornei@nxp.com>,
"Christophe Leroy (CS GROUP)" <chleroy@kernel.org>
Cc: linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
linux-arm-kernel@lists.infradead.org,
Jaidev Shastri <jaidevshastri@vt.edu>
Subject: [PATCH] soc: fsl: dpio: publish the dpaa2_io object only after it is initialised
Date: Mon, 21 Sep 2026 20:50:07 -0400 [thread overview]
Message-ID: <20260921-mb-dpio-v1-1-9e24539059c1@vt.edu> (raw)
From: Jaidev Shastri <jaidevshastri@vt.edu>
dpaa2_io_create() adds the new object to dpio_list and dpio_by_cpu[]
under dpio_list_lock, but service_select_by_cpu() reads dpio_by_cpu[]
without the lock on behalf of dpaa2_io_service_select() and
dpaa2_io_service_register().
obj->dev is assigned after the lock is dropped, so a reader can pick the
object up and pass a NULL supplier to device_link_add(), which fails
with -EINVAL and fails the consumer's probe. The publication is a plain
store, so a reader that does not take the lock is also not ordered
against the stores that set obj->swp, the notification list and the
object's spinlocks.
dpaa2-eth probes from the deferred probe worker and retries whenever
another device binds, so it runs while the remaining DPIO objects are
still being created on multi-core LS2 and LX2 parts.
Finish the object before publishing it and store dpio_by_cpu[] with
smp_store_release(), paired with smp_load_acquire() in
service_select_by_cpu(). service_select() takes the lock and is
unchanged.
Found with MBCheck, a static herd7-based memory consistency checker.
Signed-off-by: Jaidev Shastri <jaidevshastri@vt.edu>
---
drivers/soc/fsl/dpio/dpio-service.c | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/drivers/soc/fsl/dpio/dpio-service.c b/drivers/soc/fsl/dpio/dpio-service.c
index 317ca50b0..2dbd14aed 100644
--- a/drivers/soc/fsl/dpio/dpio-service.c
+++ b/drivers/soc/fsl/dpio/dpio-service.c
@@ -70,8 +70,12 @@ static inline struct dpaa2_io *service_select_by_cpu(struct dpaa2_io *d,
if (cpu < 0)
cpu = raw_smp_processor_id();
- /* If a specific cpu was requested, pick it up immediately */
- return dpio_by_cpu[cpu];
+ /*
+ * If a specific cpu was requested, pick it up immediately. Pairs with
+ * the smp_store_release() in dpaa2_io_create(): the object is only
+ * used once every field written before the publication is visible.
+ */
+ return smp_load_acquire(&dpio_by_cpu[cpu]);
}
static inline struct dpaa2_io *service_select(struct dpaa2_io *d)
@@ -177,12 +181,6 @@ struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc,
if (obj->dpio_desc.receives_notifications)
qbman_swp_push_set(obj->swp, 0, 1);
- spin_lock(&dpio_list_lock);
- list_add_tail(&obj->node, &dpio_list);
- if (desc->cpu >= 0 && !dpio_by_cpu[desc->cpu])
- dpio_by_cpu[desc->cpu] = obj;
- spin_unlock(&dpio_list_lock);
-
obj->dev = dev;
memset(&obj->rx_dim, 0, sizeof(obj->rx_dim));
@@ -191,6 +189,19 @@ struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc,
obj->bytes = 0;
obj->frames = 0;
+ /*
+ * dpaa2_io_service_select() reads dpio_by_cpu[] without taking
+ * dpio_list_lock, so the object must be complete before it is
+ * published and the publication needs release semantics.
+ */
+ spin_lock(&dpio_list_lock);
+ list_add_tail(&obj->node, &dpio_list);
+ if (desc->cpu >= 0 && !dpio_by_cpu[desc->cpu]) {
+ /* Pairs with the smp_load_acquire() in service_select_by_cpu(). */
+ smp_store_release(&dpio_by_cpu[desc->cpu], obj);
+ }
+ spin_unlock(&dpio_list_lock);
+
return obj;
}
---
base-commit: 93f51579e7df248780214094418f205253383cc5
change-id: 20260921-mb-dpio-f3f7dcf0ef41
Best regards,
--
Jaidev Shastri <jaidevshastri@vt.edu>
next reply other threads:[~2026-09-22 0:50 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-22 0:50 Jaidev Shastri via B4 Relay [this message]
2026-10-01 0:08 ` [PATCH] soc: fsl: dpio: publish the dpaa2_io object only after it is initialised Anthony Pighin
2026-10-02 9:50 ` Ioana Ciornei
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=20260921-mb-dpio-v1-1-9e24539059c1@vt.edu \
--to=devnull+jaidevshastri.vt.edu@kernel.org \
--cc=chleroy@kernel.org \
--cc=ioana.ciornei@nxp.com \
--cc=jaidevshastri@vt.edu \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox