summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMidas Chien <midaschieh@google.com>2022-09-01 13:55:07 +0800
committerMidas Chien <midaschieh@google.com>2022-09-13 01:46:56 +0000
commit6fcc5ee410cb9a274545040ac298d2ffd8bde4ca (patch)
treeb9f765dcef0190a08398996421b320b53a191f61
parent92535c26e8e630297294bf5be7b66e0587f98484 (diff)
downloaddisplay-6fcc5ee410cb9a274545040ac298d2ffd8bde4ca.tar.gz
drm: samsung: avoid do non-ATOMIC allocation in spin lock
In spin lock region, preempt is disabled. If sleep happens in this condition, it may cause deadlock. When doing non-ATOMIC allocation, it may go to sleep for reclaim memory. Move non-ATOMIC allocation out of spin lock region. Bug: 233709834 Test: historgam Signed-off-by: Midas Chien <midaschieh@google.com> Change-Id: I4fb3a37816e0a18e042763d79f3ebe2963b737eb
-rw-r--r--samsung/exynos_drm_dqe.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/samsung/exynos_drm_dqe.c b/samsung/exynos_drm_dqe.c
index 0d0f1d1..ee7116f 100644
--- a/samsung/exynos_drm_dqe.c
+++ b/samsung/exynos_drm_dqe.c
@@ -75,7 +75,7 @@ static struct exynos_drm_pending_histogram_event *create_histogram_event(
e = kzalloc(sizeof(*e), GFP_KERNEL);
if (!e)
- return NULL;
+ return ERR_PTR(-ENOMEM);
e->event.base.type = EXYNOS_DRM_HISTOGRAM_EVENT;
e->event.base.length = sizeof(e->event);
@@ -97,6 +97,7 @@ int histogram_request_ioctl(struct drm_device *dev, void *data,
struct decon_device *decon;
struct exynos_dqe *dqe;
uint32_t *crtc_id = data;
+ struct exynos_drm_pending_histogram_event *e;
unsigned long flags;
obj = drm_mode_object_find(dev, file, *crtc_id, DRM_MODE_OBJECT_CRTC);
@@ -115,6 +116,13 @@ int histogram_request_ioctl(struct drm_device *dev, void *data,
return -ENODEV;
}
+
+ e = create_histogram_event(dev, file);
+ if (IS_ERR(e)) {
+ pr_err("failed to create a histogram event\n");
+ return PTR_ERR(e);
+ }
+
/*
* TODO: Now only one observer is allowed at a time at the moment.
* This will be allowed for multiple observer in the future.
@@ -122,16 +130,11 @@ int histogram_request_ioctl(struct drm_device *dev, void *data,
spin_lock_irqsave(&dqe->state.histogram_slock, flags);
if (dqe->state.event) {
pr_warn("decon%u histogram already registered\n", decon->id);
+ drm_event_cancel_free(dev, &e->base);
spin_unlock_irqrestore(&dqe->state.histogram_slock, flags);
return -EBUSY;
}
- dqe->state.event = create_histogram_event(dev, file);
- if (IS_ERR_OR_NULL(dqe->state.event)) {
- dqe->state.event = NULL;
- pr_err("failed to create a histogram event\n");
- spin_unlock_irqrestore(&dqe->state.histogram_slock, flags);
- return -EINVAL;
- }
+ dqe->state.event = e;
spin_unlock_irqrestore(&dqe->state.histogram_slock, flags);
pr_debug("created histogram event(0x%pK) of decon%u\n",