From deaa66ac6ce0c4594332cfb5b32b9d917f93f972 Mon Sep 17 00:00:00 2001 From: Rico Yang Date: Mon, 31 Aug 2020 03:31:51 +0000 Subject: media_module:h265 encoder: protect driver from multiple release [2/2] PD#SWPL-29483 Problem: hevc driver cannot be opened after closing driver for multiple times Solution: add protection against multiple closing Verify: verified on askey deadpool s905y2 Change-Id: Ie223da97a87afddc97c3668f5052967d42039123 --- diff --git a/drivers/frame_sink/encoder/h265/vpu.c b/drivers/frame_sink/encoder/h265/vpu.c index 40b47d0..746a935 100644 --- a/drivers/frame_sink/encoder/h265/vpu.c +++ b/drivers/frame_sink/encoder/h265/vpu.c @@ -74,6 +74,7 @@ } while (0) static s32 print_level = LOG_DEBUG; +static s32 force_release = 0; static s32 clock_level = 4; static struct video_mm_t s_vmem; @@ -310,13 +311,17 @@ static s32 vpu_open(struct inode *inode, struct file *filp) bool alloc_buffer = false; s32 r = 0; - enc_pr(LOG_DEBUG, "[+] %s\n", __func__); + enc_pr(LOG_DEBUG, "[+] %s, open_count=%d\n", __func__, + s_vpu_drv_context.open_count); + enc_pr(LOG_DEBUG, "vpu_open, calling process: %d:%s\n", current->pid, current->comm); spin_lock(&s_vpu_lock); s_vpu_drv_context.open_count++; if (s_vpu_drv_context.open_count == 1) { alloc_buffer = true; } else { r = -EBUSY; + enc_pr(LOG_DEBUG, "vpu_open, device is busy, s_vpu_drv_context.open_count=%d\n", + s_vpu_drv_context.open_count); s_vpu_drv_context.open_count--; spin_unlock(&s_vpu_lock); goto Err; @@ -437,8 +442,11 @@ static s32 vpu_open(struct inode *inode, struct file *filp) dma_cfg[1].fd = -1; dma_cfg[2].fd = -1; Err: - if (r != 0) + if (r != 0) { + enc_pr(LOG_DEBUG, "vpu_open, error handling, r=%d, s_vpu_drv_context.open_count\n", + r, s_vpu_drv_context.open_count); s_vpu_drv_context.open_count--; + } enc_pr(LOG_DEBUG, "[-] %s, ret: %d\n", __func__, r); return r; } @@ -1381,14 +1389,27 @@ static s32 vpu_release(struct inode *inode, struct file *filp) s32 ret = 0; ulong flags; - enc_pr(LOG_DEBUG, "vpu_release\n"); + enc_pr(LOG_DEBUG, "vpu_release, calling process: %d:%s\n", current->pid, current->comm); ret = down_interruptible(&s_vpu_sem); + enc_pr(LOG_DEBUG, "vpu_release, ret = %d\n", ret); + + if (s_vpu_drv_context.open_count <= 0) { + enc_pr(LOG_DEBUG, "vpu_release, open_count=%d, already released or even not inited\n", + s_vpu_drv_context.open_count); + s_vpu_drv_context.open_count = 0; + goto exit_release; + } + if (ret == 0) { vpu_free_buffers(filp); vpu_free_instances(filp); + + enc_pr(LOG_DEBUG, "vpu_release, decrease open_count from %d\n", + s_vpu_drv_context.open_count); + s_vpu_drv_context.open_count--; if (s_vpu_drv_context.open_count == 0) { - enc_pr(LOG_INFO, + enc_pr(LOG_DEBUG, "vpu_release: s_interrupt_flag(%d), reason(0x%08lx)\n", s_interrupt_flag, s_vpu_drv_context.interrupt_reason); s_vpu_drv_context.interrupt_reason = 0; @@ -1439,6 +1460,7 @@ static s32 vpu_release(struct inode *inode, struct file *filp) amports_switch_gate("vdec", 0); } } +exit_release: up(&s_vpu_sem); return 0; } @@ -2278,6 +2300,9 @@ static s32 __init hevc_mem_setup(struct reserved_mem *rmem) module_param(print_level, uint, 0664); MODULE_PARM_DESC(print_level, "\n print_level\n"); +module_param(force_release, uint, 0664); +MODULE_PARM_DESC(force_release, "\n print_level\n"); + module_param(clock_level, uint, 0664); MODULE_PARM_DESC(clock_level, "\n clock_level\n"); -- cgit