From: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
The CRU driver uses a single spinlock to protect the buffers queue and
the hardware operations.
This single spinlock is held for the whole duration of the interrupt
handler, causing all other driver's operations to freeze.
Under heavy system stress conditions with userspace not providing
buffers fast enough, this causes loss of frames.
Prepare to re-work the driver locking by introducing (but not using yet)
a new spinlock to protect the hardware registers programming.
Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
---
drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h | 10 +++++++---
drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c | 1 +
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
index 3a200db15730..b46696a0012b 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
@@ -109,7 +109,6 @@ struct rzg2l_cru_info {
* @v4l2_dev: V4L2 device
* @num_buf: Holds the current number of buffers enabled
* @svc_channel: SVC0/1/2/3 to use for RZ/G3E
- * @buf_addr: Memory addresses where current video data is written.
* @notifier: V4L2 asynchronous subdevs notifier
*
* @ip: Image processing subdev info
@@ -118,6 +117,10 @@ struct rzg2l_cru_info {
* @mdev_lock: protects the count, notifier and csi members
* @pad: media pad for the video device entity
*
+ * @hw_lock: protects the slot counter, hardware programming of
+ * slot addresses and the @buf_addr[] list
+ * @buf_addr: Memory addresses where current video data is written
+ *
* @lock: protects @queue
* @queue: vb2 buffers queue
* @scratch: cpu address for scratch buffer
@@ -147,8 +150,6 @@ struct rzg2l_cru_dev {
u8 num_buf;
u8 svc_channel;
- dma_addr_t buf_addr[RZG2L_CRU_HW_BUFFER_DEFAULT];
-
struct v4l2_async_notifier notifier;
struct rzg2l_cru_ip ip;
@@ -157,6 +158,9 @@ struct rzg2l_cru_dev {
struct mutex mdev_lock;
struct media_pad pad;
+ spinlock_t hw_lock;
+ dma_addr_t buf_addr[RZG2L_CRU_HW_BUFFER_DEFAULT];
+
struct mutex lock;
struct vb2_queue queue;
void *scratch;
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
index 27079c17a54c..a79b17e146bf 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
@@ -844,6 +844,7 @@ int rzg2l_cru_dma_register(struct rzg2l_cru_dev *cru)
mutex_init(&cru->lock);
INIT_LIST_HEAD(&cru->buf_list);
+ spin_lock_init(&cru->hw_lock);
spin_lock_init(&cru->qlock);
cru->state = RZG2L_CRU_DMA_STOPPED;
--
2.53.0
Hi Jacopo,
Thank you for the patch.
On Fri, Mar 27, 2026 at 5:21 PM Jacopo Mondi
<jacopo.mondi@ideasonboard.com> wrote:
>
> From: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
>
> The CRU driver uses a single spinlock to protect the buffers queue and
> the hardware operations.
>
> This single spinlock is held for the whole duration of the interrupt
> handler, causing all other driver's operations to freeze.
>
> Under heavy system stress conditions with userspace not providing
> buffers fast enough, this causes loss of frames.
>
> Prepare to re-work the driver locking by introducing (but not using yet)
> a new spinlock to protect the hardware registers programming.
>
Is there a specific reason to split this into a separate patch? I
think it's better to squash the patches.
Cheers,
Prabhakar
> Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
> ---
> drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h | 10 +++++++---
> drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c | 1 +
> 2 files changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
> index 3a200db15730..b46696a0012b 100644
> --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
> +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
> @@ -109,7 +109,6 @@ struct rzg2l_cru_info {
> * @v4l2_dev: V4L2 device
> * @num_buf: Holds the current number of buffers enabled
> * @svc_channel: SVC0/1/2/3 to use for RZ/G3E
> - * @buf_addr: Memory addresses where current video data is written.
> * @notifier: V4L2 asynchronous subdevs notifier
> *
> * @ip: Image processing subdev info
> @@ -118,6 +117,10 @@ struct rzg2l_cru_info {
> * @mdev_lock: protects the count, notifier and csi members
> * @pad: media pad for the video device entity
> *
> + * @hw_lock: protects the slot counter, hardware programming of
> + * slot addresses and the @buf_addr[] list
> + * @buf_addr: Memory addresses where current video data is written
> + *
> * @lock: protects @queue
> * @queue: vb2 buffers queue
> * @scratch: cpu address for scratch buffer
> @@ -147,8 +150,6 @@ struct rzg2l_cru_dev {
> u8 num_buf;
>
> u8 svc_channel;
> - dma_addr_t buf_addr[RZG2L_CRU_HW_BUFFER_DEFAULT];
> -
> struct v4l2_async_notifier notifier;
>
> struct rzg2l_cru_ip ip;
> @@ -157,6 +158,9 @@ struct rzg2l_cru_dev {
> struct mutex mdev_lock;
> struct media_pad pad;
>
> + spinlock_t hw_lock;
> + dma_addr_t buf_addr[RZG2L_CRU_HW_BUFFER_DEFAULT];
> +
> struct mutex lock;
> struct vb2_queue queue;
> void *scratch;
> diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
> index 27079c17a54c..a79b17e146bf 100644
> --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
> +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
> @@ -844,6 +844,7 @@ int rzg2l_cru_dma_register(struct rzg2l_cru_dev *cru)
> mutex_init(&cru->lock);
> INIT_LIST_HEAD(&cru->buf_list);
>
> + spin_lock_init(&cru->hw_lock);
> spin_lock_init(&cru->qlock);
>
> cru->state = RZG2L_CRU_DMA_STOPPED;
>
> --
> 2.53.0
>
>
Hi Jacopo,
Thanks for your patch.
On Fri, Mar 27, 2026 at 06:10:13PM +0100, Jacopo Mondi wrote:
> From: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
>
> The CRU driver uses a single spinlock to protect the buffers queue and
> the hardware operations.
>
> This single spinlock is held for the whole duration of the interrupt
> handler, causing all other driver's operations to freeze.
>
> Under heavy system stress conditions with userspace not providing
> buffers fast enough, this causes loss of frames.
>
> Prepare to re-work the driver locking by introducing (but not using yet)
> a new spinlock to protect the hardware registers programming.
>
Reviewed-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
Kind Regards,
Tommaso
> Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
> ---
> drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h | 10 +++++++---
> drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c | 1 +
> 2 files changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
> index 3a200db15730..b46696a0012b 100644
> --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
> +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
> @@ -109,7 +109,6 @@ struct rzg2l_cru_info {
> * @v4l2_dev: V4L2 device
> * @num_buf: Holds the current number of buffers enabled
> * @svc_channel: SVC0/1/2/3 to use for RZ/G3E
> - * @buf_addr: Memory addresses where current video data is written.
> * @notifier: V4L2 asynchronous subdevs notifier
> *
> * @ip: Image processing subdev info
> @@ -118,6 +117,10 @@ struct rzg2l_cru_info {
> * @mdev_lock: protects the count, notifier and csi members
> * @pad: media pad for the video device entity
> *
> + * @hw_lock: protects the slot counter, hardware programming of
> + * slot addresses and the @buf_addr[] list
> + * @buf_addr: Memory addresses where current video data is written
> + *
> * @lock: protects @queue
> * @queue: vb2 buffers queue
> * @scratch: cpu address for scratch buffer
> @@ -147,8 +150,6 @@ struct rzg2l_cru_dev {
> u8 num_buf;
>
> u8 svc_channel;
> - dma_addr_t buf_addr[RZG2L_CRU_HW_BUFFER_DEFAULT];
> -
> struct v4l2_async_notifier notifier;
>
> struct rzg2l_cru_ip ip;
> @@ -157,6 +158,9 @@ struct rzg2l_cru_dev {
> struct mutex mdev_lock;
> struct media_pad pad;
>
> + spinlock_t hw_lock;
> + dma_addr_t buf_addr[RZG2L_CRU_HW_BUFFER_DEFAULT];
> +
> struct mutex lock;
> struct vb2_queue queue;
> void *scratch;
> diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
> index 27079c17a54c..a79b17e146bf 100644
> --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
> +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
> @@ -844,6 +844,7 @@ int rzg2l_cru_dma_register(struct rzg2l_cru_dev *cru)
> mutex_init(&cru->lock);
> INIT_LIST_HEAD(&cru->buf_list);
>
> + spin_lock_init(&cru->hw_lock);
> spin_lock_init(&cru->qlock);
>
> cru->state = RZG2L_CRU_DMA_STOPPED;
>
> --
> 2.53.0
>
Hi Jacopo
On 27/03/2026 17:10, Jacopo Mondi wrote:
> From: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
>
> The CRU driver uses a single spinlock to protect the buffers queue and
> the hardware operations.
>
> This single spinlock is held for the whole duration of the interrupt
> handler, causing all other driver's operations to freeze.
>
> Under heavy system stress conditions with userspace not providing
> buffers fast enough, this causes loss of frames.
>
> Prepare to re-work the driver locking by introducing (but not using yet)
> a new spinlock to protect the hardware registers programming.
>
> Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
> ---
Looks good:
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
> drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h | 10 +++++++---
> drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c | 1 +
> 2 files changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
> index 3a200db15730..b46696a0012b 100644
> --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
> +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
> @@ -109,7 +109,6 @@ struct rzg2l_cru_info {
> * @v4l2_dev: V4L2 device
> * @num_buf: Holds the current number of buffers enabled
> * @svc_channel: SVC0/1/2/3 to use for RZ/G3E
> - * @buf_addr: Memory addresses where current video data is written.
> * @notifier: V4L2 asynchronous subdevs notifier
> *
> * @ip: Image processing subdev info
> @@ -118,6 +117,10 @@ struct rzg2l_cru_info {
> * @mdev_lock: protects the count, notifier and csi members
> * @pad: media pad for the video device entity
> *
> + * @hw_lock: protects the slot counter, hardware programming of
> + * slot addresses and the @buf_addr[] list
> + * @buf_addr: Memory addresses where current video data is written
> + *
> * @lock: protects @queue
> * @queue: vb2 buffers queue
> * @scratch: cpu address for scratch buffer
> @@ -147,8 +150,6 @@ struct rzg2l_cru_dev {
> u8 num_buf;
>
> u8 svc_channel;
> - dma_addr_t buf_addr[RZG2L_CRU_HW_BUFFER_DEFAULT];
> -
> struct v4l2_async_notifier notifier;
>
> struct rzg2l_cru_ip ip;
> @@ -157,6 +158,9 @@ struct rzg2l_cru_dev {
> struct mutex mdev_lock;
> struct media_pad pad;
>
> + spinlock_t hw_lock;
> + dma_addr_t buf_addr[RZG2L_CRU_HW_BUFFER_DEFAULT];
> +
> struct mutex lock;
> struct vb2_queue queue;
> void *scratch;
> diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
> index 27079c17a54c..a79b17e146bf 100644
> --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
> +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
> @@ -844,6 +844,7 @@ int rzg2l_cru_dma_register(struct rzg2l_cru_dev *cru)
> mutex_init(&cru->lock);
> INIT_LIST_HEAD(&cru->buf_list);
>
> + spin_lock_init(&cru->hw_lock);
> spin_lock_init(&cru->qlock);
>
> cru->state = RZG2L_CRU_DMA_STOPPED;
>
© 2016 - 2026 Red Hat, Inc.