summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMidas Chien <midaschieh@google.com>2021-08-23 17:47:26 +0800
committerMidas Chien <midaschieh@google.com>2021-08-25 11:54:37 +0000
commite5fe960a51966176faef121296591f5c0443c6ac (patch)
tree4bd9525022843938d6978826aa1c9dd129fca794
parent93e776fe096c8ec179349004ef53f809502e1630 (diff)
downloaddisplay-e5fe960a51966176faef121296591f5c0443c6ac.tar.gz
drm: samsung: move recovery work out of decon kthread
There is potential deadlock issue if recovery work is executed in decon kthread. It happens when there is new commit comes and recovery work is scheduled to execute in decon kthread. At this moment, recovery work is waiting new commit hw done but new commit is not able to execute on decon kthread. To avoid this deadlock, move recovery work to different thread to free decon kthread to execute new commit. HWC | decon kthread -------------------------|------------------------------- atomic commit#1 | (queue to decon kthread) | | handle atomic commit#1 | atomic commit#2 | timeout, trigger recovery work (queue to decon kthread) | (queue to decon kthread) | | execute recovery work | (wait commit#2 hw done) | atomic commit#3 | (wait recovery work | release lock) | Bug: 197217227 Test: stress test on recovery path Signed-off-by: Midas Chien <midaschieh@google.com> Change-Id: I0806c1a85668eba83aae66cb3a88728247c298d2
-rw-r--r--samsung/exynos_drm_decon.h2
-rw-r--r--samsung/exynos_drm_recovery.c8
-rw-r--r--samsung/exynos_drm_recovery.h2
3 files changed, 6 insertions, 6 deletions
diff --git a/samsung/exynos_drm_decon.h b/samsung/exynos_drm_decon.h
index 6592e59..6fbc2be 100644
--- a/samsung/exynos_drm_decon.h
+++ b/samsung/exynos_drm_decon.h
@@ -563,7 +563,7 @@ static inline void decon_trigger_recovery(struct decon_device *decon)
struct exynos_recovery *recovery = &decon->recovery;
atomic_inc(&recovery->recovering);
- kthread_queue_work(&decon->worker, &recovery->work);
+ queue_work(system_highpri_wq, &recovery->work);
}
#endif /* __EXYNOS_DRM_DECON_H__ */
diff --git a/samsung/exynos_drm_recovery.c b/samsung/exynos_drm_recovery.c
index e56b753..093a1ba 100644
--- a/samsung/exynos_drm_recovery.c
+++ b/samsung/exynos_drm_recovery.c
@@ -28,7 +28,7 @@
#include "exynos_drm_decon.h"
#include "exynos_drm_recovery.h"
-static void exynos_recovery_handler(struct kthread_work *work)
+static void exynos_recovery_handler(struct work_struct *work)
{
struct exynos_recovery *recovery = container_of(work,
struct exynos_recovery, work);
@@ -45,7 +45,7 @@ static void exynos_recovery_handler(struct kthread_work *work)
struct drm_plane_state *plane_state;
int ret, i;
- pr_debug("starting recovery...\n");
+ pr_info("starting recovery...\n");
drm_modeset_acquire_init(&ctx, 0);
@@ -108,7 +108,7 @@ retry:
goto out;
recovery->count++;
- pr_debug("recovery is successfully finished(%d)\n", recovery->count);
+ pr_info("recovery is successfully finished(%d)\n", recovery->count);
out:
if (ret == -EDEADLK) {
@@ -132,7 +132,7 @@ void exynos_recovery_register(struct decon_device *decon)
{
struct exynos_recovery *recovery = &decon->recovery;
- kthread_init_work(&recovery->work, exynos_recovery_handler);
+ INIT_WORK(&recovery->work, exynos_recovery_handler);
recovery->count = 0;
atomic_set(&recovery->recovering, 0);
diff --git a/samsung/exynos_drm_recovery.h b/samsung/exynos_drm_recovery.h
index 6d27b2c..35cb224 100644
--- a/samsung/exynos_drm_recovery.h
+++ b/samsung/exynos_drm_recovery.h
@@ -19,7 +19,7 @@
struct decon_device;
struct exynos_recovery {
- struct kthread_work work;
+ struct work_struct work;
int count;
atomic_t recovering;
};