From: Arun Iyengar via B4 Relay <devnull+aiyengar1990.gmail.com@kernel.org>
To: Nicolas Dufresne <nicolas.dufresne@collabora.com>,
Benjamin Gaignard <benjamin.gaignard@collabora.com>,
Philipp Zabel <p.zabel@pengutronix.de>,
Mauro Carvalho Chehab <mchehab@kernel.org>,
Sebastian Fricke <sebastian.fricke@collabora.com>,
Hans Verkuil <hverkuil@kernel.org>,
Heiko Stuebner <heiko@sntech.de>,
Boris Brezillon <boris.brezillon@collabora.com>,
Jonas Karlman <jonas@kwiboo.se>,
Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>,
Jeffy Chen <jeffy.chen@rock-chips.com>,
Tomasz Figa <tfiga@chromium.org>
Cc: linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, stable@vger.kernel.org
Subject: [PATCH 4/4] media: verisilicon: Check every VPU981 AV1 tile column buffer before reusing them
Date: Tue, 10 Nov 2026 07:18:30 +0000 [thread overview]
Message-ID: <20261110-hantro-codec-fixes-v1-4-0fd5372ce831@gmail.com> (raw)
In-Reply-To: <20261110-hantro-codec-fixes-v1-0-0fd5372ce831@gmail.com>
From: Arun Iyengar <aiyengar1990@gmail.com>
rockchip_vpu981_av1_dec_tiles_reallocate() keeps the five tile column
buffers (deblocking data and control, CDEF, super-res, loop restoration)
when the deblocking data buffer is big enough for the current frame. The
buffers don't scale the same way: the deblocking data one grows with the
frame height and the bit depth, the super-res one only with the number of
64 pixel rows, and the loop restoration one with the number of
restoration stripes, which is one more than the number of superblock
rows. A frame can therefore fit in the old deblocking data buffer and
still need a larger buffer of another kind. For example, after a 10-bit
1088 line frame with 4 tile columns, an 8-bit frame of the same height
with 5 tile columns needs 65280 bytes of deblocking data (65536
allocated) but 367360 bytes of super-res column data (293888 allocated);
an 8-bit 128 line frame with 4 columns followed by a 64 line frame with 8
columns has the same problem with the loop restoration buffer. The
decoder then writes past the end of the smaller buffer.
The sizes are also not reset when the buffers are freed, so after a
failed allocation the stale size of the deblocking data buffer lets the
next frame skip the allocation and run with NULL buffers.
Compare each buffer with the size the current frame needs and clear the
sizes together with the buffers.
Fixes: 727a400686a2 ("media: verisilicon: Add Rockchip AV1 decoder")
Cc: stable@vger.kernel.org
Signed-off-by: Arun Iyengar <aiyengar1990@gmail.com>
---
.../verisilicon/rockchip_vpu981_hw_av1_dec.c | 34 +++++++++++++++++-----
1 file changed, 27 insertions(+), 7 deletions(-)
diff --git a/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c b/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
index 2a145433e6d1..e817c91224d3 100644
--- a/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
+++ b/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
@@ -236,27 +236,32 @@ static void rockchip_vpu981_av1_dec_tiles_free(struct hantro_ctx *ctx)
av1_dec->db_data_col.cpu,
av1_dec->db_data_col.dma);
av1_dec->db_data_col.cpu = NULL;
+ av1_dec->db_data_col.size = 0;
if (av1_dec->db_ctrl_col.cpu)
dma_free_coherent(vpu->dev, av1_dec->db_ctrl_col.size,
av1_dec->db_ctrl_col.cpu,
av1_dec->db_ctrl_col.dma);
av1_dec->db_ctrl_col.cpu = NULL;
+ av1_dec->db_ctrl_col.size = 0;
if (av1_dec->cdef_col.cpu)
dma_free_coherent(vpu->dev, av1_dec->cdef_col.size,
av1_dec->cdef_col.cpu, av1_dec->cdef_col.dma);
av1_dec->cdef_col.cpu = NULL;
+ av1_dec->cdef_col.size = 0;
if (av1_dec->sr_col.cpu)
dma_free_coherent(vpu->dev, av1_dec->sr_col.size,
av1_dec->sr_col.cpu, av1_dec->sr_col.dma);
av1_dec->sr_col.cpu = NULL;
+ av1_dec->sr_col.size = 0;
if (av1_dec->lr_col.cpu)
dma_free_coherent(vpu->dev, av1_dec->lr_col.size,
av1_dec->lr_col.cpu, av1_dec->lr_col.dma);
av1_dec->lr_col.cpu = NULL;
+ av1_dec->lr_col.size = 0;
}
static int rockchip_vpu981_av1_dec_tiles_reallocate(struct hantro_ctx *ctx)
@@ -269,15 +274,30 @@ static int rockchip_vpu981_av1_dec_tiles_reallocate(struct hantro_ctx *ctx)
unsigned int height = ALIGN(ctrls->frame->frame_height_minus_1 + 1, 64);
unsigned int height_in_sb = height / 64;
unsigned int stripe_num = ((height + 8) + 63) / 64;
+ size_t db_data_size, db_ctrl_size, cdef_size, sr_size, lr_size;
size_t size;
- if (av1_dec->db_data_col.size >=
- ALIGN(height * 12 * ctx->bit_depth / 8, 128) * num_tile_cols)
+ db_data_size = ALIGN(height * 12 * ctx->bit_depth / 8, 128) * num_tile_cols;
+ db_ctrl_size = ALIGN(height * 2 * 16 / 4, 128) * num_tile_cols;
+ cdef_size = ALIGN(height_in_sb * 44 * ctx->bit_depth * 16 / 8, 128) * num_tile_cols;
+ sr_size = ALIGN(height_in_sb * (3040 + 1280), 128) * num_tile_cols;
+ lr_size = ALIGN(stripe_num * 1536 * ctx->bit_depth / 8, 128) * num_tile_cols;
+
+ /*
+ * The five buffers scale differently with the frame height, the
+ * number of tile columns and the bit depth, so each of them has to be
+ * big enough for the current frame, not only the deblocking data one.
+ */
+ if (av1_dec->db_data_col.size >= db_data_size &&
+ av1_dec->db_ctrl_col.size >= db_ctrl_size &&
+ av1_dec->cdef_col.size >= cdef_size &&
+ av1_dec->sr_col.size >= sr_size &&
+ av1_dec->lr_col.size >= lr_size)
return 0;
rockchip_vpu981_av1_dec_tiles_free(ctx);
- size = ALIGN(height * 12 * ctx->bit_depth / 8, 128) * num_tile_cols;
+ size = db_data_size;
av1_dec->db_data_col.cpu = dma_alloc_coherent(vpu->dev, size,
&av1_dec->db_data_col.dma,
GFP_KERNEL);
@@ -285,7 +305,7 @@ static int rockchip_vpu981_av1_dec_tiles_reallocate(struct hantro_ctx *ctx)
goto buffer_allocation_error;
av1_dec->db_data_col.size = size;
- size = ALIGN(height * 2 * 16 / 4, 128) * num_tile_cols;
+ size = db_ctrl_size;
av1_dec->db_ctrl_col.cpu = dma_alloc_coherent(vpu->dev, size,
&av1_dec->db_ctrl_col.dma,
GFP_KERNEL);
@@ -293,7 +313,7 @@ static int rockchip_vpu981_av1_dec_tiles_reallocate(struct hantro_ctx *ctx)
goto buffer_allocation_error;
av1_dec->db_ctrl_col.size = size;
- size = ALIGN(height_in_sb * 44 * ctx->bit_depth * 16 / 8, 128) * num_tile_cols;
+ size = cdef_size;
av1_dec->cdef_col.cpu = dma_alloc_coherent(vpu->dev, size,
&av1_dec->cdef_col.dma,
GFP_KERNEL);
@@ -301,7 +321,7 @@ static int rockchip_vpu981_av1_dec_tiles_reallocate(struct hantro_ctx *ctx)
goto buffer_allocation_error;
av1_dec->cdef_col.size = size;
- size = ALIGN(height_in_sb * (3040 + 1280), 128) * num_tile_cols;
+ size = sr_size;
av1_dec->sr_col.cpu = dma_alloc_coherent(vpu->dev, size,
&av1_dec->sr_col.dma,
GFP_KERNEL);
@@ -309,7 +329,7 @@ static int rockchip_vpu981_av1_dec_tiles_reallocate(struct hantro_ctx *ctx)
goto buffer_allocation_error;
av1_dec->sr_col.size = size;
- size = ALIGN(stripe_num * 1536 * ctx->bit_depth / 8, 128) * num_tile_cols;
+ size = lr_size;
av1_dec->lr_col.cpu = dma_alloc_coherent(vpu->dev, size,
&av1_dec->lr_col.dma,
GFP_KERNEL);
--
2.55.0
prev parent reply other threads:[~2026-11-10 7:18 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-10 7:18 [PATCH 0/4] media: verisilicon: Fix MPEG-2 field pictures, 4K VP8 and the AV1 tile buffers Arun Iyengar via B4 Relay
2026-11-10 7:18 ` [PATCH 1/4] media: verisilicon: Support holding the CAPTURE buffer for MPEG-2 Arun Iyengar via B4 Relay
2026-11-10 7:18 ` [PATCH 2/4] media: verisilicon: Find the second MPEG-2 field without top_field_first Arun Iyengar via B4 Relay
2026-11-10 7:18 ` [PATCH 3/4] media: verisilicon: Don't offer VP8 above 1080p on the Rockchip VDPU2 Arun Iyengar via B4 Relay
2026-11-10 7:18 ` Arun Iyengar via B4 Relay [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261110-hantro-codec-fixes-v1-4-0fd5372ce831@gmail.com \
--to=devnull+aiyengar1990.gmail.com@kernel.org \
--cc=aiyengar1990@gmail.com \
--cc=benjamin.gaignard@collabora.com \
--cc=boris.brezillon@collabora.com \
--cc=ezequiel@vanguardiasur.com.ar \
--cc=heiko@sntech.de \
--cc=hverkuil@kernel.org \
--cc=jeffy.chen@rock-chips.com \
--cc=jonas@kwiboo.se \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=linux-rockchip@lists.infradead.org \
--cc=mchehab@kernel.org \
--cc=nicolas.dufresne@collabora.com \
--cc=p.zabel@pengutronix.de \
--cc=sebastian.fricke@collabora.com \
--cc=stable@vger.kernel.org \
--cc=tfiga@chromium.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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®