From e9ee0ea8fe068067d3c5dde98d5f8d5d07ad7227 Mon Sep 17 00:00:00 2001 From: Song Zhao Date: Mon, 14 Dec 2020 11:31:27 -0800 Subject: [PATCH] v4l2: fix a decoder release after oom [1/1] PD#SWPL-39061 Problem: When oom happens, decoder is leaked. Solution: correct error handling Verify: T318 Change-Id: I7d0575be2a58aad0bb3589362b45f56fda24e501 Signed-off-by: Song Zhao --- drivers/amvdec_ports/decoder/vdec_h264_if.c | 4 ++++ drivers/amvdec_ports/decoder/vdec_hevc_if.c | 4 ++++ drivers/amvdec_ports/decoder/vdec_mjpeg_if.c | 4 ++++ drivers/amvdec_ports/decoder/vdec_mpeg12_if.c | 4 ++++ drivers/amvdec_ports/decoder/vdec_mpeg4_if.c | 4 ++++ 5 files changed, 20 insertions(+) diff --git a/drivers/amvdec_ports/decoder/vdec_h264_if.c b/drivers/amvdec_ports/decoder/vdec_h264_if.c index 8ac9a1e..2df8b80 100644 --- a/drivers/amvdec_ports/decoder/vdec_h264_if.c +++ b/drivers/amvdec_ports/decoder/vdec_h264_if.c @@ -297,6 +297,7 @@ static int vdec_h264_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) { struct vdec_h264_inst *inst = NULL; int ret = -1; + bool dec_init = false; inst = kzalloc(sizeof(*inst), GFP_KERNEL); if (!inst) @@ -330,6 +331,7 @@ static int vdec_h264_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) "vdec_h264 init err=%d\n", ret); goto err; } + dec_init = true; /* probe info from the stream */ inst->vsi = kzalloc(sizeof(struct vdec_h264_vsi), GFP_KERNEL); @@ -357,6 +359,8 @@ static int vdec_h264_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) return 0; err: + if (dec_init) + video_decoder_release(&inst->vdec); if (inst) vcodec_vfm_release(&inst->vfm); if (inst && inst->vsi && inst->vsi->header_buf) diff --git a/drivers/amvdec_ports/decoder/vdec_hevc_if.c b/drivers/amvdec_ports/decoder/vdec_hevc_if.c index 9ad24d3..dc3a923 100644 --- a/drivers/amvdec_ports/decoder/vdec_hevc_if.c +++ b/drivers/amvdec_ports/decoder/vdec_hevc_if.c @@ -201,6 +201,7 @@ static int vdec_hevc_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) { struct vdec_hevc_inst *inst = NULL; int ret = -1; + bool dec_init = false; inst = kzalloc(sizeof(*inst), GFP_KERNEL); if (!inst) @@ -237,6 +238,7 @@ static int vdec_hevc_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) "vdec_hevc init err=%d\n", ret); goto err; } + dec_init = true; /* probe info from the stream */ inst->vsi = kzalloc(sizeof(struct vdec_hevc_vsi), GFP_KERNEL); @@ -264,6 +266,8 @@ static int vdec_hevc_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) return 0; err: + if (dec_init) + video_decoder_release(&inst->vdec); if (inst) vcodec_vfm_release(&inst->vfm); if (inst && inst->vsi && inst->vsi->header_buf) diff --git a/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c b/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c index f200a34..68a100e 100644 --- a/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c +++ b/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c @@ -192,6 +192,7 @@ static int vdec_mjpeg_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) { struct vdec_mjpeg_inst *inst = NULL; int ret = -1; + bool dec_init = false; inst = kzalloc(sizeof(*inst), GFP_KERNEL); if (!inst) @@ -228,6 +229,7 @@ static int vdec_mjpeg_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) "vdec_mjpeg init err=%d\n", ret); goto err; } + dec_init = true; /* probe info from the stream */ inst->vsi = kzalloc(sizeof(struct vdec_mjpeg_vsi), GFP_KERNEL); @@ -255,6 +257,8 @@ static int vdec_mjpeg_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) return 0; err: + if (dec_init) + video_decoder_release(&inst->vdec); if (inst) vcodec_vfm_release(&inst->vfm); if (inst && inst->vsi && inst->vsi->header_buf) diff --git a/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c b/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c index 613e282..be6e477 100644 --- a/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c +++ b/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c @@ -187,6 +187,7 @@ static int vdec_mpeg12_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) { struct vdec_mpeg12_inst *inst = NULL; int ret = -1; + bool dec_init = false; inst = kzalloc(sizeof(*inst), GFP_KERNEL); if (!inst) @@ -224,6 +225,7 @@ static int vdec_mpeg12_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) "vdec_mpeg12 init err=%d\n", ret); goto err; } + dec_init = true; /* probe info from the stream */ inst->vsi = kzalloc(sizeof(struct vdec_mpeg12_vsi), GFP_KERNEL); @@ -250,6 +252,8 @@ static int vdec_mpeg12_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) return 0; err: + if (dec_init) + video_decoder_release(&inst->vdec); if (inst) vcodec_vfm_release(&inst->vfm); if (inst && inst->vsi && inst->vsi->header_buf) diff --git a/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c b/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c index ea7fbc9..1287783 100644 --- a/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c +++ b/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c @@ -188,6 +188,7 @@ static int vdec_mpeg4_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) { struct vdec_mpeg4_inst *inst = NULL; int ret = -1; + bool dec_init = false; inst = kzalloc(sizeof(*inst), GFP_KERNEL); if (!inst) @@ -218,6 +219,7 @@ static int vdec_mpeg4_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) "init vfm failed.\n"); goto err; } + dec_init = true; ret = video_decoder_init(&inst->vdec); if (ret) { @@ -252,6 +254,8 @@ static int vdec_mpeg4_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec) return 0; err: + if (dec_init) + video_decoder_release(&inst->vdec); if (inst) vcodec_vfm_release(&inst->vfm); if (inst && inst->vsi && inst->vsi->header_buf) -- 2.20.1