Currently the 'pispbe_schedule()' function does two things:
1) Tries to assemble a job by inspecting all the video node queues to make sure all the required buffers are available 2) Submit the job to the hardware
The pispbe_schedule() function is called at:
- video device start_streaming() time - video device qbuf() time - irq handler
As assembling a job requires inspecting all queues, it is a rather time consuming operation which is better not run in IRQ context.
To avoid executing the time consuming job creation in interrupt context, split the job creation and job scheduling in two distinct operations. When a well-formed job is created, append it to the newly introduced 'pispbe->job_queue' where it will be dequeued from by the scheduling routine.
At start_streaming() and qbuf() time immediately try to schedule a job if one has been created as the irq handler routine is only called when a job has completed, and we can't solely rely on it for scheduling new jobs.
Signed-off-by: Jacopo Mondi jacopo.mondi@ideasonboard.com --- Changes in v8: - Use automatic release of *job in pispbe_prepare_job() - Use temporary list to release jobs without holding the main driver lock - Collect tags - Rebased on rpi-6.6.y: https://github.com/raspberrypi/linux/pull/6905 - Link to v7: https://lore.kernel.org/r/20250606-pispbe-mainline-split-jobs-handling-v6-v7...
Changes in v7: - Rebased on media-committers/next - Fix lockdep warning by using the proper spinlock_irq() primitive in pispbe_prepare_job() which can race with the IRQ handler - Link to v6: https://lore.kernel.org/r/20240930-pispbe-mainline-split-jobs-handling-v6-v6...
v5->v6: - Make the driver depend on PM - Simplify the probe() routine by using pm_runtime_ - Remove suspend call from remove()
v4->v5: - Use appropriate locking constructs: - spin_lock_irq() for pispbe_prepare_job() called from non irq context - spin_lock_irqsave() for pispbe_schedule() called from irq context - Remove hw_lock from ready_queue accesses in stop_streaming and start_streaming - Fix trivial indentation mistake in 4/4
v3->v4: - Expand commit message in 2/4 to explain why removing validation in schedule() is safe - Drop ready_lock spinlock - Use non _irqsave version of safe_guard(spinlock - Support !CONFIG_PM in 4/4 by calling the enable/disable routines directly and adjust pm_runtime usage as suggested by Laurent
v2->v3: - Mark pispbe_runtime_resume() as __maybe_unused - Add fixes tags where appropriate
v1->v2: - Add two patches to address Laurent's comments separately - use scoped_guard() when possible - Add patch to fix runtime_pm imbalance
--- Jacopo Mondi (4): media: pisp_be: Drop reference to non-existing function media: pisp_be: Remove config validation from schedule() media: pisp_be: Split jobs creation and scheduling media: pisp_be: Fix pm_runtime underrun in probe
drivers/media/platform/raspberrypi/pisp_be/Kconfig | 1 + .../media/platform/raspberrypi/pisp_be/pisp_be.c | 196 ++++++++++----------- 2 files changed, 98 insertions(+), 99 deletions(-) --- base-commit: ce5cac69b2edac3e3246fee03e8f4c2a1075238b change-id: 20240930-pispbe-mainline-split-jobs-handling-v6-15dc16e11e3a
Best regards,
During the probe() routine, the PiSP BE driver needs to power up the interface in order to identify and initialize the hardware.
The driver resumes the interface by calling the pispbe_runtime_resume() function directly, without going through the pm_runtime helpers, but later suspends it by calling pm_runtime_put_autosuspend().
This causes a PM usage count imbalance at probe time, notified by the runtime_pm framework with the below message in the system log:
pispbe 1000880000.pisp_be: Runtime PM usage count underflow!
Fix this by resuming the interface using the pm runtime helpers instead of calling the resume function directly and use the pm_runtime framework in the probe() error path. While at it, remove manual suspend of the interface in the remove() function. The driver cannot be unloaded if in use, so simply disable runtime pm.
To simplify the implementation, make the driver depend on PM as the RPI5 platform where the ISP is integrated in uses the PM framework by default.
Fixes: 12187bd5d4f8 ("media: raspberrypi: Add support for PiSP BE") Cc: stable@vger.kernel.org Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Jacopo Mondi jacopo.mondi@ideasonboard.com --- drivers/media/platform/raspberrypi/pisp_be/Kconfig | 1 + drivers/media/platform/raspberrypi/pisp_be/pisp_be.c | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/media/platform/raspberrypi/pisp_be/Kconfig b/drivers/media/platform/raspberrypi/pisp_be/Kconfig index 46765a2e4c4d1573757ff842f208834216e582cb..a9e51fd94aadc6add70f883bfcea0c9fa91f0c4b 100644 --- a/drivers/media/platform/raspberrypi/pisp_be/Kconfig +++ b/drivers/media/platform/raspberrypi/pisp_be/Kconfig @@ -3,6 +3,7 @@ config VIDEO_RASPBERRYPI_PISP_BE depends on V4L_PLATFORM_DRIVERS depends on VIDEO_DEV depends on ARCH_BCM2835 || COMPILE_TEST + depends on PM select VIDEO_V4L2_SUBDEV_API select MEDIA_CONTROLLER select VIDEOBUF2_DMA_CONTIG diff --git a/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c b/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c index ccc6cb99868b842ac0d295f9ec28470303e60788..be794a12362020f42b3cf5bd291b4a1625543b5f 100644 --- a/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c +++ b/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c @@ -1725,7 +1725,7 @@ static int pispbe_probe(struct platform_device *pdev) pm_runtime_use_autosuspend(pispbe->dev); pm_runtime_enable(pispbe->dev);
- ret = pispbe_runtime_resume(pispbe->dev); + ret = pm_runtime_resume_and_get(pispbe->dev); if (ret) goto pm_runtime_disable_err;
@@ -1747,7 +1747,7 @@ static int pispbe_probe(struct platform_device *pdev) disable_devs_err: pispbe_destroy_devices(pispbe); pm_runtime_suspend_err: - pispbe_runtime_suspend(pispbe->dev); + pm_runtime_put(pispbe->dev); pm_runtime_disable_err: pm_runtime_dont_use_autosuspend(pispbe->dev); pm_runtime_disable(pispbe->dev); @@ -1761,7 +1761,6 @@ static void pispbe_remove(struct platform_device *pdev)
pispbe_destroy_devices(pispbe);
- pispbe_runtime_suspend(pispbe->dev); pm_runtime_dont_use_autosuspend(pispbe->dev); pm_runtime_disable(pispbe->dev); }
Hi Jacopo,
Thank you for this fix.
On Tue, 17 Jun 2025 at 14:54, Jacopo Mondi jacopo.mondi@ideasonboard.com wrote:
During the probe() routine, the PiSP BE driver needs to power up the interface in order to identify and initialize the hardware.
The driver resumes the interface by calling the pispbe_runtime_resume() function directly, without going through the pm_runtime helpers, but later suspends it by calling pm_runtime_put_autosuspend().
This causes a PM usage count imbalance at probe time, notified by the runtime_pm framework with the below message in the system log:
pispbe 1000880000.pisp_be: Runtime PM usage count underflow!
Fix this by resuming the interface using the pm runtime helpers instead of calling the resume function directly and use the pm_runtime framework in the probe() error path. While at it, remove manual suspend of the interface in the remove() function. The driver cannot be unloaded if in use, so simply disable runtime pm.
To simplify the implementation, make the driver depend on PM as the RPI5 platform where the ISP is integrated in uses the PM framework by default.
Fixes: 12187bd5d4f8 ("media: raspberrypi: Add support for PiSP BE") Cc: stable@vger.kernel.org Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Jacopo Mondi jacopo.mondi@ideasonboard.com
Tested-by: Naushir Patuck naush@raspberrypi.com Reviewed-by: Naushir Patuck naush@raspberrypi.com
drivers/media/platform/raspberrypi/pisp_be/Kconfig | 1 + drivers/media/platform/raspberrypi/pisp_be/pisp_be.c | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/media/platform/raspberrypi/pisp_be/Kconfig b/drivers/media/platform/raspberrypi/pisp_be/Kconfig index 46765a2e4c4d1573757ff842f208834216e582cb..a9e51fd94aadc6add70f883bfcea0c9fa91f0c4b 100644 --- a/drivers/media/platform/raspberrypi/pisp_be/Kconfig +++ b/drivers/media/platform/raspberrypi/pisp_be/Kconfig @@ -3,6 +3,7 @@ config VIDEO_RASPBERRYPI_PISP_BE depends on V4L_PLATFORM_DRIVERS depends on VIDEO_DEV depends on ARCH_BCM2835 || COMPILE_TEST
depends on PM select VIDEO_V4L2_SUBDEV_API select MEDIA_CONTROLLER select VIDEOBUF2_DMA_CONTIG
diff --git a/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c b/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c index ccc6cb99868b842ac0d295f9ec28470303e60788..be794a12362020f42b3cf5bd291b4a1625543b5f 100644 --- a/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c +++ b/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c @@ -1725,7 +1725,7 @@ static int pispbe_probe(struct platform_device *pdev) pm_runtime_use_autosuspend(pispbe->dev); pm_runtime_enable(pispbe->dev);
ret = pispbe_runtime_resume(pispbe->dev);
ret = pm_runtime_resume_and_get(pispbe->dev); if (ret) goto pm_runtime_disable_err;
@@ -1747,7 +1747,7 @@ static int pispbe_probe(struct platform_device *pdev) disable_devs_err: pispbe_destroy_devices(pispbe); pm_runtime_suspend_err:
pispbe_runtime_suspend(pispbe->dev);
pm_runtime_put(pispbe->dev);
pm_runtime_disable_err: pm_runtime_dont_use_autosuspend(pispbe->dev); pm_runtime_disable(pispbe->dev); @@ -1761,7 +1761,6 @@ static void pispbe_remove(struct platform_device *pdev)
pispbe_destroy_devices(pispbe);
pispbe_runtime_suspend(pispbe->dev); pm_runtime_dont_use_autosuspend(pispbe->dev); pm_runtime_disable(pispbe->dev);
}
-- 2.49.0
linux-stable-mirror@lists.linaro.org