From 56cc992be4c9b15382bf688fd79fb6f785cc66bd Mon Sep 17 00:00:00 2001 From: "renjiang.han" Date: Thu, 23 Apr 2020 17:54:55 +0800 Subject: [PATCH] ppmgr: Where semaphores are used in ppmgr may cause deadlock. [1/1] PD#SWPL-24904 Problem: When the semaphore is used, it is suddenly re-initialized. Solution: The semaphore is only initialized during the probe. Verify: on X301 Change-Id: I1c45a56c1c204f5a3e2ee2fc7e31ac3da88348e1 Signed-off-by: renjiang.han --- .../media/video_processor/ppmgr/ppmgr_dev.h | 4 ++ .../media/video_processor/ppmgr/ppmgr_drv.c | 2 + .../media/video_processor/ppmgr/ppmgr_vpp.c | 50 +++++++++---------- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/drivers/amlogic/media/video_processor/ppmgr/ppmgr_dev.h b/drivers/amlogic/media/video_processor/ppmgr/ppmgr_dev.h index af789ce28efa..55cfb5a2add8 100644 --- a/drivers/amlogic/media/video_processor/ppmgr/ppmgr_dev.h +++ b/drivers/amlogic/media/video_processor/ppmgr/ppmgr_dev.h @@ -18,6 +18,8 @@ #ifndef PPMGR_DEV_INCLUDE_H #define PPMGR_DEV_INCLUDE_H #include +#include + struct ppmgr_device_t { struct class *cla; struct device *dev; @@ -81,6 +83,8 @@ struct ppmgr_device_t { unsigned int put_dec_count; unsigned int peek_dec; char dump_path[32]; + struct semaphore ppmgr_sem; + struct semaphore tb_sem; }; struct ppmgr_dev_reg_s { diff --git a/drivers/amlogic/media/video_processor/ppmgr/ppmgr_drv.c b/drivers/amlogic/media/video_processor/ppmgr/ppmgr_drv.c index 96882882bc87..07bd70d31d9b 100644 --- a/drivers/amlogic/media/video_processor/ppmgr/ppmgr_drv.c +++ b/drivers/amlogic/media/video_processor/ppmgr/ppmgr_drv.c @@ -1906,6 +1906,8 @@ int init_ppmgr_device(void) ppmgr_device.put_count = 0; ppmgr_device.get_dec_count = 0; ppmgr_device.put_dec_count = 0; + sema_init(&ppmgr_device.ppmgr_sem, 1); + sema_init(&ppmgr_device.tb_sem, 1); PPMGRDRV_INFO("ppmgr_dev major:%d\n", ret); diff --git a/drivers/amlogic/media/video_processor/ppmgr/ppmgr_vpp.c b/drivers/amlogic/media/video_processor/ppmgr/ppmgr_vpp.c index 33c1d833b594..c216a9b6c161 100644 --- a/drivers/amlogic/media/video_processor/ppmgr/ppmgr_vpp.c +++ b/drivers/amlogic/media/video_processor/ppmgr/ppmgr_vpp.c @@ -38,7 +38,7 @@ #include #include #include -#include +//#include #include #include "ppmgr_log.h" #include "ppmgr_pri.h" @@ -137,7 +137,7 @@ static struct buf_status_s buf_status[VF_POOL_SIZE]; struct vfq_s q_ready, q_free; static int display_mode_change = VF_POOL_SIZE; -static struct semaphore thread_sem; +//static struct semaphore thread_sem; static DEFINE_MUTEX(ppmgr_mutex); static bool ppmgr_quit_flag; @@ -162,7 +162,7 @@ static DEFINE_MUTEX(tb_mutex); static struct tb_buf_s detect_buf[TB_DETECT_BUFFER_MAX_SIZE]; static struct task_struct *tb_detect_task; static int tb_task_running; -static struct semaphore tb_sem; +//static struct semaphore tb_sem; static atomic_t detect_status; static atomic_t tb_detect_flag; static u8 tb_detect_last_flag; @@ -493,14 +493,14 @@ static int ppmgr_event_cb(int type, void *data, void *private_data) PPMGRVPP_WARN("video put, avail=%d, free=%d\n", vfq_level(&q_ready), vfq_level(&q_free)); #endif - up(&thread_sem); + up(&ppmgr_device.ppmgr_sem); } #ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER_PPSCALER if (type & VFRAME_EVENT_RECEIVER_POS_CHANGED) { if (task_running) { scaler_pos_changed = 1; /*printk("--ppmgr: get pos changed msg.\n");*/ - up(&thread_sem); + up(&ppmgr_device.ppmgr_sem); } } #endif @@ -516,14 +516,14 @@ static int ppmgr_event_cb(int type, void *data, void *private_data) #ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER_PPSCALER if (!amvideo_get_scaler_mode()) { still_picture_notify = 1; - up(&thread_sem); + up(&ppmgr_device.ppmgr_sem); } #else still_picture_notify = 1; - up(&thread_sem); + up(&ppmgr_device.ppmgr_sem); #endif } else { - up(&thread_sem); + up(&ppmgr_device.ppmgr_sem); } } } @@ -586,7 +586,7 @@ static int ppmgr_receiver_event_fun(int type, void *data, void *private_data) PPMGRVPP_WARN("dec put, avail=%d, free=%d\n", vfq_level(&q_ready), vfq_level(&q_free)); #endif - up(&thread_sem); + up(&ppmgr_device.ppmgr_sem); break; case VFRAME_EVENT_PROVIDER_QUREY_STATE: ppmgr_vf_states(&states, NULL); @@ -603,6 +603,7 @@ static int ppmgr_receiver_event_fun(int type, void *data, void *private_data) #ifdef DDD PPMGRVPP_WARN("register now\n"); #endif + up(&ppmgr_device.ppmgr_sem); vf_ppmgr_reg_provider(); vf_notify_receiver( PROVIDER_NAME, @@ -663,7 +664,7 @@ void vf_local_init(void) buf_status[i].index = ppmgr_canvas_tab[i]; buf_status[i].dirty = 1; } - sema_init(&thread_sem, 1); + //up(&ppmgr_device.ppmgr_sem); } static const struct vframe_provider_s *dec_vfp; @@ -722,7 +723,7 @@ void vf_ppmgr_reset(int type) ppmgr_blocking = true; ppmgr_reset_type = type; - up(&thread_sem); + up(&ppmgr_device.ppmgr_sem); last_reset_time = current_reset_time; } @@ -1879,7 +1880,7 @@ static void process_vf_change(struct vframe_s *vf, struct ge2d_context_s *context, struct config_para_ex_s *ge2d_config) { - struct vframe_s temp_vf; + static struct vframe_s temp_vf; struct ppframe_s *pp_vf = to_ppframe(vf); struct canvas_s cs0, cs1, cs2, cd; int interlace_mode; @@ -2455,7 +2456,7 @@ static int ppmgr_task(void *data) #ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER_3D_PROCESS Reset3Dclear(); #endif - while (down_interruptible(&thread_sem) == 0) { + while (down_interruptible(&ppmgr_device.ppmgr_sem) == 0) { struct vframe_s *vf = NULL; if (ppmgr_device.debug_ppmgr_flag) @@ -2506,7 +2507,7 @@ static int ppmgr_task(void *data) vf = vfq_peek(&q_ready); } - up(&thread_sem); + up(&ppmgr_device.ppmgr_sem); continue; } #endif @@ -2537,7 +2538,7 @@ static int ppmgr_task(void *data) } vfq_lookup_end(&q_ready); /* EnableVideoLayer(); */ - up(&thread_sem); + up(&ppmgr_device.ppmgr_sem); continue; } @@ -2878,7 +2879,7 @@ static int ppmgr_task(void *data) &detect_status, tb_running); if (tb_buff_wptr >= 5) - up(&tb_sem); + up(&ppmgr_device.tb_sem); } } else { reset_tb = 1; @@ -2943,7 +2944,7 @@ SKIP_DETECT: vf_reg_provider(&ppmgr_vf_prov); vf_local_init(); ppmgr_blocking = false; - up(&thread_sem); + up(&ppmgr_device.ppmgr_sem); PPMGRVPP_WARN("ppmgr rebuild light-unregister_2\n"); PPMGRVPP_WARN("ppmgr, reset, free %d, avail %d\n", vfq_level(&q_free), @@ -3303,7 +3304,7 @@ int ppmgr_buffer_init(int vout_mode) ppmgr_inited = true; ppmgr_reset_type = 0; set_buff_change(0); - sema_init(&thread_sem, 1); + //up(&ppmgr_device.ppmgr_sem); return 0; } @@ -3345,7 +3346,7 @@ void stop_ppmgr_task(void) if (!IS_ERR_OR_NULL(task)) { /* send_sig(SIGTERM, task, 1); */ ppmgr_quit_flag = true; - up(&thread_sem); + up(&ppmgr_device.ppmgr_sem); kthread_stop(task); ppmgr_quit_flag = false; task = NULL; @@ -3479,9 +3480,6 @@ static int tb_buffer_uninit(void) static void tb_detect_init(void) { - int val = 0; - - sema_init(&tb_sem, val); memset(detect_buf, 0, sizeof(detect_buf)); atomic_set(&detect_status, tb_idle); atomic_set(&tb_detect_flag, TB_DETECT_NC); @@ -3524,7 +3522,7 @@ static int tb_task(void *data) if (gfunc) gfunc->stats_init(tb_reg, TB_DETECT_H, TB_DETECT_W); allow_signal(SIGTERM); - while (down_interruptible(&tb_sem) == 0) { + while (down_interruptible(&ppmgr_device.tb_sem) == 0) { if (kthread_should_stop() || tb_quit_flag) break; if (tb_buff_rptr == 0) { @@ -3634,15 +3632,13 @@ int start_tb_task(void) void stop_tb_task(void) { - int val = 0; - if (!IS_ERR_OR_NULL(tb_detect_task)) { tb_quit_flag = true; - up(&tb_sem); + up(&ppmgr_device.tb_sem); /* send_sig(SIGTERM, tb_detect_task, 1); */ kthread_stop(tb_detect_task); tb_quit_flag = false; - sema_init(&tb_sem, val); + //sema_init(&tb_sem, val); tb_detect_task = NULL; } tb_task_running = 0;