From b015cebfc92b0e0f9cbc388a7d12fb8d75df149e Mon Sep 17 00:00:00 2001 From: "haitao.liu" Date: Tue, 27 Feb 2024 17:37:19 +0800 Subject: [PATCH] vdin: optimize the scatter memory flow [1/1] PD#SWPL-159339 Problem: Vdin failed to allocate scatter memory,and did not check the return value.This may cause system crash. Solution: Donot use the memory if allocating memory failed Verify: T5m Change-Id: I1b400626a67e7aee01304266f3d4de9776187624 Signed-off-by: haitao.liu --- drivers/media/vin/tvin/vdin/vdin_afbce.c | 3 +- drivers/media/vin/tvin/vdin/vdin_ctl.c | 6 ++-- drivers/media/vin/tvin/vdin/vdin_ctl_s5.c | 8 ++--- drivers/media/vin/tvin/vdin/vdin_ctl_t3x.c | 2 +- drivers/media/vin/tvin/vdin/vdin_debug.c | 4 +-- drivers/media/vin/tvin/vdin/vdin_drv.c | 8 ++--- drivers/media/vin/tvin/vdin/vdin_drv.h | 2 +- .../media/vin/tvin/vdin/vdin_mem_scatter.c | 33 ++++++++++++++----- .../media/vin/tvin/vdin/vdin_mem_scatter.h | 2 +- 9 files changed, 40 insertions(+), 28 deletions(-) diff --git a/drivers/media/vin/tvin/vdin/vdin_afbce.c b/drivers/media/vin/tvin/vdin/vdin_afbce.c index a9d00e298..87102e40a 100644 --- a/drivers/media/vin/tvin/vdin/vdin_afbce.c +++ b/drivers/media/vin/tvin/vdin/vdin_afbce.c @@ -691,8 +691,7 @@ void vdin_afbce_set_next_frame(struct vdin_dev_s *devp, rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 1, AFBCE_START_PULSE_BIT, AFBCE_START_PULSE_WID); - if (devp->pause_dec || devp->msct_top.sct_pause_dec || - devp->debug.pause_afbce_dec) + if (devp->pause_dec || devp->debug.pause_afbce_dec) rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 0, AFBCE_EN_BIT, AFBCE_EN_WID); else diff --git a/drivers/media/vin/tvin/vdin/vdin_ctl.c b/drivers/media/vin/tvin/vdin/vdin_ctl.c index 3af63f6d5..152ed1971 100644 --- a/drivers/media/vin/tvin/vdin/vdin_ctl.c +++ b/drivers/media/vin/tvin/vdin/vdin_ctl.c @@ -2814,7 +2814,7 @@ void vdin_set_canvas_id(struct vdin_dev_s *devp, unsigned int rdma_enable, VDIN_WR_CTRL + devp->addr_offset, canvas_id, WR_CANVAS_BIT, WR_CANVAS_WID); - if (devp->pause_dec || devp->msct_top.sct_pause_dec || devp->debug.pause_mif_dec) + if (devp->pause_dec || devp->debug.pause_mif_dec) rdma_write_reg_bits(devp->rdma_handle, VDIN_WR_CTRL + devp->addr_offset, 0, WR_REQ_EN_BIT, WR_REQ_EN_WID); else @@ -2825,7 +2825,7 @@ void vdin_set_canvas_id(struct vdin_dev_s *devp, unsigned int rdma_enable, wr_bits(devp->addr_offset, VDIN_WR_CTRL, canvas_id, WR_CANVAS_BIT, WR_CANVAS_WID); - if (devp->pause_dec || devp->msct_top.sct_pause_dec || devp->debug.pause_mif_dec) + if (devp->pause_dec || devp->debug.pause_mif_dec) wr_bits(devp->addr_offset, VDIN_WR_CTRL, 0, WR_REQ_EN_BIT, WR_REQ_EN_WID); else @@ -4288,7 +4288,7 @@ bool vdin_write_done_check(unsigned int offset, struct vdin_dev_s *devp) /* If write ddr paused,donot checking write done */ if (devp->debug.pause_mif_dec || devp->debug.pause_afbce_dec || - devp->pause_dec || devp->msct_top.sct_pause_dec) + devp->pause_dec) return true; #ifndef CONFIG_AMLOGIC_ZAPPER_CUT diff --git a/drivers/media/vin/tvin/vdin/vdin_ctl_s5.c b/drivers/media/vin/tvin/vdin/vdin_ctl_s5.c index b86c96351..8db9ee3d2 100644 --- a/drivers/media/vin/tvin/vdin/vdin_ctl_s5.c +++ b/drivers/media/vin/tvin/vdin/vdin_ctl_s5.c @@ -2138,7 +2138,7 @@ void vdin_set_frame_mif_write_addr_s5(struct vdin_dev_s *devp, VDIN_WRMIF_STRIDE_CHROMA + devp->addr_offset, stride_chroma); } - if (devp->pause_dec || devp->msct_top.sct_pause_dec) + if (devp->pause_dec) rdma_write_reg_bits(devp->rdma_handle, VDIN_WRMIF_CTRL + devp->addr_offset, 0, WR_REQ_EN_BIT, WR_REQ_EN_WID); @@ -2156,7 +2156,7 @@ void vdin_set_frame_mif_write_addr_s5(struct vdin_dev_s *devp, wr(devp->addr_offset, VDIN_WRMIF_STRIDE_CHROMA, stride_chroma); } - if (devp->pause_dec || devp->msct_top.sct_pause_dec) + if (devp->pause_dec) wr_bits(devp->addr_offset, VDIN_WRMIF_CTRL, 0, WR_REQ_EN_BIT, WR_REQ_EN_WID); else @@ -2217,7 +2217,7 @@ void vdin_set_canvas_id_s5(struct vdin_dev_s *devp, unsigned int rdma_enable, VDIN_WRMIF_CTRL + devp->addr_offset, canvas_id, WR_CANVAS_BIT, WR_CANVAS_WID); - if (devp->pause_dec || devp->msct_top.sct_pause_dec) + if (devp->pause_dec) rdma_write_reg_bits(devp->rdma_handle, VDIN_WRMIF_CTRL + devp->addr_offset, 0, WR_REQ_EN_BIT, WR_REQ_EN_WID); else @@ -2228,7 +2228,7 @@ void vdin_set_canvas_id_s5(struct vdin_dev_s *devp, unsigned int rdma_enable, wr_bits(devp->addr_offset, VDIN_WRMIF_CTRL, canvas_id, WR_CANVAS_BIT, WR_CANVAS_WID); - if (devp->pause_dec || devp->msct_top.sct_pause_dec) + if (devp->pause_dec) wr_bits(devp->addr_offset, VDIN_WRMIF_CTRL, 0, WR_REQ_EN_BIT, WR_REQ_EN_WID); else diff --git a/drivers/media/vin/tvin/vdin/vdin_ctl_t3x.c b/drivers/media/vin/tvin/vdin/vdin_ctl_t3x.c index 7a5a10798..09adb60b0 100644 --- a/drivers/media/vin/tvin/vdin/vdin_ctl_t3x.c +++ b/drivers/media/vin/tvin/vdin/vdin_ctl_t3x.c @@ -1934,7 +1934,7 @@ void vdin_set_frame_mif_write_addr_t3x(struct vdin_dev_s *devp, stride_luma, stride_chroma); } - if (devp->pause_dec || devp->debug.pause_mif_dec || devp->msct_top.sct_pause_dec) + if (devp->pause_dec || devp->debug.pause_mif_dec) reg_en = false; if (rdma_enable) { diff --git a/drivers/media/vin/tvin/vdin/vdin_debug.c b/drivers/media/vin/tvin/vdin/vdin_debug.c index 3a050e9d1..adbc8f02f 100644 --- a/drivers/media/vin/tvin/vdin/vdin_debug.c +++ b/drivers/media/vin/tvin/vdin/vdin_debug.c @@ -4853,11 +4853,11 @@ static void vdin_dump_sct_state(struct vdin_dev_s *devp) struct vdin_mmu_box *box = NULL; pr_info("mem_type:%d\n", devp->mem_type); - pr_info("irq:%d,frm:%d,que:%d,run:%d,pause:%d,af_num:%d\n", + pr_info("irq:%d,frm:%d,que:%d,run:%d,af_num:%d\n", devp->irq_cnt, devp->frame_cnt, devp->msct_top.que_work_cnt, devp->msct_top.worker_run_cnt, - devp->msct_top.sct_pause_dec, devp->af_num); + devp->af_num); pr_info("pool,size:%d,wr_list:%d,wr_mode:%d,rd_list:%d,rd_mode:%d\n", devp->vfp->size, devp->vfp->wr_list_size, diff --git a/drivers/media/vin/tvin/vdin/vdin_drv.c b/drivers/media/vin/tvin/vdin/vdin_drv.c index 9c6d9b3fd..4f1a9235b 100644 --- a/drivers/media/vin/tvin/vdin/vdin_drv.c +++ b/drivers/media/vin/tvin/vdin/vdin_drv.c @@ -1573,6 +1573,7 @@ void vdin_stop_dec(struct vdin_dev_s *devp) pr_err("%s vdin%d not enable\n", __func__, devp->index); return; } + devp->msct_top.sct_stop_flag = true; #ifdef CONFIG_CMA if (devp->cma_mem_alloc == 0 && devp->cma_config_en && @@ -2758,8 +2759,8 @@ int vdin_vframe_put_and_recycle(struct vdin_dev_s *devp, struct vf_entry *vfe, devp->vfp->last_last_vfe->vf.index, devp->vfp->last_last_vfe->vf.signal_type, devp->vfp->last_last_vfe->vf.type, - devp->vfp->last_last_vfe->vf.flag, devp->vfp->last_last_vfe->flag, + devp->vfp->last_last_vfe->vf.flag, devp->vfp->last_last_vfe->vf.duration, devp->vfp->last_last_vfe->vf.index_disp); @@ -3471,13 +3472,10 @@ irqreturn_t vdin_isr(int irq, void *dev_id) spin_lock_irqsave(&devp->vfp->wr_lock, wr_list_flags); if (next_wr_vfe->sct_stat != VFRAME_SCT_STATE_FULL) { spin_unlock_irqrestore(&devp->vfp->wr_lock, wr_list_flags); - devp->msct_top.sct_pause_dec = true; devp->vdin_irq_flag = VDIN_IRQ_FLG_NO_NEXT_FE; vdin_drop_frame_info(devp, "sct no next wr vfe"); - vdin_pause_hw_write(devp, 0); + vdin_pause_hw_write(devp, devp->flags & VDIN_FLAG_RDMA_ENABLE); goto irq_handled; - } else if (devp->msct_top.sct_pause_dec) { - devp->msct_top.sct_pause_dec = false; } spin_unlock_irqrestore(&devp->vfp->wr_lock, wr_list_flags); } diff --git a/drivers/media/vin/tvin/vdin/vdin_drv.h b/drivers/media/vin/tvin/vdin/vdin_drv.h index 34dde6ed2..07e2f16b8 100644 --- a/drivers/media/vin/tvin/vdin/vdin_drv.h +++ b/drivers/media/vin/tvin/vdin/vdin_drv.h @@ -782,7 +782,7 @@ struct vdin_msct_top_s { unsigned int mmu_4k_number; /* mmu 4k number in full size */ unsigned int buffer_size_nub; /* 4k number per frame */ unsigned int tail_cnt; - bool sct_pause_dec; /* pause dec flag on sct mem */ + bool sct_stop_flag; /* statistics info*/ unsigned int que_work_cnt; unsigned int worker_run_cnt; diff --git a/drivers/media/vin/tvin/vdin/vdin_mem_scatter.c b/drivers/media/vin/tvin/vdin/vdin_mem_scatter.c index 91084a663..7af6bdd2e 100644 --- a/drivers/media/vin/tvin/vdin/vdin_mem_scatter.c +++ b/drivers/media/vin/tvin/vdin/vdin_mem_scatter.c @@ -121,6 +121,8 @@ void vdin_sct_read_mmu_num(struct vdin_dev_s *devp, struct vf_entry *vfe) int vdin_sct_start(struct vdin_dev_s *devp) { + int retry = 3, ret = 0; + struct vf_entry *vfe = NULL; if (devp->mem_type != VDIN_MEM_TYPE_SCT) @@ -140,13 +142,20 @@ int vdin_sct_start(struct vdin_dev_s *devp) pr_info("%s vdin%d:peek vframe failed\n", __func__, devp->index); return -1; } - vdin_sct_alloc(devp, vfe->vf.index); - vfe->sct_stat = VFRAME_SCT_STATE_FULL; + while (retry--) { + ret = vdin_sct_alloc(devp, vfe->vf.index); + if (ret >= 0) { + vfe->sct_stat = VFRAME_SCT_STATE_FULL; + break; + } + pr_info("%s vdin%d:alloc sct failed,retry=%d\n", __func__, devp->index, retry); + msleep(50); + } return 0; } -void vdin_sct_alloc(struct vdin_dev_s *devp, int vf_idx) +int vdin_sct_alloc(struct vdin_dev_s *devp, int vf_idx) { int ret; unsigned int page_idx; @@ -182,6 +191,7 @@ void vdin_sct_alloc(struct vdin_dev_s *devp, int vf_idx) pr_info("%s:use %u us\n", __func__, (unsigned int)diff); if (diff > 10000) pr_info("%s:takes %llu us,too long\n", __func__, diff); + return ret; } void vdin_sct_free_tail(struct vdin_dev_s *devp, int vf_idx, int buffer_used) @@ -355,6 +365,7 @@ void vdin_sct_free_idx_in_game(struct vdin_dev_s *devp) void vdin_sct_worker(struct work_struct *work) { + int ret = 0; struct vf_entry *vfe = NULL, *next_wr_vfe = NULL; struct vdin_dev_s *devp = @@ -368,6 +379,10 @@ void vdin_sct_worker(struct work_struct *work) pr_err("%s vdin%d,afbce_info == NULL!!!\n", __func__, devp->index); return; } + if (devp->msct_top.sct_stop_flag) { + pr_info("%s vdin%d in stop process!!!\n", __func__, devp->index); + return; + } /* alloc memory may take same time,save the captured vfe first */ vfe = devp->msct_top.vfe; devp->msct_top.vfe = NULL; @@ -391,8 +406,9 @@ void vdin_sct_worker(struct work_struct *work) next_wr_vfe->vf.mem_handle); //this memory is used for every vf in one buffer mode,donot alloc again or free it if (next_wr_vfe->vf.index != devp->af_num) { - vdin_sct_alloc(devp, next_wr_vfe->vf.index); - next_wr_vfe->sct_stat = VFRAME_SCT_STATE_FULL; + ret = vdin_sct_alloc(devp, next_wr_vfe->vf.index); + if (ret >= 0) + next_wr_vfe->sct_stat = VFRAME_SCT_STATE_FULL; } next_wr_vfe->vf.afbce_num = 0; @@ -445,7 +461,6 @@ int vdin_mem_init(struct vdin_dev_s *devp) devp->index || !is_afbce || !(devp->cma_config_flag & MEM_ALLOC_CODEC_SCT)) { devp->mem_type = VDIN_MEM_TYPE_CONTINUOUS; - devp->msct_top.sct_pause_dec = false; pr_info("%s,vdin%d do not use scatter memory;is_afbce:%d,cma_flag:%#x\n", __func__, devp->index, is_afbce, devp->cma_config_flag); return 0; @@ -486,14 +501,14 @@ int vdin_mem_exit(struct vdin_dev_s *devp) if (devp->mem_type != VDIN_MEM_TYPE_SCT) return 0; + flush_workqueue(devp->wq); + destroy_workqueue(devp->wq); + for (i = 0; i < devp->vfp->size; i++) vdin_sct_free(devp->vfp, i); vdin_sct_release(devp); - flush_workqueue(devp->wq); - destroy_workqueue(devp->wq); - devp->frame_buff_num = devp->frame_buff_num_bak; if (sct_print_ctl & SCT_PRINT_CTL_EXIT) diff --git a/drivers/media/vin/tvin/vdin/vdin_mem_scatter.h b/drivers/media/vin/tvin/vdin/vdin_mem_scatter.h index 47ad8cc9e..ec92b7543 100644 --- a/drivers/media/vin/tvin/vdin/vdin_mem_scatter.h +++ b/drivers/media/vin/tvin/vdin/vdin_mem_scatter.h @@ -25,7 +25,7 @@ int vdin_sct_init(struct vdin_dev_s *devp); void vdin_sct_worker(struct work_struct *work); -void vdin_sct_alloc(struct vdin_dev_s *devp, int vf_idx); +int vdin_sct_alloc(struct vdin_dev_s *devp, int vf_idx); int vdin_sct_start(struct vdin_dev_s *devp); void vdin_sct_queue_work(struct vdin_dev_s *devp); void vdin_sct_free(struct vf_pool *p, int index);