Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 286a52ba authored by Narendra Muppalla's avatar Narendra Muppalla Committed by Gerrit - the friendly Code Review server
Browse files

disp: msm: sde: use different spin lock for frame events



Due to lock sequence inconsistency between sde_crtc->spin_lock and
sde_kms->hw_intr->irq_lock can cause deadlock, to avoid this possible
deadlock this change uses different spin lock for frame events.

Change-Id: I51b1184dfa1069c87653099b95b992b277721daf
Signed-off-by: default avatarNarendra Muppalla <NarendraM@codeaurora.org>
parent 87440766
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
/*
 * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved.
 * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
 * Copyright (C) 2013 Red Hat
 * Author: Rob Clark <robdclark@gmail.com>
 *
@@ -2232,12 +2232,12 @@ static void sde_crtc_frame_event_cb(void *data, u32 event)
	SDE_DEBUG("crtc%d\n", crtc->base.id);
	SDE_EVT32_VERBOSE(DRMID(crtc), event);

	spin_lock_irqsave(&sde_crtc->spin_lock, flags);
	spin_lock_irqsave(&sde_crtc->fevent_spin_lock, flags);
	fevent = list_first_entry_or_null(&sde_crtc->frame_event_list,
			struct sde_crtc_frame_event, list);
	if (fevent)
		list_del_init(&fevent->list);
	spin_unlock_irqrestore(&sde_crtc->spin_lock, flags);
	spin_unlock_irqrestore(&sde_crtc->fevent_spin_lock, flags);

	if (!fevent) {
		SDE_ERROR("crtc%d event %d overflow\n",
@@ -2536,9 +2536,9 @@ static void sde_crtc_frame_event_work(struct kthread_work *work)
		SDE_ERROR("crtc%d ts:%lld received panel dead event\n",
				crtc->base.id, ktime_to_ns(fevent->ts));

	spin_lock_irqsave(&sde_crtc->spin_lock, flags);
	spin_lock_irqsave(&sde_crtc->fevent_spin_lock, flags);
	list_add_tail(&fevent->list, &sde_crtc->frame_event_list);
	spin_unlock_irqrestore(&sde_crtc->spin_lock, flags);
	spin_unlock_irqrestore(&sde_crtc->fevent_spin_lock, flags);
	SDE_ATRACE_END("crtc_frame_event");
}

@@ -6591,6 +6591,7 @@ struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct drm_plane *plane)

	mutex_init(&sde_crtc->crtc_lock);
	spin_lock_init(&sde_crtc->spin_lock);
	spin_lock_init(&sde_crtc->fevent_spin_lock);
	atomic_set(&sde_crtc->frame_pending, 0);

	sde_crtc->enabled = false;
+3 −1
Original line number Diff line number Diff line
@@ -259,7 +259,8 @@ struct sde_crtc_misr_info {
 * @frame_pending : Whether or not an update is pending
 * @frame_events  : static allocation of in-flight frame events
 * @frame_event_list : available frame event list
 * @spin_lock     : spin lock for frame event, transaction status, etc...
 * @spin_lock     : spin lock for transaction status, etc...
 * @fevent_spin_lock     : spin lock for frame event
 * @event_thread  : Pointer to event handler thread
 * @event_worker  : Event worker queue
 * @event_cache   : Local cache of event worker structures
@@ -342,6 +343,7 @@ struct sde_crtc {
	struct sde_crtc_frame_event frame_events[SDE_CRTC_FRAME_EVENT_SIZE];
	struct list_head frame_event_list;
	spinlock_t spin_lock;
	spinlock_t fevent_spin_lock;

	/* for handling internal event thread */
	struct sde_crtc_event event_cache[SDE_CRTC_MAX_EVENT_COUNT];