From: Mike Galbraith Date: Sat, 27 Feb 2016 09:01:42 +0100 Subject: [PATCH 251/342] drm,i915: Use local_lock/unlock_irq() in intel_pipe_update_start/end() Origin: https://git.kernel.org/cgit/linux/kernel/git/rt/linux-stable-rt.git/commit?id=7f085a648643b652361155e0b483d114b769aaeb [ 8.014039] BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:918 [ 8.014041] in_atomic(): 0, irqs_disabled(): 1, pid: 78, name: kworker/u4:4 [ 8.014045] CPU: 1 PID: 78 Comm: kworker/u4:4 Not tainted 4.1.7-rt7 #5 [ 8.014055] Workqueue: events_unbound async_run_entry_fn [ 8.014059] 0000000000000000 ffff880037153748 ffffffff815f32c9 0000000000000002 [ 8.014063] ffff88013a50e380 ffff880037153768 ffffffff815ef075 ffff8800372c06c8 [ 8.014066] ffff8800372c06c8 ffff880037153778 ffffffff8107c0b3 ffff880037153798 [ 8.014067] Call Trace: [ 8.014074] [] dump_stack+0x4a/0x61 [ 8.014078] [] ___might_sleep.part.93+0xe9/0xee [ 8.014082] [] ___might_sleep+0x53/0x80 [ 8.014086] [] rt_spin_lock+0x24/0x50 [ 8.014090] [] prepare_to_wait+0x2b/0xa0 [ 8.014152] [] intel_pipe_update_start+0x17c/0x300 [i915] [ 8.014156] [] ? prepare_to_wait_event+0x120/0x120 [ 8.014201] [] intel_begin_crtc_commit+0x166/0x1e0 [i915] [ 8.014215] [] drm_atomic_helper_commit_planes+0x5d/0x1a0 [drm_kms_helper] [ 8.014260] [] intel_atomic_commit+0xab/0xf0 [i915] [ 8.014288] [] drm_atomic_commit+0x37/0x60 [drm] [ 8.014298] [] drm_atomic_helper_plane_set_property+0x8d/0xd0 [drm_kms_helper] [ 8.014301] [] ? __ww_mutex_lock+0x39/0x40 [ 8.014319] [] drm_mode_plane_set_obj_prop+0x2d/0x90 [drm] [ 8.014328] [] restore_fbdev_mode+0x6b/0xf0 [drm_kms_helper] [ 8.014337] [] drm_fb_helper_restore_fbdev_mode_unlocked+0x29/0x80 [drm_kms_helper] [ 8.014346] [] drm_fb_helper_set_par+0x22/0x50 [drm_kms_helper] [ 8.014390] [] intel_fbdev_set_par+0x1a/0x60 [i915] [ 8.014394] [] fbcon_init+0x4f4/0x580 [ 8.014398] [] visual_init+0xbc/0x120 [ 8.014401] [] do_bind_con_driver+0x163/0x330 [ 8.014405] [] do_take_over_console+0x11c/0x1c0 [ 8.014408] [] do_fbcon_takeover+0x63/0xd0 [ 8.014410] [] fbcon_event_notify+0x785/0x8d0 [ 8.014413] [] ? __might_sleep+0x4d/0x90 [ 8.014416] [] notifier_call_chain+0x4e/0x80 [ 8.014419] [] __blocking_notifier_call_chain+0x4d/0x70 [ 8.014422] [] blocking_notifier_call_chain+0x16/0x20 [ 8.014425] [] fb_notifier_call_chain+0x1b/0x20 [ 8.014428] [] register_framebuffer+0x21a/0x350 [ 8.014439] [] drm_fb_helper_initial_config+0x274/0x3e0 [drm_kms_helper] [ 8.014483] [] intel_fbdev_initial_config+0x1b/0x20 [i915] [ 8.014486] [] async_run_entry_fn+0x4c/0x160 [ 8.014490] [] process_one_work+0x14a/0x470 [ 8.014493] [] worker_thread+0x169/0x4c0 [ 8.014496] [] ? process_one_work+0x470/0x470 [ 8.014499] [] kthread+0xc6/0xe0 [ 8.014502] [] ? queue_work_on+0x80/0x110 [ 8.014506] [] ? kthread_worker_fn+0x1c0/0x1c0 Signed-off-by: Mike Galbraith Cc: Sebastian Andrzej Siewior Cc: linux-rt-users Signed-off-by: Thomas Gleixner --- drivers/gpu/drm/i915/intel_sprite.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index f7026e887fa9..07e4ddebdd80 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "intel_drv.h" #include "intel_frontbuffer.h" #include @@ -60,6 +61,8 @@ int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, #define VBLANK_EVASION_TIME_US 100 #endif +static DEFINE_LOCAL_IRQ_LOCK(pipe_update_lock); + /** * intel_pipe_update_start() - start update of a set of display registers * @new_crtc_state: the new crtc state @@ -107,7 +110,7 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state) if (intel_psr_wait_for_idle(new_crtc_state)) DRM_ERROR("PSR idle timed out, atomic update may fail\n"); - local_irq_disable(); + local_lock_irq(pipe_update_lock); crtc->debug.min_vbl = min; crtc->debug.max_vbl = max; @@ -131,11 +134,11 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state) break; } - local_irq_enable(); + local_unlock_irq(pipe_update_lock); timeout = schedule_timeout(timeout); - local_irq_disable(); + local_lock_irq(pipe_update_lock); } finish_wait(wq, &wait); @@ -168,7 +171,7 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state) return; irq_disable: - local_irq_disable(); + local_lock_irq(pipe_update_lock); } /** @@ -204,7 +207,7 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) new_crtc_state->base.event = NULL; } - local_irq_enable(); + local_unlock_irq(pipe_update_lock); if (intel_vgpu_active(dev_priv)) return;