From 310cad87e0d431e8c25ee29ec41fccbb342f5e51 Mon Sep 17 00:00:00 2001 From: Yu Qiaowei Date: Fri, 26 Jul 2024 11:48:56 +0800 Subject: [PATCH] video: rockchip: rga3: add commit work in fence callback To avoid the caller signaling acquire_fence in some special cases (e.g. interruptions), use the work queue to execute 'request_commit'. Signed-off-by: Yu Qiaowei Change-Id: Ibec2c8a7f5b5bd3e99d9109793561f28bfb7d4ac --- drivers/video/rockchip/rga3/include/rga_drv.h | 1 + drivers/video/rockchip/rga3/rga_job.c | 23 +++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/video/rockchip/rga3/include/rga_drv.h b/drivers/video/rockchip/rga3/include/rga_drv.h index 3daf623c339e..2ef48e8c469a 100644 --- a/drivers/video/rockchip/rga3/include/rga_drv.h +++ b/drivers/video/rockchip/rga3/include/rga_drv.h @@ -366,6 +366,7 @@ struct rga_request { int32_t release_fence_fd; struct dma_fence *release_fence; spinlock_t fence_lock; + struct work_struct fence_work; wait_queue_head_t finished_wq; diff --git a/drivers/video/rockchip/rga3/rga_job.c b/drivers/video/rockchip/rga3/rga_job.c index 7ecad88341b6..809006a2bc2b 100644 --- a/drivers/video/rockchip/rga3/rga_job.c +++ b/drivers/video/rockchip/rga3/rga_job.c @@ -930,14 +930,12 @@ int rga_request_commit(struct rga_request *request) return 0; } -static void rga_request_acquire_fence_signaled_cb(struct dma_fence *fence, - struct dma_fence_cb *_waiter) +static void rga_request_acquire_fence_work(struct work_struct *work) { int ret; unsigned long flags; struct mm_struct *current_mm; - struct rga_fence_waiter *waiter = (struct rga_fence_waiter *)_waiter; - struct rga_request *request = (struct rga_request *)waiter->private; + struct rga_request *request = container_of(work, struct rga_request, fence_work); struct rga_pending_request_manager *request_manager = rga_drvdata->pend_request_manager; ret = rga_request_commit(request); @@ -954,18 +952,22 @@ static void rga_request_acquire_fence_signaled_cb(struct dma_fence *fence, rga_request_put_current_mm(current_mm); - /* - * Since the callback is called while holding &dma_fence.lock, - * the _locked API is used here. - */ - if (dma_fence_get_status_locked(request->release_fence) == 0) - dma_fence_signal_locked(request->release_fence); + if (rga_dma_fence_get_status(request->release_fence) == 0) + rga_dma_fence_signal(request->release_fence, ret); } mutex_lock(&request_manager->lock); rga_request_put(request); mutex_unlock(&request_manager->lock); +} +static void rga_request_acquire_fence_signaled_cb(struct dma_fence *fence, + struct dma_fence_cb *_waiter) +{ + struct rga_fence_waiter *waiter = (struct rga_fence_waiter *)_waiter; + struct rga_request *request = (struct rga_request *)waiter->private; + + queue_work(system_highpri_wq, &request->fence_work); kfree(waiter); } @@ -1224,6 +1226,7 @@ int rga_request_submit(struct rga_request *request) request->release_fence = release_fence; if (request->acquire_fence_fd > 0) { + INIT_WORK(&request->fence_work, rga_request_acquire_fence_work); ret = rga_request_add_acquire_fence_callback( request->acquire_fence_fd, request, rga_request_acquire_fence_signaled_cb);