mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] firmware: tegra: bpmp: populate debugfs in the background
@ 2026-10-17  6:50 Austin Schuh
  2026-10-23  8:16 ` Mikko Perttunen
  0 siblings, 1 reply; 2+ messages in thread
From: Austin Schuh @ 2026-10-17  6:50 UTC (permalink / raw)
  To: thierry.reding, jonathanh; +Cc: anrao, linux-tegra, linux-kernel, Austin Schuh

Populating the BPMP debugfs mirror takes a series of synchronous BPMP
requests, several per directory.  On an Orin Nano (Tegra234) the tree has
about 10,800 entries, and the BPMP probe doesn't return for over five
seconds.  Every device that gets its clocks, resets or power domains from
the BPMP waits for it, which on Tegra234 is nearly all of them, so PCIe,
NVMe and the root filesystem all come up five seconds late.

Commit c7fc690da6f1 ("firmware: tegra: bpmp: Allow BPMP debugfs population
to be skipped") lets a system that doesn't need the mirror turn it off with
tegra_bpmp.debugfs=0.  A system that does use it, for instance to set
clocks from userspace at boot, still pays the full cost.

Nothing in the kernel uses the mirror, and the probe already only logs an
error from it, so populate it from a workqueue instead.  It isn't an
async_schedule() job, since kernel_init() waits for all of those before it
starts init.  Userspace that reads the mirror right after boot may find it
still being filled in.

Measured with initcall_debug on an Orin Nano running 6.18.39 with
NVIDIA's patches: the BPMP probe returns after 1.2 seconds instead of
6.36 seconds.

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

Notes:
    Based on tegra/for-7.4/firmware (1bbcf4a19f14).  Built for arm64, W=1,
    no new warnings.  The timing is from the same change on 6.18.39 with
    NVIDIA's patches (where the probe also has the VDK check), which is what
    our board runs; I haven't booted this branch on it.

 drivers/firmware/tegra/bpmp.c | 35 ++++++++++++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
index d3508e98e338..535ebbd55a6f 100644
--- a/drivers/firmware/tegra/bpmp.c
+++ b/drivers/firmware/tegra/bpmp.c
@@ -16,6 +16,7 @@
 #include <linux/semaphore.h>
 #include <linux/sched/clock.h>
 #include <linux/slab.h>
+#include <linux/workqueue.h>
 
 #include <soc/tegra/bpmp.h>
 #include <soc/tegra/bpmp-abi.h>
@@ -1052,8 +1053,26 @@ int tegra_bpmp_init_dt_providers(struct tegra_bpmp *bpmp)
 	return 0;
 }
 
+struct tegra_bpmp_debugfs_work {
+	struct work_struct work;
+	struct tegra_bpmp *bpmp;
+};
+
+static void tegra_bpmp_debugfs_work_fn(struct work_struct *work)
+{
+	struct tegra_bpmp_debugfs_work *dw =
+		container_of(work, struct tegra_bpmp_debugfs_work, work);
+	int err;
+
+	err = tegra_bpmp_init_debugfs(dw->bpmp);
+	if (err < 0)
+		dev_err(dw->bpmp->dev, "debugfs initialization failed: %d\n",
+			err);
+}
+
 static int tegra_bpmp_probe(struct platform_device *pdev)
 {
+	struct tegra_bpmp_debugfs_work *debugfs_work;
 	struct tegra_bpmp *bpmp;
 	char tag[TAG_SZ];
 	int err;
@@ -1089,9 +1108,19 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
 	if (err < 0)
 		dev_err(&pdev->dev, "failed to initialize sysfs: %d\n", err);
 
-	err = tegra_bpmp_init_debugfs(bpmp);
-	if (err < 0)
-		dev_err(&pdev->dev, "debugfs initialization failed: %d\n", err);
+	/*
+	 * Mirroring the BPMP's debugfs tree takes several requests per
+	 * directory, which on Tegra234 adds up to seconds.  Nothing else
+	 * waits for it, so do it in the background rather than hold up every
+	 * device that depends on the BPMP.
+	 */
+	debugfs_work = devm_kzalloc(&pdev->dev, sizeof(*debugfs_work),
+				    GFP_KERNEL);
+	if (debugfs_work) {
+		debugfs_work->bpmp = bpmp;
+		INIT_WORK(&debugfs_work->work, tegra_bpmp_debugfs_work_fn);
+		queue_work(system_dfl_long_wq, &debugfs_work->work);
+	}
 
 	return 0;
 

base-commit: 1bbcf4a19f1495f769b69e9569d8c1e81df074f5
-- 
2.47.3


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] firmware: tegra: bpmp: populate debugfs in the background
  2026-10-17  6:50 [PATCH] firmware: tegra: bpmp: populate debugfs in the background Austin Schuh
@ 2026-10-23  8:16 ` Mikko Perttunen
  0 siblings, 0 replies; 2+ messages in thread
From: Mikko Perttunen @ 2026-10-23  8:16 UTC (permalink / raw)
  To: thierry.reding, jonathanh, Austin Schuh
  Cc: anrao, linux-tegra, linux-kernel, Austin Schuh

