From ff2f479da9231492ee6a654eed49bca02e391999 Mon Sep 17 00:00:00 2001 From: Ding Wei Date: Tue, 18 May 2021 11:02:34 +0800 Subject: [PATCH] video: rockchip: mpp: Optimize kref_get within mem_regions tips: 1. If fd has imported, then just copy mem_regiony struct. 2. Task is the unit for running, and mem_region is the internal element of task. 3. In mem_regions, it can only kref_get once with the same fd, instead of all fds which the same fd. Change-Id: I7236803a5a263d6e79256036caf580b5ac2c35e9 Signed-off-by: Ding Wei --- drivers/video/rockchip/mpp/mpp_common.c | 20 +++++++++++--------- drivers/video/rockchip/mpp/mpp_common.h | 2 ++ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/video/rockchip/mpp/mpp_common.c b/drivers/video/rockchip/mpp/mpp_common.c index f4a33f941e2a..185076ffe901 100644 --- a/drivers/video/rockchip/mpp/mpp_common.c +++ b/drivers/video/rockchip/mpp/mpp_common.c @@ -1334,12 +1334,11 @@ mpp_task_attach_fd(struct mpp_task *task, int fd) mem_region = &task->mem_regions[task->mem_count]; if (found) { memcpy(mem_region, loop, sizeof(*loop)); - buffer = mem_region->hdl; - kref_get(&buffer->ref); + mem_region->is_dup = true; } else { - down_read(&mpp->iommu_info->rw_sem); + mpp_iommu_down_read(mpp->iommu_info); buffer = mpp_dma_import_fd(mpp->iommu_info, dma, fd); - up_read(&mpp->iommu_info->rw_sem); + mpp_iommu_up_read(mpp->iommu_info); if (IS_ERR_OR_NULL(buffer)) { mpp_err("can't import dma-buf %d\n", fd); return ERR_PTR(-ENOMEM); @@ -1349,8 +1348,10 @@ mpp_task_attach_fd(struct mpp_task *task, int fd) mem_region->iova = buffer->iova; mem_region->len = buffer->size; mem_region->fd = fd; + mem_region->is_dup = false; } task->mem_count++; + INIT_LIST_HEAD(&mem_region->reg_link); list_add_tail(&mem_region->reg_link, &task->mem_region_list); return mem_region; @@ -1545,17 +1546,18 @@ int mpp_task_finish(struct mpp_session *session, int mpp_task_finalize(struct mpp_session *session, struct mpp_task *task) { - struct mpp_dev *mpp = NULL; struct mpp_mem_region *mem_region = NULL, *n; + struct mpp_dev *mpp = session->mpp; - mpp = session->mpp; /* release memory region attach to this registers table. */ list_for_each_entry_safe(mem_region, n, &task->mem_region_list, reg_link) { - mpp_iommu_down_read(mpp->iommu_info); - mpp_dma_release(session->dma, mem_region->hdl); - mpp_iommu_up_read(mpp->iommu_info); + if (!mem_region->is_dup) { + mpp_iommu_down_read(mpp->iommu_info); + mpp_dma_release(session->dma, mem_region->hdl); + mpp_iommu_up_read(mpp->iommu_info); + } list_del_init(&mem_region->reg_link); } diff --git a/drivers/video/rockchip/mpp/mpp_common.h b/drivers/video/rockchip/mpp/mpp_common.h index 68880851a38e..1dbbe6addce3 100644 --- a/drivers/video/rockchip/mpp/mpp_common.h +++ b/drivers/video/rockchip/mpp/mpp_common.h @@ -267,6 +267,8 @@ struct mpp_mem_region { u32 reg_idx; void *hdl; int fd; + /* whether is dup import entity */ + bool is_dup; }; struct mpp_dma_session;