[git:media_stage/master] media: mediatek: vcodec: fix possible unbalanced PM counter
This is an automatic generated email to let you know that the following patch were queued: Subject: media: mediatek: vcodec: fix possible unbalanced PM counter Author: Eugen Hristev Date:Thu Dec 28 13:32:40 2023 +0200 It is possible that mtk_vcodec_enc_pw_on fails, and in that scenario the PM counter is not incremented, and subsequent call to mtk_vcodec_enc_pw_off decrements the counter, leading to a PM imbalance. Fix by bailing out of venc_if_encode in the case when mtk_vcodec_enc_pw_on fails. Fixes: 4e855a6efa54 ("[media] vcodec: mediatek: Add Mediatek V4L2 Video Encoder Driver") Signed-off-by: Eugen Hristev Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Sebastian Fricke Signed-off-by: Hans Verkuil drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.c | 4 +++- drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.h | 2 +- drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c | 5 - 3 files changed, 8 insertions(+), 3 deletions(-) --- diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.c b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.c index a22b7dfc656e..1a2b14a3e219 100644 --- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.c @@ -58,13 +58,15 @@ int mtk_vcodec_init_enc_clk(struct mtk_vcodec_enc_dev *mtkdev) return 0; } -void mtk_vcodec_enc_pw_on(struct mtk_vcodec_pm *pm) +int mtk_vcodec_enc_pw_on(struct mtk_vcodec_pm *pm) { int ret; ret = pm_runtime_resume_and_get(pm->dev); if (ret) dev_err(pm->dev, "pm_runtime_resume_and_get fail: %d", ret); + + return ret; } void mtk_vcodec_enc_pw_off(struct mtk_vcodec_pm *pm) diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.h b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.h index 157ea08ba9e3..2e28f25e36cc 100644 --- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.h +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.h @@ -10,7 +10,7 @@ #include "mtk_vcodec_enc_drv.h" int mtk_vcodec_init_enc_clk(struct mtk_vcodec_enc_dev *dev); -void mtk_vcodec_enc_pw_on(struct mtk_vcodec_pm *pm); +int mtk_vcodec_enc_pw_on(struct mtk_vcodec_pm *pm); void mtk_vcodec_enc_pw_off(struct mtk_vcodec_pm *pm); void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm); void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm); diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c index c402a686f3cb..e83747b8d69a 100644 --- a/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c @@ -64,7 +64,9 @@ int venc_if_encode(struct mtk_vcodec_enc_ctx *ctx, ctx->dev->curr_ctx = ctx; spin_unlock_irqrestore(>dev->irqlock, flags); - mtk_vcodec_enc_pw_on(>dev->pm); + ret = mtk_vcodec_enc_pw_on(>dev->pm); + if (ret) + goto venc_if_encode_pw_on_err; mtk_vcodec_enc_clock_on(>dev->pm); ret = ctx->enc_if->encode(ctx->drv_handle, opt, frm_buf, bs_buf, result); @@ -75,6 +77,7 @@ int venc_if_encode(struct mtk_vcodec_enc_ctx *ctx, ctx->dev->curr_ctx = NULL; spin_unlock_irqrestore(>dev->irqlock, flags); +venc_if_encode_pw_on_err: mtk_venc_unlock(ctx); return ret; }
[git:media_stage/master] media: mediatek: vcodec: Drop unnecessary variable
This is an automatic generated email to let you know that the following patch were queued: Subject: media: mediatek: vcodec: Drop unnecessary variable Author: Fei Shao Date:Thu Dec 21 09:17:44 2023 + In mtk_vcodec_mem_alloc() and mtk_vcodec_mem_free(), the value of mem->size is not expected to change before and when using the DMA APIs and debug print, so there's no point in keeping local copies of it. Drop the local variable "size" in the mentioned functions, and update printk format identifiers accordingly. This makes the code slightly more visually consistent, and retrieve a small amount of memory that is used for no real purpose. Signed-off-by: Fei Shao Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Sebastian Fricke Signed-off-by: Mauro Carvalho Chehab .../mediatek/vcodec/common/mtk_vcodec_util.c | 22 ++ 1 file changed, 10 insertions(+), 12 deletions(-) --- diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c index ea8c35c0e667..23bea2702c9a 100644 --- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c @@ -49,7 +49,6 @@ int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) { enum mtk_instance_type inst_type = *((unsigned int *)priv); struct platform_device *plat_dev; - unsigned long size = mem->size; int id; if (inst_type == MTK_INST_ENCODER) { @@ -64,15 +63,15 @@ int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) id = dec_ctx->id; } - mem->va = dma_alloc_coherent(_dev->dev, size, >dma_addr, GFP_KERNEL); + mem->va = dma_alloc_coherent(_dev->dev, mem->size, >dma_addr, GFP_KERNEL); if (!mem->va) { - mtk_v4l2_err(plat_dev, "%s dma_alloc size=%ld failed!", -__func__, size); + mtk_v4l2_err(plat_dev, "%s dma_alloc size=0x%zx failed!", +__func__, mem->size); return -ENOMEM; } - mtk_v4l2_debug(plat_dev, 3, "[%d] - va = %p dma = 0x%lx size = 0x%lx", id, mem->va, - (unsigned long)mem->dma_addr, size); + mtk_v4l2_debug(plat_dev, 3, "[%d] - va = %p dma = 0x%lx size = 0x%zx", id, mem->va, + (unsigned long)mem->dma_addr, mem->size); return 0; } @@ -82,7 +81,6 @@ void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) { enum mtk_instance_type inst_type = *((unsigned int *)priv); struct platform_device *plat_dev; - unsigned long size = mem->size; int id; if (inst_type == MTK_INST_ENCODER) { @@ -98,15 +96,15 @@ void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) } if (!mem->va) { - mtk_v4l2_err(plat_dev, "%s dma_free size=%ld failed!", -__func__, size); + mtk_v4l2_err(plat_dev, "%s dma_free size=0x%zx failed!", +__func__, mem->size); return; } - mtk_v4l2_debug(plat_dev, 3, "[%d] - va = %p dma = 0x%lx size = 0x%lx", id, mem->va, - (unsigned long)mem->dma_addr, size); + mtk_v4l2_debug(plat_dev, 3, "[%d] - va = %p dma = 0x%lx size = 0x%zx", id, mem->va, + (unsigned long)mem->dma_addr, mem->size); - dma_free_coherent(_dev->dev, size, mem->va, mem->dma_addr); + dma_free_coherent(_dev->dev, mem->size, mem->va, mem->dma_addr); mem->va = NULL; mem->dma_addr = 0; mem->size = 0;
[git:media_stage/master] media: mediatek: vcodec: Replace dev_name in error string
This is an automatic generated email to let you know that the following patch were queued: Subject: media: mediatek: vcodec: Replace dev_name in error string Author: Fei Shao Date:Thu Dec 21 09:17:43 2023 + mtk_v4l2_err() already uses dev_err(), so don't print the device name again. Print the function name instead. Signed-off-by: Fei Shao Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Sebastian Fricke Signed-off-by: Mauro Carvalho Chehab drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) --- diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c index 9ce34a3b5ee6..ea8c35c0e667 100644 --- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c @@ -67,7 +67,7 @@ int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) mem->va = dma_alloc_coherent(_dev->dev, size, >dma_addr, GFP_KERNEL); if (!mem->va) { mtk_v4l2_err(plat_dev, "%s dma_alloc size=%ld failed!", -dev_name(_dev->dev), size); +__func__, size); return -ENOMEM; } @@ -99,7 +99,7 @@ void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) if (!mem->va) { mtk_v4l2_err(plat_dev, "%s dma_free size=%ld failed!", -dev_name(_dev->dev), size); +__func__, size); return; }
[git:media_stage/master] media: mediatek: vcodec: Update mtk_vcodec_mem_free() error messages
This is an automatic generated email to let you know that the following patch were queued: Subject: media: mediatek: vcodec: Update mtk_vcodec_mem_free() error messages Author: Fei Shao Date:Thu Dec 21 09:17:45 2023 + In mtk_vcodec_mem_free(), there are two cases where a NULL VA is passed: - mem->size == 0: we are called to free no memory. This may happen when we call mtk_vcodec_mem_free() twice or the memory has never been allocated. - mem->size > 0: we are called to free memory but without VA. This means that we failed to free the memory for real. Both cases are not expected to happen, and we want to have clearer error messages to describe which one we just encountered. Update the error messages to include more information for that purpose. Signed-off-by: Fei Shao Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Sebastian Fricke Signed-off-by: Mauro Carvalho Chehab drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) --- diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c index 23bea2702c9a..c60e4c193b25 100644 --- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c @@ -96,8 +96,9 @@ void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) } if (!mem->va) { - mtk_v4l2_err(plat_dev, "%s dma_free size=0x%zx failed!", -__func__, mem->size); + mtk_v4l2_err(plat_dev, "%s: Tried to free a NULL VA", __func__); + if (mem->size) + mtk_v4l2_err(plat_dev, "Failed to free %zu bytes", mem->size); return; }
[git:media_stage/master] media: mediatek: vcodec: Only free buffer VA that is not NULL
This is an automatic generated email to let you know that the following patch were queued: Subject: media: mediatek: vcodec: Only free buffer VA that is not NULL Author: Fei Shao Date:Thu Dec 21 09:17:46 2023 + In the MediaTek vcodec driver, while mtk_vcodec_mem_free() is mostly called only when the buffer to free exists, there are some instances that didn't do the check and triggered warnings in practice. We believe those checks were forgotten unintentionally. Add the checks back to fix the warnings. Signed-off-by: Fei Shao Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Sebastian Fricke Signed-off-by: Mauro Carvalho Chehab .../vcodec/decoder/vdec/vdec_av1_req_lat_if.c | 22 +++--- .../mediatek/vcodec/encoder/venc/venc_h264_if.c| 5 +++-- 2 files changed, 18 insertions(+), 9 deletions(-) --- diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c index a081e12d67d6..bf21f2467a0f 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c @@ -1023,18 +1023,26 @@ static void vdec_av1_slice_free_working_buffer(struct vdec_av1_slice_instance *i int i; for (i = 0; i < ARRAY_SIZE(instance->mv); i++) - mtk_vcodec_mem_free(ctx, >mv[i]); + if (instance->mv[i].va) + mtk_vcodec_mem_free(ctx, >mv[i]); for (i = 0; i < ARRAY_SIZE(instance->seg); i++) - mtk_vcodec_mem_free(ctx, >seg[i]); + if (instance->seg[i].va) + mtk_vcodec_mem_free(ctx, >seg[i]); for (i = 0; i < ARRAY_SIZE(instance->cdf); i++) - mtk_vcodec_mem_free(ctx, >cdf[i]); + if (instance->cdf[i].va) + mtk_vcodec_mem_free(ctx, >cdf[i]); + - mtk_vcodec_mem_free(ctx, >tile); - mtk_vcodec_mem_free(ctx, >cdf_temp); - mtk_vcodec_mem_free(ctx, >cdf_table); - mtk_vcodec_mem_free(ctx, >iq_table); + if (instance->tile.va) + mtk_vcodec_mem_free(ctx, >tile); + if (instance->cdf_temp.va) + mtk_vcodec_mem_free(ctx, >cdf_temp); + if (instance->cdf_table.va) + mtk_vcodec_mem_free(ctx, >cdf_table); + if (instance->iq_table.va) + mtk_vcodec_mem_free(ctx, >iq_table); instance->level = AV1_RES_NONE; } diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c index a68dac72c4e4..f8145998fcaf 100644 --- a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c @@ -301,11 +301,12 @@ static void h264_enc_free_work_buf(struct venc_h264_inst *inst) * other buffers need to be freed by AP. */ for (i = 0; i < VENC_H264_VPU_WORK_BUF_MAX; i++) { - if (i != VENC_H264_VPU_WORK_BUF_SKIP_FRAME) + if (i != VENC_H264_VPU_WORK_BUF_SKIP_FRAME && inst->work_bufs[i].va) mtk_vcodec_mem_free(inst->ctx, >work_bufs[i]); } - mtk_vcodec_mem_free(inst->ctx, >pps_buf); + if (inst->pps_buf.va) + mtk_vcodec_mem_free(inst->ctx, >pps_buf); } static int h264_enc_alloc_work_buf(struct venc_h264_inst *inst, bool is_34bit)