diff --git a/drivers/video/rockchip/rga3/rga_job.c b/drivers/video/rockchip/rga3/rga_job.c index 0093aa2f7c2f..fbe4535a081b 100644 --- a/drivers/video/rockchip/rga3/rga_job.c +++ b/drivers/video/rockchip/rga3/rga_job.c @@ -848,12 +848,28 @@ int rga_request_commit(struct rga_request *request) static void rga_request_acquire_fence_signaled_cb(struct dma_fence *fence, struct dma_fence_cb *_waiter) { + int ret; + unsigned long flags; struct rga_fence_waiter *waiter = (struct rga_fence_waiter *)_waiter; struct rga_request *request = (struct rga_request *)waiter->private; struct rga_pending_request_manager *request_manager = rga_drvdata->pend_request_manager; - if (rga_request_commit(request)) - pr_err("rga request[%d] commit failed!\n", request->id); + ret = rga_request_commit(request); + if (ret < 0) { + pr_err("acquire_fence callback: rga request[%d] commit failed!\n", request->id); + + spin_lock_irqsave(&request->lock, flags); + rga_request_put_current_mm(request); + request->is_running = false; + spin_unlock_irqrestore(&request->lock, flags); + + /* + * 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); + } mutex_lock(&request_manager->lock); rga_request_put(request);