On Saturday, October 17, 2026 3:50 PM Austin Schuh wrote:
> Populating the BPMP debugfs mirror takes a series of synchronous BPMP
> requests, several per directory.  On an Orin Nano (Tegra234) the tree has
> about 10,800 entries, and the BPMP probe doesn't return for over five
> seconds.  Every device that gets its clocks, resets or power domains from
> the BPMP waits for it, which on Tegra234 is nearly all of them, so PCIe,
> NVMe and the root filesystem all come up five seconds late.
> 
> Commit c7fc690da6f1 ("firmware: tegra: bpmp: Allow BPMP debugfs population
> to be skipped") lets a system that doesn't need the mirror turn it off with
> tegra_bpmp.debugfs=0.  A system that does use it, for instance to set
> clocks from userspace at boot, still pays the full cost.
> 
> Nothing in the kernel uses the mirror, and the probe already only logs an
> error from it, so populate it from a workqueue instead.  It isn't an
> async_schedule() job, since kernel_init() waits for all of those before it
> starts init.  Userspace that reads the mirror right after boot may find it
> still being filled in.
> 
> Measured with initcall_debug on an Orin Nano running 6.18.39 with
> NVIDIA's patches: the BPMP probe returns after 1.2 seconds instead of
> 6.36 seconds.
> 
> Assisted-by: LLM
> Signed-off-by: Austin Schuh <austin.linux@gmail.com>
> ---

Sashiko reports some hard to trigger but worth checking concurrency 
issues.

This does seem a good idea, but I am a bit concerned about the change to 
what userspace sees. Ideally we'd be able to have userspace stall if the 
debugfs population was still in progress. If that's not possible, at the 
very least userspace should have a way to voluntarily wait for the full 
debugfs to be available.

> 
> Notes:
>     Based on tegra/for-7.4/firmware (1bbcf4a19f14).  Built for arm64, W=1,
>     no new warnings.  The timing is from the same change on 6.18.39 with
>     NVIDIA's patches (where the probe also has the VDK check), which is what
>     our board runs; I haven't booted this branch on it.
> 
>  drivers/firmware/tegra/bpmp.c | 35 ++++++++++++++++++++++++++++++++---
>  1 file changed, 32 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
> index d3508e98e338..535ebbd55a6f 100644
> --- a/drivers/firmware/tegra/bpmp.c
> +++ b/drivers/firmware/tegra/bpmp.c
> @@ -16,6 +16,7 @@
>  #include <linux/semaphore.h>
>  #include <linux/sched/clock.h>
>  #include <linux/slab.h>
> +#include <linux/workqueue.h>
>  
>  #include <soc/tegra/bpmp.h>
>  #include <soc/tegra/bpmp-abi.h>
> @@ -1052,8 +1053,26 @@ int tegra_bpmp_init_dt_providers(struct tegra_bpmp *bpmp)
>  	return 0;
>  }
>  
> +struct tegra_bpmp_debugfs_work {
> +	struct work_struct work;
> +	struct tegra_bpmp *bpmp;
> +};

Just inline the work_struct inside tegra_bpmp. In any case the work 
should be synchronously cancelled if the bpmp driver instance is going 
to go away (not that that will happen, but good practice).

Thanks
Mikko

> +
> +static void tegra_bpmp_debugfs_work_fn(struct work_struct *work)
> +{
> +	struct tegra_bpmp_debugfs_work *dw =
> +		container_of(work, struct tegra_bpmp_debugfs_work, work);
> +	int err;
> +
> +	err = tegra_bpmp_init_debugfs(dw->bpmp);
> +	if (err < 0)
> +		dev_err(dw->bpmp->dev, "debugfs initialization failed: %d\n",
> +			err);
> +}
> +
>  static int tegra_bpmp_probe(struct platform_device *pdev)
>  {
> +	struct tegra_bpmp_debugfs_work *debugfs_work;
>  	struct tegra_bpmp *bpmp;
>  	char tag[TAG_SZ];
>  	int err;
> @@ -1089,9 +1108,19 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
>  	if (err < 0)
>  		dev_err(&pdev->dev, "failed to initialize sysfs: %d\n", err);
>  
> -	err = tegra_bpmp_init_debugfs(bpmp);
> -	if (err < 0)
> -		dev_err(&pdev->dev, "debugfs initialization failed: %d\n", err);
> +	/*
> +	 * Mirroring the BPMP's debugfs tree takes several requests per
> +	 * directory, which on Tegra234 adds up to seconds.  Nothing else
> +	 * waits for it, so do it in the background rather than hold up every
> +	 * device that depends on the BPMP.
> +	 */
> +	debugfs_work = devm_kzalloc(&pdev->dev, sizeof(*debugfs_work),
> +				    GFP_KERNEL);
> +	if (debugfs_work) {
> +		debugfs_work->bpmp = bpmp;
> +		INIT_WORK(&debugfs_work->work, tegra_bpmp_debugfs_work_fn);
> +		queue_work(system_dfl_long_wq, &debugfs_work->work);
> +	}
>  
>  	return 0;
>  
> 
> base-commit: 1bbcf4a19f1495f769b69e9569d8c1e81df074f5
> -- 
> 2.47.3
> 
> 





^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-10-23  8:16 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-17  6:50 [PATCH] firmware: tegra: bpmp: populate debugfs in the background Austin Schuh
2026-10-23  8:16 ` Mikko Perttunen

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®