diff options
author | Midas Chien <midaschieh@google.com> | 2022-09-01 13:55:07 +0800 |
---|---|---|
committer | Midas Chien <midaschieh@google.com> | 2022-09-13 01:46:56 +0000 |
commit | 6fcc5ee410cb9a274545040ac298d2ffd8bde4ca (patch) | |
tree | b9f765dcef0190a08398996421b320b53a191f61 | |
parent | 92535c26e8e630297294bf5be7b66e0587f98484 (diff) | |
download | display-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.c | 19 |
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", |