diff options
author | Midas Chien <midaschieh@google.com> | 2022-05-26 12:22:36 +0800 |
---|---|---|
committer | susi_su <susisu@google.com> | 2022-09-14 20:22:15 +0800 |
commit | d0d4f65abe68ede4cd1c86678f8ad552ecd31817 (patch) | |
tree | 2907c78e650ff97fbb01810c00a9b0b971e6c378 | |
parent | b96583299e2dfd9c97af8de79a85c0027d78897e (diff) | |
download | display-android-gs-raviole-5.10-android13-qpr1.tar.gz |
drm: samsung: add lock when access histogram drm eventandroid-t-qpr1-beta-3_r0.4android-t-qpr1-beta-3_r0.3android-13.0.0_r0.59android-13.0.0_r0.58android-13.0.0_r0.54android-13.0.0_r0.53android-13.0.0_r0.49android-13.0.0_r0.48main-16k-gs-raviole-5.10android-gs-raviole-5.10-android13-qpr1-beta-3android-gs-raviole-5.10-android13-qpr1android-gs-bluejay-5.10-android13-qpr1-beta-3android-gs-bluejay-5.10-android13-qpr1
There is race condition problem when composer and irq thread to access
dqe->state.event. Add lock protection to avoid this problem.
Bug: 233709834
Test: enable/disable histogram
Signed-off-by: Midas Chien <midaschieh@google.com>
Change-Id: I1727622adb036cdc2bbaae4d9c15526b3e11c67f
-rw-r--r-- | samsung/exynos_drm_dqe.c | 12 | ||||
-rw-r--r-- | samsung/exynos_drm_dqe.h | 1 |
2 files changed, 12 insertions, 1 deletions
diff --git a/samsung/exynos_drm_dqe.c b/samsung/exynos_drm_dqe.c index 03851d6..2db2875 100644 --- a/samsung/exynos_drm_dqe.c +++ b/samsung/exynos_drm_dqe.c @@ -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; + unsigned long flags; obj = drm_mode_object_find(dev, file, *crtc_id, DRM_MODE_OBJECT_CRTC); if (!obj) { @@ -118,16 +119,20 @@ int histogram_request_ioctl(struct drm_device *dev, void *data, * TODO: Now only one observer is allowed at a time at the moment. * This will be allowed for multiple observer in the future. */ + spin_lock_irqsave(&dqe->state.histogram_slock, flags); if (dqe->state.event) { pr_warn("decon%u histogram already registered\n", decon->id); + 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; } + spin_unlock_irqrestore(&dqe->state.histogram_slock, flags); pr_debug("created histogram event(0x%pK) of decon%u\n", dqe->state.event, decon->id); @@ -143,6 +148,7 @@ int histogram_cancel_ioctl(struct drm_device *dev, void *data, struct decon_device *decon; struct exynos_dqe *dqe; uint32_t *crtc_id = data; + unsigned long flags; obj = drm_mode_object_find(dev, file, *crtc_id, DRM_MODE_OBJECT_CRTC); if (!obj) { @@ -160,11 +166,13 @@ int histogram_cancel_ioctl(struct drm_device *dev, void *data, return -ENODEV; } + spin_lock_irqsave(&dqe->state.histogram_slock, flags); if (dqe->state.event) { pr_debug("remained event(0x%pK)\n", dqe->state.event); drm_event_cancel_free(dev, &dqe->state.event->base); dqe->state.event = NULL; } + spin_unlock_irqrestore(&dqe->state.histogram_slock, flags); pr_debug("terminated histogram event of decon%u\n", decon->id); @@ -173,7 +181,8 @@ int histogram_cancel_ioctl(struct drm_device *dev, void *data, void handle_histogram_event(struct exynos_dqe *dqe) { - struct exynos_drm_pending_histogram_event *e = dqe->state.event; + /* This function runs in interrupt context */ + struct exynos_drm_pending_histogram_event *e; struct drm_device *dev = dqe->decon->drm_dev; uint32_t id, crtc_id; @@ -814,6 +823,7 @@ struct exynos_dqe *exynos_dqe_register(struct decon_device *decon) dqe->funcs = &dqe_funcs; dqe->initialized = false; dqe->decon = decon; + spin_lock_init(&dqe->state.histogram_slock); scnprintf(dqe_name, MAX_DQE_NAME_SIZE, "dqe%u", decon->id); dqe->dqe_class = class_create(THIS_MODULE, dqe_name); diff --git a/samsung/exynos_drm_dqe.h b/samsung/exynos_drm_dqe.h index 0d440d9..d578114 100644 --- a/samsung/exynos_drm_dqe.h +++ b/samsung/exynos_drm_dqe.h @@ -40,6 +40,7 @@ struct exynos_dqe_state { struct histogram_bins *bins; struct exynos_drm_pending_histogram_event *event; u32 histogram_threshold; + spinlock_t histogram_slock; enum exynos_prog_pos histogram_pos; bool rcd_enabled; struct drm_gem_object *cgc_gem; |