* [PATCH] soc: tegra: cbb: walk cbb_list under cbb_lock in the debugfs path
@ 2026-09-22 1:08 Jaidev Shastri via B4 Relay
2026-09-22 10:37 ` Thierry Reding
0 siblings, 1 reply; 2+ messages in thread
From: Jaidev Shastri via B4 Relay @ 2026-09-22 1:08 UTC (permalink / raw)
To: Thierry Reding, Jonathan Hunter; +Cc: linux-tegra, linux-kernel, Jaidev Shastri
From: Jaidev Shastri <jaidevshastri@vt.edu>
tegra194_cbb_probe() and tegra194_cbb_remove() add and remove cbb_list
entries under cbb_lock, and the error interrupt handler walks the list
under the same lock. tegra194_cbb_debugfs_show() walks it holding only
cbb_err_mutex, which the writers never take.
A debugfs read of one CBB instance can therefore run while another
instance is probed or removed. list_add() publishes the node with a
plain store, so the walker can see a node before its links and private
data are visible, or step onto a node that remove is freeing.
Take cbb_lock around the walk. cbb_err_mutex keeps its existing job of
serialising the error log output.
Found with MBCheck, a static herd7-based memory consistency checker.
Signed-off-by: Jaidev Shastri <jaidevshastri@vt.edu>
---
drivers/soc/tegra/cbb/tegra194-cbb.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/soc/tegra/cbb/tegra194-cbb.c b/drivers/soc/tegra/cbb/tegra194-cbb.c
index 69ef929e0..d1a80b0b5 100644
--- a/drivers/soc/tegra/cbb/tegra194-cbb.c
+++ b/drivers/soc/tegra/cbb/tegra194-cbb.c
@@ -1990,9 +1990,16 @@ static DEFINE_MUTEX(cbb_err_mutex);
static int tegra194_cbb_debugfs_show(struct tegra_cbb *cbb, struct seq_file *file, void *data)
{
struct tegra_cbb *noc;
+ unsigned long flags;
mutex_lock(&cbb_err_mutex);
+ /*
+ * cbb_list is modified under cbb_lock by the probe and remove paths of
+ * the other CBB instances; cbb_err_mutex alone does not exclude them.
+ */
+ spin_lock_irqsave(&cbb_lock, flags);
+
list_for_each_entry(noc, &cbb_list, node) {
struct tegra194_cbb *priv = to_tegra194_cbb(noc);
u32 status;
@@ -2002,6 +2009,8 @@ static int tegra194_cbb_debugfs_show(struct tegra_cbb *cbb, struct seq_file *fil
print_errlog(file, priv, status);
}
+ spin_unlock_irqrestore(&cbb_lock, flags);
+
mutex_unlock(&cbb_err_mutex);
return 0;
---
base-commit: 93f51579e7df248780214094418f205253383cc5
change-id: 20260921-mb-tegra-cbb-dd2dde85c68f
Best regards,
--
Jaidev Shastri <jaidevshastri@vt.edu>
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] soc: tegra: cbb: walk cbb_list under cbb_lock in the debugfs path
2026-09-22 1:08 [PATCH] soc: tegra: cbb: walk cbb_list under cbb_lock in the debugfs path Jaidev Shastri via B4 Relay
@ 2026-09-22 10:37 ` Thierry Reding
0 siblings, 0 replies; 2+ messages in thread
From: Thierry Reding @ 2026-09-22 10:37 UTC (permalink / raw)
To: jaidevshastri; +Cc: Jonathan Hunter, linux-tegra, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2729 bytes --]
On Mon, Sep 21, 2026 at 09:08:41PM -0400, Jaidev Shastri via B4 Relay wrote:
> From: Jaidev Shastri <jaidevshastri@vt.edu>
>
> tegra194_cbb_probe() and tegra194_cbb_remove() add and remove cbb_list
> entries under cbb_lock, and the error interrupt handler walks the list
> under the same lock. tegra194_cbb_debugfs_show() walks it holding only
> cbb_err_mutex, which the writers never take.
>
> A debugfs read of one CBB instance can therefore run while another
> instance is probed or removed. list_add() publishes the node with a
> plain store, so the walker can see a node before its links and private
> data are visible, or step onto a node that remove is freeing.
>
> Take cbb_lock around the walk. cbb_err_mutex keeps its existing job of
> serialising the error log output.
>
> Found with MBCheck, a static herd7-based memory consistency checker.
>
> Signed-off-by: Jaidev Shastri <jaidevshastri@vt.edu>
> ---
> drivers/soc/tegra/cbb/tegra194-cbb.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/drivers/soc/tegra/cbb/tegra194-cbb.c b/drivers/soc/tegra/cbb/tegra194-cbb.c
> index 69ef929e0..d1a80b0b5 100644
> --- a/drivers/soc/tegra/cbb/tegra194-cbb.c
> +++ b/drivers/soc/tegra/cbb/tegra194-cbb.c
> @@ -1990,9 +1990,16 @@ static DEFINE_MUTEX(cbb_err_mutex);
> static int tegra194_cbb_debugfs_show(struct tegra_cbb *cbb, struct seq_file *file, void *data)
> {
> struct tegra_cbb *noc;
> + unsigned long flags;
>
> mutex_lock(&cbb_err_mutex);
>
> + /*
> + * cbb_list is modified under cbb_lock by the probe and remove paths of
> + * the other CBB instances; cbb_err_mutex alone does not exclude them.
> + */
> + spin_lock_irqsave(&cbb_lock, flags);
> +
> list_for_each_entry(noc, &cbb_list, node) {
> struct tegra194_cbb *priv = to_tegra194_cbb(noc);
> u32 status;
> @@ -2002,6 +2009,8 @@ static int tegra194_cbb_debugfs_show(struct tegra_cbb *cbb, struct seq_file *fil
> print_errlog(file, priv, status);
> }
>
> + spin_unlock_irqrestore(&cbb_lock, flags);
> +
> mutex_unlock(&cbb_err_mutex);
cbb_err_mutex no longer serves any purpose (though, honestly, it never
really did), so it can be removed entirely.
There's a slight issue with this patch, though it also previously
existed already (partially). print_errlog() ends up calling the
tegra_cbb_print_err(), which in turn is quite slow when it goes out to
the debug serial. On the other hand, we can't use a mutex for the dumps
during the interrupt handling.
Probably best to get rid of the mutex for now since it's obviously not
needed and maybe revisit this at some point to get rid of the spin lock
around the slow UART operations.
Thierry
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-22 10:37 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-22 1:08 [PATCH] soc: tegra: cbb: walk cbb_list under cbb_lock in the debugfs path Jaidev Shastri via B4 Relay
2026-09-22 10:37 ` Thierry Reding
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox