From ccfc068e61d666c28bd951ba01f3e5cc09106063 Mon Sep 17 00:00:00 2001 From: "hyesoo.yu" Date: Mon, 15 Jan 2018 16:44:30 +0900 Subject: [PATCH] [COMMON] g2d: release hwfc buffer when error happens Change-Id: I561e8eefdebc3dca5d60e4c7945e89e5f4121725 Signed-off-by: hyesoo.yu --- drivers/gpu/exynos/g2d/g2d_drv.c | 3 +++ drivers/gpu/exynos/g2d/g2d_task.c | 3 +++ drivers/gpu/exynos/g2d/g2d_task.h | 1 + drivers/gpu/exynos/g2d/g2d_uapi_process.c | 16 ++++++++-------- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/exynos/g2d/g2d_drv.c b/drivers/gpu/exynos/g2d/g2d_drv.c index 434817dd80b5..a3ef84183eb5 100644 --- a/drivers/gpu/exynos/g2d/g2d_drv.c +++ b/drivers/gpu/exynos/g2d/g2d_drv.c @@ -406,6 +406,9 @@ static long g2d_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ret = g2d_get_userdata(g2d_dev, ctx, task, &data); if (ret < 0) { + /* release hwfc buffer */ + if (IS_HWFC(task->flags) && (task->bufidx >= 0)) + hwfc_set_valid_buffer(task->bufidx, -1); g2d_put_free_task(g2d_dev, task); break; } diff --git a/drivers/gpu/exynos/g2d/g2d_task.c b/drivers/gpu/exynos/g2d/g2d_task.c index 1bf054dd47b7..40792662e1ee 100644 --- a/drivers/gpu/exynos/g2d/g2d_task.c +++ b/drivers/gpu/exynos/g2d/g2d_task.c @@ -352,6 +352,8 @@ void g2d_put_free_task(struct g2d_device *g2d_dev, struct g2d_task *task) spin_lock_irqsave(&g2d_dev->lock_task, flags); + task->bufidx = -1; + clear_task_state(task); if (IS_HWFC(task->flags)) { @@ -418,6 +420,7 @@ static struct g2d_task *g2d_create_task(struct g2d_device *g2d_dev, int id) } task->job_id = id; + task->bufidx = -1; task->g2d_dev = g2d_dev; ret = g2d_map_cmd_data(task); diff --git a/drivers/gpu/exynos/g2d/g2d_task.h b/drivers/gpu/exynos/g2d/g2d_task.h index b75470e17884..fa1b7b302ad3 100644 --- a/drivers/gpu/exynos/g2d/g2d_task.h +++ b/drivers/gpu/exynos/g2d/g2d_task.h @@ -89,6 +89,7 @@ struct g2d_task { unsigned int flags; unsigned int job_id; + unsigned int bufidx; unsigned long state; struct sync_file *release_fence; struct kref starter; diff --git a/drivers/gpu/exynos/g2d/g2d_uapi_process.c b/drivers/gpu/exynos/g2d/g2d_uapi_process.c index fde5b2f933e4..eebe9690fb90 100644 --- a/drivers/gpu/exynos/g2d/g2d_uapi_process.c +++ b/drivers/gpu/exynos/g2d/g2d_uapi_process.c @@ -661,7 +661,6 @@ static int g2d_get_target(struct g2d_device *g2d_dev, struct g2d_context *ctx, if (IS_HWFC(task->flags)) { struct g2d_task *ptask; unsigned long flags; - u32 idx; target->buffer_type = G2D_BUFTYPE_DMABUF; @@ -671,14 +670,14 @@ static int g2d_get_target(struct g2d_device *g2d_dev, struct g2d_context *ctx, * avoid overwriting the buffer index and job id while MFC is * running. */ - ret = hwfc_get_valid_buffer(&idx); + ret = hwfc_get_valid_buffer(&task->bufidx); if (ret < 0) { dev_err(dev, "%s: Failed to get valid buffer from repeater\n", __func__); return ret; } - BUG_ON(idx >= ctx->hwfc_info->buffer_count); + BUG_ON(task->bufidx >= ctx->hwfc_info->buffer_count); spin_lock_irqsave(&task->g2d_dev->lock_task, flags); @@ -689,10 +688,10 @@ static int g2d_get_target(struct g2d_device *g2d_dev, struct g2d_context *ctx, ptask = ptask->next; continue; } - if ((ptask->job_id == idx) && + if ((ptask->job_id == task->bufidx) && !is_task_state_idle(ptask)) { dev_err(dev, "%s: The %d task is not idle\n", - __func__, idx); + __func__, task->bufidx); spin_unlock_irqrestore( &task->g2d_dev->lock_task, flags); @@ -702,15 +701,16 @@ static int g2d_get_target(struct g2d_device *g2d_dev, struct g2d_context *ctx, ptask = ptask->next; } - g2d_stamp_task(task, G2D_STAMP_STATE_HWFCBUF, idx); + g2d_stamp_task(task, G2D_STAMP_STATE_HWFCBUF, task->bufidx); - task->job_id = idx; + task->job_id = task->bufidx; spin_unlock_irqrestore(&task->g2d_dev->lock_task, flags); data->num_buffers = 1; data->buffer[0].dmabuf.offset = 0; - data->buffer[0].length = (__u32)ctx->hwfc_info->bufs[idx]->size; + data->buffer[0].length = + (__u32)ctx->hwfc_info->bufs[task->bufidx]->size; } if (target->buffer_type == G2D_BUFTYPE_EMPTY) { -- 2.20.1