mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v3] firmware: tegra: bpmp: populate debugfs in the background
@ 2026-11-03  6:11 Austin Schuh
  0 siblings, 0 replies; only message in thread
From: Austin Schuh @ 2026-11-03  6:11 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter
  Cc: Austin Schuh, Mikko Perttunen, Aniruddha Rao, linux-tegra, linux-kernel

Populating the BPMP debugfs mirror takes several synchronous BPMP requests
per directory, which on Tegra234 adds up to seconds.  The BPMP probe waits
for it, and nearly every other device on the SoC waits for the BPMP.

Nothing in the kernel uses the mirror, so populate it from the freezable
workqueue instead, which system suspend waits for.  Create the mirror as
.debug-populating and rename it to debug once it is complete, so that
userspace never sees an incomplete state.  Count the users of the shared
root, so that one BPMP failing doesn't remove it while another is still
populating.

On an Orin Nano with v7.3-rc1, the BPMP probe now takes 0.5 seconds
instead of 2.6.

Assisted-by: LLM
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
---

Notes:
    Changes in v3:
     - Shorten the commit message and comments.
     - Populate several BPMPs in parallel, and count the users of the shared
       root instead of holding its lock across the whole population.
    
    Changes in v2:
     - Embed the work_struct in struct tegra_bpmp, and cancel it with
       cancel_work_sync() from a devm action.
     - Create the mirror as .debug-populating and rename it to debug once it
       is complete.
     - Queue the work on system_freezable_wq, so that system suspend waits
       for it.
     - Hold bpmp_debugfs_root_lock across the whole population.
    
    v2: https://lore.kernel.org/r/20261024055055.602558-1-austin.linux@gmail.com
    v1: https://lore.kernel.org/r/20261017065012.3063980-1-austin.linux@gmail.com

 drivers/firmware/tegra/bpmp-debugfs.c | 62 ++++++++++++++++++++++++---
 include/soc/tegra/bpmp.h              |  2 +
 2 files changed, 58 insertions(+), 6 deletions(-)

diff --git a/drivers/firmware/tegra/bpmp-debugfs.c b/drivers/firmware/tegra/bpmp-debugfs.c
index 2efc48b522ac..d90ef912b66c 100644
--- a/drivers/firmware/tegra/bpmp-debugfs.c
+++ b/drivers/firmware/tegra/bpmp-debugfs.c
@@ -774,6 +774,7 @@ static int bpmp_populate_debugfs_shmem(struct tegra_bpmp *bpmp)
 
 static DEFINE_MUTEX(bpmp_debugfs_root_lock);
 static struct dentry *bpmp_debugfs_root;
+static unsigned int bpmp_debugfs_root_users;
 static bool bpmp_debugfs_enabled = true;
 
 module_param_named(debugfs, bpmp_debugfs_enabled, bool, 0444);
@@ -785,19 +786,18 @@ static struct dentry *bpmp_debugfs_get_root(void)
 	guard(mutex)(&bpmp_debugfs_root_lock);
 	if (!bpmp_debugfs_root)
 		bpmp_debugfs_root = debugfs_create_dir("bpmp", NULL);
+	if (!IS_ERR(bpmp_debugfs_root))
+		bpmp_debugfs_root_users++;
 	return bpmp_debugfs_root;
 }
 
-int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
+static int tegra_bpmp_populate_debugfs(struct tegra_bpmp *bpmp)
 {
 	struct dentry *root, *d;
 	char name[32];
 	bool inband;
 	int err;
 
-	if (!bpmp_debugfs_enabled)
-		return 0;
-
 	inband = tegra_bpmp_mrq_is_supported(bpmp, MRQ_DEBUG);
 
 	if (!inband && !tegra_bpmp_mrq_is_supported(bpmp, MRQ_DEBUGFS))
@@ -818,7 +818,11 @@ int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
 		}
 	}
 
-	bpmp->debugfs_mirror = debugfs_create_dir("debug", d);
+	/*
+	 * Name the mirror "debug" only once it is complete, so that userspace
+	 * never sees an incomplete state.
+	 */
+	bpmp->debugfs_mirror = debugfs_create_dir(".debug-populating", d);
 	if (IS_ERR(bpmp->debugfs_mirror)) {
 		err = PTR_ERR(bpmp->debugfs_mirror);
 		goto out;
@@ -830,15 +834,19 @@ int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
 	else
 		err = bpmp_populate_debugfs_shmem(bpmp);
 
+	if (!err)
+		err = debugfs_change_name(bpmp->debugfs_mirror, "debug");
+
 out:
 	if (err < 0) {
 		if (!IS_ERR(d))
 			debugfs_remove_recursive(d);
 
 		guard(mutex)(&bpmp_debugfs_root_lock);
+		bpmp_debugfs_root_users--;
 		if (root == d) {
 			bpmp_debugfs_root = NULL;
-		} else if (simple_empty(root)) {
+		} else if (!bpmp_debugfs_root_users) {
 			debugfs_remove(root);
 			bpmp_debugfs_root = NULL;
 		}
@@ -846,3 +854,45 @@ int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
 
 	return err;
 }
+
+static void tegra_bpmp_debugfs_work(struct work_struct *work)
+{
+	struct tegra_bpmp *bpmp =
+		container_of(work, struct tegra_bpmp, debugfs_work);
+	int err;
+
+	err = tegra_bpmp_populate_debugfs(bpmp);
+	if (err < 0)
+		dev_err(bpmp->dev, "debugfs initialization failed: %d\n", err);
+}
+
+static void tegra_bpmp_cancel_debugfs(void *data)
+{
+	struct tegra_bpmp *bpmp = data;
+
+	cancel_work_sync(&bpmp->debugfs_work);
+}
+
+int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
+{
+	int err;
+
+	if (!bpmp_debugfs_enabled)
+		return 0;
+
+	INIT_WORK(&bpmp->debugfs_work, tegra_bpmp_debugfs_work);
+
+	err = devm_add_action_or_reset(bpmp->dev, tegra_bpmp_cancel_debugfs,
+				       bpmp);
+	if (err < 0)
+		return err;
+
+	/*
+	 * Mirroring the BPMP's debugfs tree can take several seconds, so do
+	 * it asynchronously, on the freezable workqueue so that system
+	 * suspend doesn't make its requests fail.
+	 */
+	queue_work(system_freezable_wq, &bpmp->debugfs_work);
+
+	return 0;
+}
diff --git a/include/soc/tegra/bpmp.h b/include/soc/tegra/bpmp.h
index f55db918ccb1..f961c265326c 100644
--- a/include/soc/tegra/bpmp.h
+++ b/include/soc/tegra/bpmp.h
@@ -12,6 +12,7 @@
 #include <linux/reset-controller.h>
 #include <linux/semaphore.h>
 #include <linux/types.h>
+#include <linux/workqueue.h>
 
 #include <soc/tegra/bpmp-abi.h>
 
@@ -103,6 +104,7 @@ struct tegra_bpmp {
 
 #ifdef CONFIG_DEBUG_FS
 	struct dentry *debugfs_mirror;
+	struct work_struct debugfs_work;
 #endif
 
 	bool suspended;

base-commit: 1bbcf4a19f1495f769b69e9569d8c1e81df074f5
-- 
2.47.3


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-11-03  6:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-03  6:11 [PATCH v3] firmware: tegra: bpmp: populate debugfs in the background Austin Schuh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®