* [PATCH] media: verisilicon: rockchip: Fix leaks in init
@ 2026-08-19 9:28 Michail Tatas
2026-08-19 16:56 ` Frank Li
0 siblings, 1 reply; 3+ messages in thread
From: Michail Tatas @ 2026-08-19 9:28 UTC (permalink / raw)
To: nicolas.dufresne, benjamin.gaignard, p.zabel, mchehab, heiko
Cc: linux-media, linux-rockchip, linux-arm-kernel, linux-kernel
if one of the dma_alloc_coherent in the init fucntion fails then
the previously allocated ones leak.
Fix by freeing them in the error path.
Fixes: 727a400686a2 ("media: verisilicon: Add Rockchip AV1 decoder")
Signed-off-by: Michail Tatas <michail.tatas@gmail.com>
---
.../verisilicon/rockchip_vpu981_hw_av1_dec.c | 68 +++++++++++++++----
1 file changed, 55 insertions(+), 13 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 e4e21ad37323..fa77fd402412 100644
--- a/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
+++ b/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
@@ -369,6 +369,7 @@ void rockchip_vpu981_av1_dec_exit(struct hantro_ctx *ctx)
int rockchip_vpu981_av1_dec_init(struct hantro_ctx *ctx)
{
+ int ret = 0;
struct hantro_dev *vpu = ctx->dev;
struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
@@ -377,39 +378,54 @@ int rockchip_vpu981_av1_dec_init(struct hantro_ctx *ctx)
av1_dec->global_model.cpu = dma_alloc_coherent(vpu->dev, GLOBAL_MODEL_SIZE,
&av1_dec->global_model.dma,
GFP_KERNEL);
- if (!av1_dec->global_model.cpu)
- return -ENOMEM;
+ if (!av1_dec->global_model.cpu) {
+ ret = -ENOMEM;
+ goto global_model_cpu_err;
+ }
+
av1_dec->global_model.size = GLOBAL_MODEL_SIZE;
av1_dec->tile_info.cpu = dma_alloc_coherent(vpu->dev, AV1_TILE_INFO_SIZE,
&av1_dec->tile_info.dma,
GFP_KERNEL);
- if (!av1_dec->tile_info.cpu)
- return -ENOMEM;
+ if (!av1_dec->tile_info.cpu) {
+ ret = -ENOMEM;
+ goto tile_info_cpu_err;
+ }
+
av1_dec->tile_info.size = AV1_TILE_INFO_SIZE;
av1_dec->film_grain.cpu = dma_alloc_coherent(vpu->dev,
ALIGN(sizeof(struct rockchip_av1_film_grain), 2048),
&av1_dec->film_grain.dma,
GFP_KERNEL);
- if (!av1_dec->film_grain.cpu)
- return -ENOMEM;
+ if (!av1_dec->film_grain.cpu) {
+ ret = -ENOMEM;
+ goto film_grain_cpu_err;
+ }
+
av1_dec->film_grain.size = ALIGN(sizeof(struct rockchip_av1_film_grain), 2048);
av1_dec->prob_tbl.cpu = dma_alloc_coherent(vpu->dev,
ALIGN(sizeof(struct av1cdfs), 2048),
&av1_dec->prob_tbl.dma,
GFP_KERNEL);
- if (!av1_dec->prob_tbl.cpu)
- return -ENOMEM;
+ if (!av1_dec->prob_tbl.cpu) {
+ ret = -ENOMEM;
+ goto prob_tbl_cpu_err;
+ }
+
av1_dec->prob_tbl.size = ALIGN(sizeof(struct av1cdfs), 2048);
av1_dec->prob_tbl_out.cpu = dma_alloc_coherent(vpu->dev,
ALIGN(sizeof(struct av1cdfs), 2048),
&av1_dec->prob_tbl_out.dma,
GFP_KERNEL);
- if (!av1_dec->prob_tbl_out.cpu)
- return -ENOMEM;
+ if (!av1_dec->prob_tbl_out.cpu) {
+ ret = -ENOMEM;
+ goto prob_tbl_out_cpu_err;
+ }
+
av1_dec->prob_tbl_out.size = ALIGN(sizeof(struct av1cdfs), 2048);
av1_dec->cdfs = &av1_dec->default_cdfs;
av1_dec->cdfs_ndvc = &av1_dec->default_cdfs_ndvc;
@@ -420,11 +436,37 @@ int rockchip_vpu981_av1_dec_init(struct hantro_ctx *ctx)
AV1_TILE_SIZE,
&av1_dec->tile_buf.dma,
GFP_KERNEL);
- if (!av1_dec->tile_buf.cpu)
- return -ENOMEM;
+ if (!av1_dec->tile_buf.cpu) {
+ ret = -ENOMEM;
+ goto tile_buf_cpu_err;
+ }
+
av1_dec->tile_buf.size = AV1_TILE_SIZE;
- return 0;
+ return ret;
+
+tile_buf_cpu_err:
+ dma_free_coherent(vpu->dev, av1_dec->prob_tbl_out.size,
+ av1_dec->prob_tbl_out.cpu,
+ av1_dec->prob_tbl_out.dma);
+prob_tbl_out_cpu_err:
+ dma_free_coherent(vpu->dev, av1_dec->prob_tbl.size,
+ av1_dec->prob_tbl.cpu,
+ av1_dec->prob_tbl.dma);
+prob_tbl_cpu_err:
+ dma_free_coherent(vpu->dev, av1_dec->film_grain.size,
+ av1_dec->film_grain.cpu,
+ av1_dec->film_grain.dma);
+film_grain_cpu_err:
+ dma_free_coherent(vpu->dev, av1_dec->tile_info.size,
+ av1_dec->tile_info.cpu,
+ av1_dec->tile_info.dma);
+tile_info_cpu_err:
+ dma_free_coherent(vpu->dev, av1_dec->global_model.size,
+ av1_dec->global_model.cpu,
+ av1_dec->global_model.dma);
+global_model_cpu_err:
+ return ret;
}
static int rockchip_vpu981_av1_dec_prepare_run(struct hantro_ctx *ctx)
--
2.43.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] media: verisilicon: rockchip: Fix leaks in init
2026-08-19 9:28 [PATCH] media: verisilicon: rockchip: Fix leaks in init Michail Tatas
@ 2026-08-19 16:56 ` Frank Li
2026-08-20 21:16 ` Michail Tatas
0 siblings, 1 reply; 3+ messages in thread
From: Frank Li @ 2026-08-19 16:56 UTC (permalink / raw)
To: Michail Tatas
Cc: nicolas.dufresne, benjamin.gaignard, p.zabel, mchehab, heiko,
linux-media, linux-rockchip, linux-arm-kernel, linux-kernel
On Wed, Aug 19, 2026 at 12:28:12PM +0300, Michail Tatas wrote:
> if one of the dma_alloc_coherent in the init fucntion fails then
> the previously allocated ones leak.
>
> Fix by freeing them in the error path.
>
> Fixes: 727a400686a2 ("media: verisilicon: Add Rockchip AV1 decoder")
> Signed-off-by: Michail Tatas <michail.tatas@gmail.com>
> ---
> .../verisilicon/rockchip_vpu981_hw_av1_dec.c | 68 +++++++++++++++----
> 1 file changed, 55 insertions(+), 13 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 e4e21ad37323..fa77fd402412 100644
> --- a/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
> +++ b/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
> @@ -369,6 +369,7 @@ void rockchip_vpu981_av1_dec_exit(struct hantro_ctx *ctx)
>
> int rockchip_vpu981_av1_dec_init(struct hantro_ctx *ctx)
> {
> + int ret = 0;
> struct hantro_dev *vpu = ctx->dev;
> struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
>
> @@ -377,39 +378,54 @@ int rockchip_vpu981_av1_dec_init(struct hantro_ctx *ctx)
> av1_dec->global_model.cpu = dma_alloc_coherent(vpu->dev, GLOBAL_MODEL_SIZE,
> &av1_dec->global_model.dma,
> GFP_KERNEL);
> - if (!av1_dec->global_model.cpu)
> - return -ENOMEM;
> + if (!av1_dec->global_model.cpu) {
> + ret = -ENOMEM;
> + goto global_model_cpu_err;
> + }
> +
> av1_dec->global_model.size = GLOBAL_MODEL_SIZE;
>
> av1_dec->tile_info.cpu = dma_alloc_coherent(vpu->dev, AV1_TILE_INFO_SIZE,
> &av1_dec->tile_info.dma,
> GFP_KERNEL);
> - if (!av1_dec->tile_info.cpu)
> - return -ENOMEM;
> + if (!av1_dec->tile_info.cpu) {
> + ret = -ENOMEM;
> + goto tile_info_cpu_err;
> + }
> +
This function is called by hantro_probe() if I am correct
there are dmam_alloc_coherent(), use dmam_alloc_coherent() will simple
error handle and tear down.
Frank
> av1_dec->tile_info.size = AV1_TILE_INFO_SIZE;
>
> av1_dec->film_grain.cpu = dma_alloc_coherent(vpu->dev,
> ALIGN(sizeof(struct rockchip_av1_film_grain), 2048),
> &av1_dec->film_grain.dma,
> GFP_KERNEL);
> - if (!av1_dec->film_grain.cpu)
> - return -ENOMEM;
> + if (!av1_dec->film_grain.cpu) {
> + ret = -ENOMEM;
> + goto film_grain_cpu_err;
> + }
> +
> av1_dec->film_grain.size = ALIGN(sizeof(struct rockchip_av1_film_grain), 2048);
>
> av1_dec->prob_tbl.cpu = dma_alloc_coherent(vpu->dev,
> ALIGN(sizeof(struct av1cdfs), 2048),
> &av1_dec->prob_tbl.dma,
> GFP_KERNEL);
> - if (!av1_dec->prob_tbl.cpu)
> - return -ENOMEM;
> + if (!av1_dec->prob_tbl.cpu) {
> + ret = -ENOMEM;
> + goto prob_tbl_cpu_err;
> + }
> +
> av1_dec->prob_tbl.size = ALIGN(sizeof(struct av1cdfs), 2048);
>
> av1_dec->prob_tbl_out.cpu = dma_alloc_coherent(vpu->dev,
> ALIGN(sizeof(struct av1cdfs), 2048),
> &av1_dec->prob_tbl_out.dma,
> GFP_KERNEL);
> - if (!av1_dec->prob_tbl_out.cpu)
> - return -ENOMEM;
> + if (!av1_dec->prob_tbl_out.cpu) {
> + ret = -ENOMEM;
> + goto prob_tbl_out_cpu_err;
> + }
> +
> av1_dec->prob_tbl_out.size = ALIGN(sizeof(struct av1cdfs), 2048);
> av1_dec->cdfs = &av1_dec->default_cdfs;
> av1_dec->cdfs_ndvc = &av1_dec->default_cdfs_ndvc;
> @@ -420,11 +436,37 @@ int rockchip_vpu981_av1_dec_init(struct hantro_ctx *ctx)
> AV1_TILE_SIZE,
> &av1_dec->tile_buf.dma,
> GFP_KERNEL);
> - if (!av1_dec->tile_buf.cpu)
> - return -ENOMEM;
> + if (!av1_dec->tile_buf.cpu) {
> + ret = -ENOMEM;
> + goto tile_buf_cpu_err;
> + }
> +
> av1_dec->tile_buf.size = AV1_TILE_SIZE;
>
> - return 0;
> + return ret;
> +
> +tile_buf_cpu_err:
> + dma_free_coherent(vpu->dev, av1_dec->prob_tbl_out.size,
> + av1_dec->prob_tbl_out.cpu,
> + av1_dec->prob_tbl_out.dma);
> +prob_tbl_out_cpu_err:
> + dma_free_coherent(vpu->dev, av1_dec->prob_tbl.size,
> + av1_dec->prob_tbl.cpu,
> + av1_dec->prob_tbl.dma);
> +prob_tbl_cpu_err:
> + dma_free_coherent(vpu->dev, av1_dec->film_grain.size,
> + av1_dec->film_grain.cpu,
> + av1_dec->film_grain.dma);
> +film_grain_cpu_err:
> + dma_free_coherent(vpu->dev, av1_dec->tile_info.size,
> + av1_dec->tile_info.cpu,
> + av1_dec->tile_info.dma);
> +tile_info_cpu_err:
> + dma_free_coherent(vpu->dev, av1_dec->global_model.size,
> + av1_dec->global_model.cpu,
> + av1_dec->global_model.dma);
> +global_model_cpu_err:
> + return ret;
> }
>
> static int rockchip_vpu981_av1_dec_prepare_run(struct hantro_ctx *ctx)
> --
> 2.43.0
>
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] media: verisilicon: rockchip: Fix leaks in init
2026-08-19 16:56 ` Frank Li
@ 2026-08-20 21:16 ` Michail Tatas
0 siblings, 0 replies; 3+ messages in thread
From: Michail Tatas @ 2026-08-20 21:16 UTC (permalink / raw)
To: Frank Li
Cc: nicolas.dufresne, benjamin.gaignard, p.zabel, mchehab, heiko,
linux-media, linux-rockchip, linux-arm-kernel, linux-kernel
On Wed, Aug 19, 2026 at 12:56:40PM -0400, Frank Li wrote:
> On Wed, Aug 19, 2026 at 12:28:12PM +0300, Michail Tatas wrote:
> > if one of the dma_alloc_coherent in the init fucntion fails then
> > the previously allocated ones leak.
> >
> > Fix by freeing them in the error path.
> >
> > Fixes: 727a400686a2 ("media: verisilicon: Add Rockchip AV1 decoder")
> > Signed-off-by: Michail Tatas <michail.tatas@gmail.com>
> > ---
> > .../verisilicon/rockchip_vpu981_hw_av1_dec.c | 68 +++++++++++++++----
> > 1 file changed, 55 insertions(+), 13 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 e4e21ad37323..fa77fd402412 100644
> > --- a/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
> > +++ b/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
> > @@ -369,6 +369,7 @@ void rockchip_vpu981_av1_dec_exit(struct hantro_ctx *ctx)
> >
> > int rockchip_vpu981_av1_dec_init(struct hantro_ctx *ctx)
> > {
> > + int ret = 0;
> > struct hantro_dev *vpu = ctx->dev;
> > struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
> >
> > @@ -377,39 +378,54 @@ int rockchip_vpu981_av1_dec_init(struct hantro_ctx *ctx)
> > av1_dec->global_model.cpu = dma_alloc_coherent(vpu->dev, GLOBAL_MODEL_SIZE,
> > &av1_dec->global_model.dma,
> > GFP_KERNEL);
> > - if (!av1_dec->global_model.cpu)
> > - return -ENOMEM;
> > + if (!av1_dec->global_model.cpu) {
> > + ret = -ENOMEM;
> > + goto global_model_cpu_err;
> > + }
> > +
> > av1_dec->global_model.size = GLOBAL_MODEL_SIZE;
> >
> > av1_dec->tile_info.cpu = dma_alloc_coherent(vpu->dev, AV1_TILE_INFO_SIZE,
> > &av1_dec->tile_info.dma,
> > GFP_KERNEL);
> > - if (!av1_dec->tile_info.cpu)
> > - return -ENOMEM;
> > + if (!av1_dec->tile_info.cpu) {
> > + ret = -ENOMEM;
> > + goto tile_info_cpu_err;
> > + }
> > +
>
> This function is called by hantro_probe() if I am correct
>
> there are dmam_alloc_coherent(), use dmam_alloc_coherent() will simple
> error handle and tear down.
>
> Frank
Hello Frank,
I did not know about the dmam* functions thanks for letting me know.
I read some of the docs about them and they seem to not apply to
this particular case since this code is not called from the probe
function but rather the hantro_start_streaming function. Since
dmam_alloc_coherent() only releases memory at device removal,
it wouldn't free them when the stream ends and a new stream would
re-allocate while the old buffers lingered until detach.
So I think manual dma_free_coherent() error path is the correct
fit here.
Best regards,
Michail
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-08-20 21:16 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-19 9:28 [PATCH] media: verisilicon: rockchip: Fix leaks in init Michail Tatas
2026-08-19 16:56 ` Frank Li
2026-08-20 21:16 ` Michail Tatas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox