From 04790c5a35d1c42b70525622359ce3f4d279b9e5 Mon Sep 17 00:00:00 2001 From: "hyesoo.yu" Date: Tue, 3 Apr 2018 19:25:30 +0900 Subject: [PATCH] [COMMON] g2d: split timer as purpose One timer is used for two purposes, but it may cause unexpected race condition between timer handler and deletion, initialization for another purpose. So, we seperate timers into two for each purpose. Change-Id: I44831a4a7b663d75c5d5d4297a78e245f3b4d3ef Signed-off-by: hyesoo.yu --- drivers/gpu/exynos/g2d/g2d_drv.c | 2 +- drivers/gpu/exynos/g2d/g2d_task.c | 30 +++++++++++++++--------------- drivers/gpu/exynos/g2d/g2d_task.h | 3 ++- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/exynos/g2d/g2d_drv.c b/drivers/gpu/exynos/g2d/g2d_drv.c index 178458c7e590..e0d90217a644 100644 --- a/drivers/gpu/exynos/g2d/g2d_drv.c +++ b/drivers/gpu/exynos/g2d/g2d_drv.c @@ -111,7 +111,7 @@ void g2d_hw_timeout_handler(unsigned long arg) goto out; } - mod_timer(&task->timer, + mod_timer(&task->hw_timer, jiffies + msecs_to_jiffies(G2D_HW_TIMEOUT_MSEC)); if (!g2d_hw_stuck_state(g2d_dev) && diff --git a/drivers/gpu/exynos/g2d/g2d_task.c b/drivers/gpu/exynos/g2d/g2d_task.c index 40792662e1ee..c4b84976355f 100644 --- a/drivers/gpu/exynos/g2d/g2d_task.c +++ b/drivers/gpu/exynos/g2d/g2d_task.c @@ -113,7 +113,7 @@ static void g2d_finish_task(struct g2d_device *g2d_dev, task->ktime_end = ktime_get(); - del_timer(&task->timer); + del_timer(&task->hw_timer); g2d_stamp_task(task, G2D_STAMP_STATE_DONE, (int)ktime_us_delta(task->ktime_end, task->ktime_begin)); @@ -171,13 +171,9 @@ static void g2d_execute_task(struct g2d_device *g2d_dev, struct g2d_task *task) list_move_tail(&task->node, &g2d_dev->tasks_active); change_task_state_active(task); - del_timer(&task->timer); - - setup_timer(&task->timer, - g2d_hw_timeout_handler, (unsigned long)task); - - mod_timer(&task->timer, - jiffies + msecs_to_jiffies(G2D_HW_TIMEOUT_MSEC)); + task->hw_timer.expires = + jiffies + msecs_to_jiffies(G2D_HW_TIMEOUT_MSEC); + add_timer(&task->hw_timer); /* * g2d_device_run() is not reentrant while g2d_schedule() is @@ -225,7 +221,7 @@ static void g2d_schedule_task(struct g2d_task *task) unsigned long flags; int ret; - del_timer(&task->timer); + del_timer(&task->fence_timer); g2d_complete_commands(task); @@ -286,12 +282,11 @@ void g2d_start_task(struct g2d_task *task) { reinit_completion(&task->completion); - setup_timer(&task->timer, - g2d_fence_timeout_handler, (unsigned long)task); - - if (atomic_read(&task->starter.refcount.refs) > 1) - mod_timer(&task->timer, - jiffies + msecs_to_jiffies(G2D_FENCE_TIMEOUT_MSEC)); + if (atomic_read(&task->starter.refcount.refs) > 1) { + task->fence_timer.expires = + jiffies + msecs_to_jiffies(G2D_FENCE_TIMEOUT_MSEC); + add_timer(&task->fence_timer); + } task->ktime_begin = ktime_get(); @@ -434,6 +429,11 @@ static struct g2d_task *g2d_create_task(struct g2d_device *g2d_dev, int id) init_completion(&task->completion); spin_lock_init(&task->fence_timeout_lock); + setup_timer(&task->hw_timer, + g2d_hw_timeout_handler, (unsigned long)task); + setup_timer(&task->fence_timer, + g2d_fence_timeout_handler, (unsigned long)task); + return task; err_map: diff --git a/drivers/gpu/exynos/g2d/g2d_task.h b/drivers/gpu/exynos/g2d/g2d_task.h index fa1b7b302ad3..f6e0ef2e8ffe 100644 --- a/drivers/gpu/exynos/g2d/g2d_task.h +++ b/drivers/gpu/exynos/g2d/g2d_task.h @@ -93,7 +93,8 @@ struct g2d_task { unsigned long state; struct sync_file *release_fence; struct kref starter; - struct timer_list timer; + struct timer_list fence_timer; + struct timer_list hw_timer; struct g2d_layer *source; struct g2d_layer target; -- 2.20.1