From 86e7631272eaf508401152a06c624a40849a783e Mon Sep 17 00:00:00 2001 From: Yu Qiaowei Date: Fri, 1 Apr 2022 21:33:03 +0800 Subject: [PATCH] video: rockchip: rga3: Decrement the reference of handle when the user exits Update driver version to 1.2.7 Signed-off-by: Yu Qiaowei Change-Id: Ied7a0cf3237bfbfb250791a9d0847dad3f6c41f9 --- drivers/video/rockchip/rga3/include/rga_drv.h | 5 +++- drivers/video/rockchip/rga3/include/rga_mm.h | 4 ++- drivers/video/rockchip/rga3/rga_debugger.c | 4 +-- drivers/video/rockchip/rga3/rga_drv.c | 29 ++++++++++++------ drivers/video/rockchip/rga3/rga_mm.c | 30 ++++++++++++++++++- 5 files changed, 58 insertions(+), 14 deletions(-) diff --git a/drivers/video/rockchip/rga3/include/rga_drv.h b/drivers/video/rockchip/rga3/include/rga_drv.h index 6e2799ffd222..0b3590a44f45 100644 --- a/drivers/video/rockchip/rga3/include/rga_drv.h +++ b/drivers/video/rockchip/rga3/include/rga_drv.h @@ -86,7 +86,7 @@ #define DRIVER_MAJOR_VERISON 1 #define DRIVER_MINOR_VERSION 2 -#define DRIVER_REVISION_VERSION 6 +#define DRIVER_REVISION_VERSION 7 #define DRIVER_VERSION (STR(DRIVER_MAJOR_VERISON) "." STR(DRIVER_MINOR_VERSION) \ "." STR(DRIVER_REVISION_VERSION)) @@ -227,6 +227,7 @@ struct rga_internal_buffer { uint32_t mm_flag; struct kref refcount; + struct rga_session *session; }; /* @@ -250,6 +251,8 @@ struct rga_scheduler_t; struct rga_session { int id; + + pid_t tgid; }; struct rga_job { diff --git a/drivers/video/rockchip/rga3/include/rga_mm.h b/drivers/video/rockchip/rga3/include/rga_mm.h index 60c5dbec721f..f825b2245a85 100644 --- a/drivers/video/rockchip/rga3/include/rga_mm.h +++ b/drivers/video/rockchip/rga3/include/rga_mm.h @@ -45,8 +45,10 @@ void rga_mm_dump_info(struct rga_mm *session); int rga_mm_get_handle_info(struct rga_job *job); void rga_mm_put_handle_info(struct rga_job *job); -uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer); +uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer, + struct rga_session *session); int rga_mm_release_buffer(uint32_t handle); +int rga_mm_session_release_buffer(struct rga_session *session); int rga_mm_init(struct rga_mm **session); int rga_mm_remove(struct rga_mm **session); diff --git a/drivers/video/rockchip/rga3/rga_debugger.c b/drivers/video/rockchip/rga3/rga_debugger.c index 9e88e01f288f..a67edaa0406d 100644 --- a/drivers/video/rockchip/rga3/rga_debugger.c +++ b/drivers/video/rockchip/rga3/rga_debugger.c @@ -223,9 +223,9 @@ static int rga_mm_session_show(struct seq_file *m, void *data) seq_puts(m, "===============================================================\n"); idr_for_each_entry(&mm_session->memory_idr, dump_buffer, id) { - seq_printf(m, "handle = %d refcount = %d mm_flag = 0x%x\n", + seq_printf(m, "handle = %d refcount = %d mm_flag = 0x%x tgid = %d\n", dump_buffer->handle, kref_read(&dump_buffer->refcount), - dump_buffer->mm_flag); + dump_buffer->mm_flag, dump_buffer->session->tgid); switch (dump_buffer->type) { case RGA_DMA_BUFFER: diff --git a/drivers/video/rockchip/rga3/rga_drv.c b/drivers/video/rockchip/rga3/rga_drv.c index 4cfb97162655..2951febccc64 100644 --- a/drivers/video/rockchip/rga3/rga_drv.c +++ b/drivers/video/rockchip/rga3/rga_drv.c @@ -41,7 +41,9 @@ static const struct rga_backend_ops rga2_ops = { .soft_reset = rga2_soft_reset }; -static int rga_mpi_set_channel_buffer(struct dma_buf *dma_buf, struct rga_img_info_t *channel_info) +static int rga_mpi_set_channel_buffer(struct dma_buf *dma_buf, + struct rga_img_info_t *channel_info, + struct rga_session *session) { struct rga_external_buffer buffer; @@ -51,7 +53,7 @@ static int rga_mpi_set_channel_buffer(struct dma_buf *dma_buf, struct rga_img_in buffer.memory_parm.height = channel_info->vir_h; buffer.memory_parm.format = channel_info->format; - buffer.handle = rga_mm_import_buffer(&buffer); + buffer.handle = rga_mm_import_buffer(&buffer, session); if (buffer.handle == 0) { pr_err("can not import dma_buf %p\n", dma_buf); return -EFAULT; @@ -162,7 +164,9 @@ int rga_mpi_commit(struct rga_mpi_job_t *mpi_job) /* set buffer handle */ if (mpi_job->dma_buf_src0 != NULL) { - ret = rga_mpi_set_channel_buffer(mpi_job->dma_buf_src0, &mpi_cmd.src); + ret = rga_mpi_set_channel_buffer(mpi_job->dma_buf_src0, + &mpi_cmd.src, + ctx->session); if (ret < 0) { pr_err("src channel set buffer handle failed!\n"); return ret; @@ -170,7 +174,9 @@ int rga_mpi_commit(struct rga_mpi_job_t *mpi_job) } if (mpi_job->dma_buf_src1 != NULL) { - ret = rga_mpi_set_channel_buffer(mpi_job->dma_buf_src1, &mpi_cmd.pat); + ret = rga_mpi_set_channel_buffer(mpi_job->dma_buf_src1, + &mpi_cmd.pat, + ctx->session); if (ret < 0) { pr_err("src1 channel set buffer handle failed!\n"); return ret; @@ -178,7 +184,9 @@ int rga_mpi_commit(struct rga_mpi_job_t *mpi_job) } if (mpi_job->dma_buf_dst != NULL) { - ret = rga_mpi_set_channel_buffer(mpi_job->dma_buf_dst, &mpi_cmd.dst); + ret = rga_mpi_set_channel_buffer(mpi_job->dma_buf_dst, + &mpi_cmd.dst, + ctx->session); if (ret < 0) { pr_err("dst channel set buffer handle failed!\n"); return ret; @@ -481,6 +489,8 @@ static struct rga_session *rga_session_init(void) mutex_unlock(&session_manager->lock); + session->tgid = current->tgid; + return session; } @@ -511,15 +521,16 @@ static int rga_session_deinit(struct rga_session *session) mutex_unlock(&ctx_manager->lock); - rga_session_free_remove_idr(session); rga_job_session_destroy(session); + rga_mm_session_release_buffer(session); + rga_session_free_remove_idr(session); kfree(session); return 0; } -static long rga_ioctl_import_buffer(unsigned long arg) +static long rga_ioctl_import_buffer(unsigned long arg, struct rga_session *session) { int i; int ret = 0; @@ -561,7 +572,7 @@ static long rga_ioctl_import_buffer(unsigned long arg) } for (i = 0; i < buffer_pool.size; i++) { - ret = rga_mm_import_buffer(&external_buffer[i]); + ret = rga_mm_import_buffer(&external_buffer[i], session); if (ret == 0) { pr_err("buffer[%d] mm import buffer failed! memory = 0x%lx, type = 0x%x\n", i, (unsigned long)external_buffer[i].memory, @@ -897,7 +908,7 @@ static long rga_ioctl(struct file *file, uint32_t cmd, unsigned long arg) case RGA_IOC_IMPORT_BUFFER: rga_power_enable_all(); - ret = rga_ioctl_import_buffer(arg); + ret = rga_ioctl_import_buffer(arg, session); rga_power_disable_all(); diff --git a/drivers/video/rockchip/rga3/rga_mm.c b/drivers/video/rockchip/rga3/rga_mm.c index 335ac9cdc313..4f176bf3fe9e 100644 --- a/drivers/video/rockchip/rga3/rga_mm.c +++ b/drivers/video/rockchip/rga3/rga_mm.c @@ -1089,7 +1089,8 @@ void rga_mm_put_handle_info(struct rga_job *job) rga_mm_put_channel_handle_info(mm, job->els_buffer, job, DMA_NONE); } -uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer) +uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer, + struct rga_session *session) { int ret = 0; struct rga_mm *mm; @@ -1126,6 +1127,7 @@ uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer) goto FREE_INTERNAL_BUFFER; kref_init(&internal_buffer->refcount); + internal_buffer->session = session; /* * Get the user-visible handle using idr. Preload and perform @@ -1175,6 +1177,32 @@ int rga_mm_release_buffer(uint32_t handle) return 0; } +int rga_mm_session_release_buffer(struct rga_session *session) +{ + int i; + struct rga_mm *mm; + struct rga_internal_buffer *buffer; + + mm = rga_drvdata->mm; + if (mm == NULL) { + pr_err("rga mm is null!\n"); + return -EFAULT; + } + + mutex_lock(&mm->lock); + + idr_for_each_entry(&mm->memory_idr, buffer, i) { + if (session == buffer->session) { + pr_err("[tgid:%d] Decrement the reference of handle[%d] when the user exits\n", + session->tgid, buffer->handle); + kref_put(&buffer->refcount, rga_mm_kref_release_buffer); + } + } + + mutex_unlock(&mm->lock); + return 0; +} + int rga_mm_init(struct rga_mm **mm_session) { struct rga_mm *mm = NULL;