From eb8fe01c96366b67129a0fbeb21b9cdc60581a87 Mon Sep 17 00:00:00 2001 From: Putin Lee Date: Fri, 1 Dec 2017 17:25:16 +0800 Subject: [PATCH] video/rockchip: rga: Fixup some situation will cause memory leak Change-Id: I2ec424e09149c5b4c1d6a2f141e0359e197abe35 Signed-off-by: Putin Lee --- drivers/video/rockchip/rga/rga_drv.c | 191 ++++----------------------- 1 file changed, 26 insertions(+), 165 deletions(-) diff --git a/drivers/video/rockchip/rga/rga_drv.c b/drivers/video/rockchip/rga/rga_drv.c index bbf069672ddb..26d68221c990 100755 --- a/drivers/video/rockchip/rga/rga_drv.c +++ b/drivers/video/rockchip/rga/rga_drv.c @@ -520,85 +520,6 @@ static struct rga_reg * rga_reg_init(rga_session *session, struct rga_req *req) return reg; } -static struct rga_reg * rga_reg_init_2(rga_session *session, struct rga_req *req0, struct rga_req *req1) -{ - int32_t ret; - - struct rga_reg *reg0, *reg1; - - reg0 = NULL; - reg1 = NULL; - - do - { - reg0 = kzalloc(sizeof(struct rga_reg), GFP_KERNEL); - if (NULL == reg0) { - pr_err("%s [%d] kmalloc fail in rga_reg_init\n", __FUNCTION__, __LINE__); - break; - } - - reg1 = kzalloc(sizeof(struct rga_reg), GFP_KERNEL); - if (NULL == reg1) { - pr_err("%s [%d] kmalloc fail in rga_reg_init\n", __FUNCTION__, __LINE__); - break; - } - - reg0->session = session; - INIT_LIST_HEAD(®0->session_link); - INIT_LIST_HEAD(®0->status_link); - - reg1->session = session; - INIT_LIST_HEAD(®1->session_link); - INIT_LIST_HEAD(®1->status_link); - - req0->mmu_info.mmu_flag &= (~(1 << 10)); - - if(req0->mmu_info.mmu_en) - { - ret = rga_set_mmu_info(reg0, req0); - if(ret < 0) { - printk("%s, [%d] set mmu info error \n", __FUNCTION__, __LINE__); - break; - } - } - - RGA_gen_reg_info(req0, (uint8_t *)reg0->cmd_reg); - - req1->mmu_info.mmu_flag &= (~(1 << 8)); - - if(req1->mmu_info.mmu_en) - { - ret = rga_set_mmu_info(reg1, req1); - if(ret < 0) { - printk("%s, [%d] set mmu info error \n", __FUNCTION__, __LINE__); - break; - } - } - - RGA_gen_reg_info(req1, (uint8_t *)reg1->cmd_reg); - - mutex_lock(&rga_service.lock); - list_add_tail(®0->status_link, &rga_service.waiting); - list_add_tail(®0->session_link, &session->waiting); - list_add_tail(®1->status_link, &rga_service.waiting); - list_add_tail(®1->session_link, &session->waiting); - mutex_unlock(&rga_service.lock); - - return reg1; - } - while(0); - - if(reg0 != NULL) { - kfree(reg0); - } - - if(reg1 != NULL) { - kfree(reg1); - } - - return NULL; -} - /* Caller must hold rga_service.lock */ static void rga_reg_deinit(struct rga_reg *reg) { @@ -824,42 +745,6 @@ static void rga_del_running_list_timeout(void) } } - -static void rga_mem_addr_sel(struct rga_req *req) -{ - switch(req->src.format) - { - case RK_FORMAT_YCbCr_422_SP: - break; - case RK_FORMAT_YCbCr_422_P : - break; - case RK_FORMAT_YCbCr_420_SP : - if((req->src.yrgb_addr > 0xc0000000) && (req->src.uv_addr > 0xc0000000) - && (req->dst.yrgb_addr > 0xc0000000)) - { - req->src.yrgb_addr = req->src.yrgb_addr - 0x60000000; - req->src.uv_addr = req->src.uv_addr - 0x60000000; - req->dst.yrgb_addr = req->dst.yrgb_addr - 0x60000000; - req->mmu_info.mmu_en = 0; - req->mmu_info.mmu_flag &= 0xfffe; - } - break; - case RK_FORMAT_YCbCr_420_P : - break; - case RK_FORMAT_YCrCb_422_SP : - break; - case RK_FORMAT_YCrCb_422_P : - break; - case RK_FORMAT_YCrCb_420_SP : - break; - case RK_FORMAT_YCrCb_420_P : - break; - default : - break; - } - -} - /* static int rga_convert_dma_buf(struct rga_req *req) { @@ -1052,14 +937,13 @@ static int rga_blit(rga_session *session, struct rga_req *req) int ret = -1; int num = 0; struct rga_reg *reg; - struct rga_req req2; - uint32_t saw, sah, daw, dah; + uint32_t saw, sah, daw, dah; - saw = req->src.act_w; - sah = req->src.act_h; - daw = req->dst.act_w; - dah = req->dst.act_h; + saw = req->src.act_w; + sah = req->src.act_h; + daw = req->dst.act_w; + dah = req->dst.act_h; #if RGA_TEST print_info(req); @@ -1070,67 +954,44 @@ static int rga_blit(rga_session *session, struct rga_req *req) } req->render_mode &= (~RGA_BUF_GEM_TYPE_MASK); do { - if((req->render_mode == bitblt_mode) && (((saw>>1) >= daw) || ((sah>>1) >= dah))) { - /* generate 2 cmd for pre scale */ + if (((saw >> 1) >= daw) || ((sah >> 1) >= dah)) { + pr_err("unsupported to scaling less than 1/2 \n"); + goto err_put_dma_buf; + } - ret = rga_check_param(req); - if(ret == -EINVAL) { - printk("req 0 argument is inval\n"); - break; - } + if (((daw >> 3) >= saw) || ((dah >> 3) >= daw)) { + pr_err("unsupported to scaling more than 8 \n"); + goto err_put_dma_buf; + } - ret = RGA_gen_two_pro(req, &req2); - if(ret == -EINVAL) { - break; - } - ret = rga_check_param(req); - if(ret == -EINVAL) { - printk("req 1 argument is inval\n"); - break; - } - - ret = rga_check_param(&req2); - if(ret == -EINVAL) { - printk("req 2 argument is inval\n"); - break; - } - - reg = rga_reg_init_2(session, req, &req2); - if(reg == NULL) { - break; - } - num = 2; - - } - else { /* check value if legal */ ret = rga_check_param(req); if(ret == -EINVAL) { printk("req argument is inval\n"); - break; + goto err_put_dma_buf; } - if(req->render_mode == bitblt_mode) - rga_mem_addr_sel(req); - reg = rga_reg_init(session, req); if(reg == NULL) { - pr_err("init reg fail\n"); - break; + pr_err("init reg fail\n"); + goto err_put_dma_buf; } + num = 1; - } - mutex_lock(&rga_service.lock); - atomic_add(num, &rga_service.total_running); - rga_try_set_reg(); - mutex_unlock(&rga_service.lock); + mutex_lock(&rga_service.lock); + atomic_add(num, &rga_service.total_running); + rga_try_set_reg(); + mutex_unlock(&rga_service.lock); - return 0; - } + return 0; + } while(0); +err_put_dma_buf: + rga_put_dma_buf(req, NULL); + return -EFAULT; }