120 lines
3.7 KiB
Diff
120 lines
3.7 KiB
Diff
|
From: Mike Galbraith <umgwanakikbuti@gmail.com>
|
||
|
Date: Sat, 27 Feb 2016 09:01:42 +0100
|
||
|
Subject: [PATCH 2/8] drm/i915: Don't disable interrupts on PREEMPT_RT during
|
||
|
atomic updates
|
||
|
Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.11/older/patches-6.11-rt7.tar.xz
|
||
|
|
||
|
Commit
|
||
|
8d7849db3eab7 ("drm/i915: Make sprite updates atomic")
|
||
|
|
||
|
started disabling interrupts across atomic updates. This breaks on PREEMPT_RT
|
||
|
because within this section the code attempt to acquire spinlock_t locks which
|
||
|
are sleeping locks on PREEMPT_RT.
|
||
|
|
||
|
According to the comment the interrupts are disabled to avoid random delays and
|
||
|
not required for protection or synchronisation.
|
||
|
If this needs to happen with disabled interrupts on PREEMPT_RT, and the
|
||
|
whole section is restricted to register access then all sleeping locks
|
||
|
need to be acquired before interrupts are disabled and some function
|
||
|
maybe moved after enabling interrupts again.
|
||
|
This includes:
|
||
|
- prepare_to_wait() + finish_wait() due its wake queue.
|
||
|
- drm_crtc_vblank_put() -> vblank_disable_fn() drm_device::vbl_lock.
|
||
|
- skl_pfit_enable(), intel_update_plane(), vlv_atomic_update_fifo() and
|
||
|
maybe others due to intel_uncore::lock
|
||
|
- drm_crtc_arm_vblank_event() due to drm_device::event_lock and
|
||
|
drm_device::vblank_time_lock.
|
||
|
|
||
|
Don't disable interrupts on PREEMPT_RT during atomic updates.
|
||
|
|
||
|
[bigeasy: drop local locks, commit message]
|
||
|
|
||
|
Signed-off-by: Mike Galbraith <umgwanakikbuti@gmail.com>
|
||
|
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
||
|
---
|
||
|
drivers/gpu/drm/i915/display/intel_crtc.c | 9 ++++++---
|
||
|
drivers/gpu/drm/i915/display/intel_cursor.c | 9 ++++++---
|
||
|
drivers/gpu/drm/i915/display/intel_vblank.c | 6 ++++--
|
||
|
3 files changed, 16 insertions(+), 8 deletions(-)
|
||
|
|
||
|
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
|
||
|
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
|
||
|
@@ -521,7 +521,8 @@ void intel_pipe_update_start(struct inte
|
||
|
*/
|
||
|
intel_psr_wait_for_idle_locked(new_crtc_state);
|
||
|
|
||
|
- local_irq_disable();
|
||
|
+ if (!IS_ENABLED(CONFIG_PREEMPT_RT))
|
||
|
+ local_irq_disable();
|
||
|
|
||
|
crtc->debug.min_vbl = evade.min;
|
||
|
crtc->debug.max_vbl = evade.max;
|
||
|
@@ -539,7 +540,8 @@ void intel_pipe_update_start(struct inte
|
||
|
return;
|
||
|
|
||
|
irq_disable:
|
||
|
- local_irq_disable();
|
||
|
+ if (!IS_ENABLED(CONFIG_PREEMPT_RT))
|
||
|
+ local_irq_disable();
|
||
|
}
|
||
|
|
||
|
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_VBLANK_EVADE)
|
||
|
@@ -668,7 +670,8 @@ void intel_pipe_update_end(struct intel_
|
||
|
*/
|
||
|
intel_vrr_send_push(new_crtc_state);
|
||
|
|
||
|
- local_irq_enable();
|
||
|
+ if (!IS_ENABLED(CONFIG_PREEMPT_RT))
|
||
|
+ local_irq_enable();
|
||
|
|
||
|
if (intel_vgpu_active(dev_priv))
|
||
|
goto out;
|
||
|
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
|
||
|
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
|
||
|
@@ -895,13 +895,15 @@ intel_legacy_cursor_update(struct drm_pl
|
||
|
*/
|
||
|
intel_psr_wait_for_idle_locked(crtc_state);
|
||
|
|
||
|
- local_irq_disable();
|
||
|
+ if (!IS_ENABLED(CONFIG_PREEMPT_RT))
|
||
|
+ local_irq_disable();
|
||
|
|
||
|
intel_vblank_evade(&evade);
|
||
|
|
||
|
drm_crtc_vblank_put(&crtc->base);
|
||
|
} else {
|
||
|
- local_irq_disable();
|
||
|
+ if (!IS_ENABLED(CONFIG_PREEMPT_RT))
|
||
|
+ local_irq_disable();
|
||
|
}
|
||
|
|
||
|
if (new_plane_state->uapi.visible) {
|
||
|
@@ -911,7 +913,8 @@ intel_legacy_cursor_update(struct drm_pl
|
||
|
intel_plane_disable_arm(plane, crtc_state);
|
||
|
}
|
||
|
|
||
|
- local_irq_enable();
|
||
|
+ if (!IS_ENABLED(CONFIG_PREEMPT_RT))
|
||
|
+ local_irq_enable();
|
||
|
|
||
|
intel_psr_unlock(crtc_state);
|
||
|
|
||
|
--- a/drivers/gpu/drm/i915/display/intel_vblank.c
|
||
|
+++ b/drivers/gpu/drm/i915/display/intel_vblank.c
|
||
|
@@ -705,11 +705,13 @@ int intel_vblank_evade(struct intel_vbla
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
- local_irq_enable();
|
||
|
+ if (!IS_ENABLED(CONFIG_PREEMPT_RT))
|
||
|
+ local_irq_enable();
|
||
|
|
||
|
timeout = schedule_timeout(timeout);
|
||
|
|
||
|
- local_irq_disable();
|
||
|
+ if (!IS_ENABLED(CONFIG_PREEMPT_RT))
|
||
|
+ local_irq_disable();
|
||
|
}
|
||
|
|
||
|
finish_wait(wq, &wait);
|