Re: [Intel-gfx] [PATCH 2/2] drm/i915: Handle legacy cursor update as normal update
Hello, kernel test robot noticed "BUG:KASAN:slab-use-after-free_in_intel_wait_for_vblank_workers" on: commit: cfd54d37e5cd9511b5a4a98bba6d4b2f596149cf ("[Intel-gfx] [PATCH 2/2] drm/i915: Handle legacy cursor update as normal update") url: https://github.com/intel-lab-lkp/linux/commits/Maarten-Lankhorst/drm-i915-Handle-legacy-cursor-update-as-normal-update/20230814-145051 base: git://anongit.freedesktop.org/drm/drm-tip drm-tip patch link: https://lore.kernel.org/all/20230814065006.47160-2-...@lankhorst.se/ patch subject: [Intel-gfx] [PATCH 2/2] drm/i915: Handle legacy cursor update as normal update in testcase: igt version: igt-x86_64-0f075441-1_20230520 with following parameters: group: group-23 compiler: gcc-12 test machine: 20 threads 1 sockets (Commet Lake) with 16G memory (please refer to attached dmesg/kmsg for entire log/backtrace) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot | Closes: https://lore.kernel.org/oe-lkp/202308181627.2fec1157-oliver.s...@intel.com kern :err : [ 162.196982] BUG: KASAN: slab-use-after-free in intel_wait_for_vblank_workers (drivers/gpu/drm/i915/display/intel_crtc.c:395 drivers/gpu/drm/i915/display/intel_crtc.c:447) i915 kern :err : [ 162.206530] Read of size 1 at addr 88811d8dc150 by task kworker/0:0H/8 kern :err : [ 162.216391] CPU: 0 PID: 8 Comm: kworker/0:0H Not tainted 6.5.0-rc6-00947-gcfd54d37e5cd #1 kern :err : [ 162.225319] Workqueue: events_highpri intel_atomic_cleanup_work [i915] kern :err : [ 162.232683] Call Trace: kern :err : [ 162.235861] kern :err : [ 162.238688] dump_stack_lvl (lib/dump_stack.c:107 (discriminator 1)) kern :err : [ 162.243085] print_address_description+0x2c/0x3a0 kern :err : [ 162.249618] ? intel_wait_for_vblank_workers (drivers/gpu/drm/i915/display/intel_crtc.c:395 drivers/gpu/drm/i915/display/intel_crtc.c:447) i915 kern :err : [ 162.256370] print_report (mm/kasan/report.c:476) kern :err : [ 162.260681] ? kasan_addr_to_slab (mm/kasan/common.c:35) kern :err : [ 162.265515] ? intel_wait_for_vblank_workers (drivers/gpu/drm/i915/display/intel_crtc.c:395 drivers/gpu/drm/i915/display/intel_crtc.c:447) i915 kern :err : [ 162.272267] kasan_report (mm/kasan/report.c:590) kern :err : [ 162.276584] ? intel_wait_for_vblank_workers (drivers/gpu/drm/i915/display/intel_crtc.c:395 drivers/gpu/drm/i915/display/intel_crtc.c:447) i915 kern :err : [ 162.283336] intel_wait_for_vblank_workers (drivers/gpu/drm/i915/display/intel_crtc.c:395 drivers/gpu/drm/i915/display/intel_crtc.c:447) i915 kern :err : [ 162.289911] intel_atomic_cleanup_work (drivers/gpu/drm/i915/display/intel_display.c:6901) i915 kern :err : [ 162.296191] ? drm_dev_put (drivers/gpu/drm/drm_drv.c:827) drm kern :err : [ 162.301672] process_one_work (kernel/workqueue.c:2605) kern :err : [ 162.306507] worker_thread (include/linux/list.h:292 kernel/workqueue.c:2752) kern :err : [ 162.311080] ? rescuer_thread (kernel/workqueue.c:2694) kern :err : [ 162.315828] kthread (kernel/kthread.c:389) kern :err : [ 162.319791] ? kthread_complete_and_exit (kernel/kthread.c:342) kern :err : [ 162.325323] ret_from_fork (arch/x86/kernel/process.c:151) kern :err : [ 162.329630] ? kthread_complete_and_exit (kernel/kthread.c:342) kern :err : [ 162.335181] ret_from_fork_asm (arch/x86/entry/entry_64.S:312) kern :err : [ 162.339840] kern :err : [ 162.344980] Allocated by task 4201: kern :warn : [ 162.349214] kasan_save_stack (mm/kasan/common.c:46) kern :warn : [ 162.353787] kasan_set_track (mm/kasan/common.c:52) kern :warn : [ 162.358270] __kasan_kmalloc (mm/kasan/common.c:374 mm/kasan/common.c:383) kern :warn : [ 162.362757] __kmalloc_node_track_caller (include/linux/kasan.h:196 mm/slab_common.c:985 mm/slab_common.c:1005) kern :warn : [ 162.368283] kmemdup (mm/util.c:131) kern :warn : [ 162.372075] intel_crtc_duplicate_state (include/linux/fortify-string.h:765 drivers/gpu/drm/i915/display/intel_atomic.c:242) i915 kern :warn : [ 162.378364] drm_atomic_get_crtc_state (drivers/gpu/drm/drm_atomic.c:363) drm kern :warn : [ 162.384453] drm_atomic_get_plane_state (drivers/gpu/drm/drm_atomic.c:567) drm kern :warn : [ 162.390622] drm_atomic_helper_update_plane (drivers/gpu/drm/drm_atomic_helper.c:3127) drm_kms_helper kern :warn : [ 162.397997] drm_mode_cursor_universal (drivers/gpu/drm/drm_plane.c:1086) drm kern :warn : [ 162.404086] drm_mode_cursor_common (drivers/gpu/drm/drm_plane.c:1172) drm kern :warn : [ 162.409973] drm_mode_cursor_ioctl (drivers/gpu/drm/drm_plane.c:1188) drm kern :warn : [ 162.415628] drm_ioctl_kernel (drivers/gpu/drm/drm_ioctl.c:795) drm kern :warn : [ 162.420933] drm_ioctl (drivers/gpu/drm/drm_ioctl.c:893) drm kern :warn : [ 162.425627] __x64_sys_ioctl (fs/ioctl.c:52 fs/ioctl.c:870 fs/ioctl.c:856 fs/ioctl.c:856) kern :
[Intel-gfx] [PATCH 2/2] drm/i915: Handle legacy cursor update as normal update
From: Maarten Lankhorst Abuse the vblank worker to make the changes as small as possible. We need a way to sync flip_done, but if we wait on flip_done, all async tests start failing. Changes since v1: - Prevent null deref when crtc is inactive. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_crtc.c| 28 +--- drivers/gpu/drm/i915/display/intel_crtc.h| 6 +++-- drivers/gpu/drm/i915/display/intel_display.c | 10 --- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index f06b987f5558..be6959c6eb0d 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -389,11 +389,17 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe) return ret; } -static bool intel_crtc_needs_vblank_work(const struct intel_crtc_state *crtc_state) +static bool intel_crtc_needs_vblank_work(const struct intel_atomic_state *state, +const struct intel_crtc_state *crtc_state) { - return crtc_state->hw.active && - !intel_crtc_needs_modeset(crtc_state) && - !crtc_state->preload_luts && + if (!crtc_state->hw.active || intel_crtc_needs_modeset(crtc_state)) + return false; + + /* Init for legacy cursor update, so we can sync on teardown */ + if (state->base.legacy_cursor_update) + return true; + + return !crtc_state->preload_luts && intel_crtc_needs_color_update(crtc_state); } @@ -438,7 +444,7 @@ void intel_wait_for_vblank_workers(struct intel_atomic_state *state) int i; for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { - if (!intel_crtc_needs_vblank_work(crtc_state)) + if (!intel_crtc_needs_vblank_work(state, crtc_state)) continue; drm_vblank_work_flush(_state->vblank_work); @@ -470,6 +476,7 @@ static int intel_mode_vblank_start(const struct drm_display_mode *mode) /** * intel_pipe_update_start() - start update of a set of display registers + * @state: the intel atomic state * @new_crtc_state: the new crtc state * * Mark the start of an update to pipe registers that should be updated @@ -480,7 +487,8 @@ static int intel_mode_vblank_start(const struct drm_display_mode *mode) * until a subsequent call to intel_pipe_update_end(). That is done to * avoid random delays. */ -void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state) +void intel_pipe_update_start(struct intel_atomic_state *state, +struct intel_crtc_state *new_crtc_state) { struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); @@ -497,7 +505,7 @@ void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state) if (new_crtc_state->do_async_flip) return; - if (intel_crtc_needs_vblank_work(new_crtc_state)) + if (intel_crtc_needs_vblank_work(state, new_crtc_state)) intel_crtc_vblank_work_init(new_crtc_state); if (new_crtc_state->vrr.enable) { @@ -635,13 +643,15 @@ static void dbg_vblank_evade(struct intel_crtc *crtc, ktime_t end) {} /** * intel_pipe_update_end() - end update of a set of display registers + * @state: the intel atomic state * @new_crtc_state: the new crtc state * * Mark the end of an update started with intel_pipe_update_start(). This * re-enables interrupts and verifies the update was actually completed * before a vblank. */ -void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) +void intel_pipe_update_end(struct intel_atomic_state *state, + struct intel_crtc_state *new_crtc_state) { struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); enum pipe pipe = crtc->pipe; @@ -669,7 +679,7 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) * Would be slightly nice to just grab the vblank count and arm the * event outside of the critical section - the spinlock might spin for a * while ... */ - if (intel_crtc_needs_vblank_work(new_crtc_state)) { + if (intel_crtc_needs_vblank_work(state, new_crtc_state)) { drm_vblank_work_schedule(_crtc_state->vblank_work, drm_crtc_accurate_vblank_count(>base) + 1, false); diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h b/drivers/gpu/drm/i915/display/intel_crtc.h index 51a4c8df9e65..ca7f45a454a0 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.h +++ b/drivers/gpu/drm/i915/display/intel_crtc.h @@ -36,8 +36,10 @@ void intel_crtc_state_reset(struct intel_crtc_state *crtc_state, u32
[Intel-gfx] [PATCH 2/2] drm/i915: Handle legacy cursor update as normal update
Abuse the vblank worker to make the changes as small as possible. We need a way to sync flip_done, but if we wait on flip_done, all async tests start failing. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_crtc.c| 21 ++-- drivers/gpu/drm/i915/display/intel_crtc.h| 6 -- drivers/gpu/drm/i915/display/intel_display.c | 10 +++--- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 182c6dd64f47..2adcce303271 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -389,8 +389,13 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe) return ret; } -static bool intel_crtc_needs_vblank_work(const struct intel_crtc_state *crtc_state) +static bool intel_crtc_needs_vblank_work(const struct intel_atomic_state *state, +const struct intel_crtc_state *crtc_state) { + /* Always init for legacy cursor update, so we can sync on teardown */ + if (state->base.legacy_cursor_update) + return true; + return crtc_state->hw.active && !intel_crtc_needs_modeset(crtc_state) && !crtc_state->preload_luts && @@ -438,7 +443,7 @@ void intel_wait_for_vblank_workers(struct intel_atomic_state *state) int i; for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { - if (!intel_crtc_needs_vblank_work(crtc_state)) + if (!intel_crtc_needs_vblank_work(state, crtc_state)) continue; drm_vblank_work_flush(_state->vblank_work); @@ -470,6 +475,7 @@ static int intel_mode_vblank_start(const struct drm_display_mode *mode) /** * intel_pipe_update_start() - start update of a set of display registers + * @state: the intel atomic state * @new_crtc_state: the new crtc state * * Mark the start of an update to pipe registers that should be updated @@ -480,7 +486,8 @@ static int intel_mode_vblank_start(const struct drm_display_mode *mode) * until a subsequent call to intel_pipe_update_end(). That is done to * avoid random delays. */ -void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state) +void intel_pipe_update_start(struct intel_atomic_state *state, +struct intel_crtc_state *new_crtc_state) { struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); @@ -497,7 +504,7 @@ void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state) if (new_crtc_state->do_async_flip) return; - if (intel_crtc_needs_vblank_work(new_crtc_state)) + if (intel_crtc_needs_vblank_work(state, new_crtc_state)) intel_crtc_vblank_work_init(new_crtc_state); if (new_crtc_state->vrr.enable) { @@ -631,13 +638,15 @@ static void dbg_vblank_evade(struct intel_crtc *crtc, ktime_t end) {} /** * intel_pipe_update_end() - end update of a set of display registers + * @state: the intel atomic state * @new_crtc_state: the new crtc state * * Mark the end of an update started with intel_pipe_update_start(). This * re-enables interrupts and verifies the update was actually completed * before a vblank. */ -void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) +void intel_pipe_update_end(struct intel_atomic_state *state, + struct intel_crtc_state *new_crtc_state) { struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); enum pipe pipe = crtc->pipe; @@ -665,7 +674,7 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) * Would be slightly nice to just grab the vblank count and arm the * event outside of the critical section - the spinlock might spin for a * while ... */ - if (intel_crtc_needs_vblank_work(new_crtc_state)) { + if (intel_crtc_needs_vblank_work(state, new_crtc_state)) { drm_vblank_work_schedule(_crtc_state->vblank_work, drm_crtc_accurate_vblank_count(>base) + 1, false); diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h b/drivers/gpu/drm/i915/display/intel_crtc.h index 51a4c8df9e65..ca7f45a454a0 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.h +++ b/drivers/gpu/drm/i915/display/intel_crtc.h @@ -36,8 +36,10 @@ void intel_crtc_state_reset(struct intel_crtc_state *crtc_state, u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc); void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state); void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state); -void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state); -void intel_pipe_update_end(struct
[Intel-gfx] [PATCH 2/2] drm/i915: Handle legacy cursor update as normal update
Move hw_done to cleanup, to ensure we only unpin cursor fb after we received a flip event. This disables the legacy_cursor_update immediate completion of flip_done events, and waits for flip_done before cleaning up. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_display.c | 15 ++- .../gpu/drm/i915/display/intel_display_types.h| 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 43bcd3d011bf5..38c3eb8d95789 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6864,6 +6864,9 @@ static void intel_atomic_cleanup_work(struct work_struct *work) struct intel_crtc *crtc; int i; + if (state->cursor_update) + drm_atomic_helper_wait_for_flip_done(>drm, >base); + for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state, i) intel_color_cleanup_commit(old_crtc_state); @@ -7062,7 +7065,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) * - switch over to the vblank wait helper in the core after that since * we don't need out special handling any more. */ - drm_atomic_helper_wait_for_flip_done(dev, >base); + if (!state->cursor_update) + drm_atomic_helper_wait_for_flip_done(dev, >base); for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { if (new_crtc_state->do_async_flip) @@ -7247,6 +7251,15 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, state->base.legacy_cursor_update = false; } + if (state->base.legacy_cursor_update) { + /* +* If this is a legacy cursor update, handle like a normal update, +* but wait before calling cleanup +*/ + state->base.legacy_cursor_update = false; + state->cursor_update = true; + } + ret = intel_atomic_prepare_commit(state); if (ret) { drm_dbg_atomic(_priv->drm, diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index c85cf8adc7a69..01f7c8d24179c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -646,7 +646,7 @@ struct intel_atomic_state { /* Internal commit, as opposed to userspace/client initiated one */ bool internal; - bool dpll_set, modeset; + bool dpll_set, modeset, cursor_update; struct intel_shared_dpll_state shared_dpll[I915_NUM_PLLS]; -- 2.39.2
Re: [Intel-gfx] [PATCH 2/2] drm/i915: Handle legacy cursor update as normal update
Hi Maarten, kernel test robot noticed the following build errors: [auto build test ERROR on drm-tip/drm-tip] url: https://github.com/intel-lab-lkp/linux/commits/Maarten-Lankhorst/drm-i915-Handle-legacy-cursor-update-as-normal-update/20230621-195009 base: git://anongit.freedesktop.org/drm/drm-tip drm-tip patch link: https://lore.kernel.org/r/20230621114827.167713-2-maarten.lankhorst%40linux.intel.com patch subject: [Intel-gfx] [PATCH 2/2] drm/i915: Handle legacy cursor update as normal update config: x86_64-rhel-8.3-rust (https://download.01.org/0day-ci/archive/20230622/202306220703.f8igfxot-...@intel.com/config) compiler: clang version 15.0.7 (https://github.com/llvm/llvm-project.git 8dfdcc7b7bf66834a761bd8de445840ef68e4d1a) reproduce: (https://download.01.org/0day-ci/archive/20230622/202306220703.f8igfxot-...@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot | Closes: https://lore.kernel.org/oe-kbuild-all/202306220703.f8igfxot-...@intel.com/ All errors (new ones prefixed by >>): >> drivers/gpu/drm/i915/display/intel_display.c:6900:40: error: use of >> undeclared identifier 'dev' drm_atomic_helper_wait_for_flip_done(dev, >base); ^ 1 error generated. vim +/dev +6900 drivers/gpu/drm/i915/display/intel_display.c 6889 6890 static void intel_atomic_cleanup_work(struct work_struct *work) 6891 { 6892 struct intel_atomic_state *state = 6893 container_of(work, struct intel_atomic_state, base.commit_work); 6894 struct drm_i915_private *i915 = to_i915(state->base.dev); 6895 struct intel_crtc_state *old_crtc_state; 6896 struct intel_crtc *crtc; 6897 int i; 6898 6899 if (state->cursor_update) > 6900 drm_atomic_helper_wait_for_flip_done(dev, >base); 6901 6902 for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state, i) 6903 intel_color_cleanup_commit(old_crtc_state); 6904 6905 drm_atomic_helper_cleanup_planes(>drm, >base); 6906 drm_atomic_helper_commit_cleanup_done(>base); 6907 drm_atomic_state_put(>base); 6908 6909 intel_atomic_helper_free_state(i915); 6910 } 6911 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Re: [Intel-gfx] [PATCH 2/2] drm/i915: Handle legacy cursor update as normal update
Hi Maarten, kernel test robot noticed the following build errors: [auto build test ERROR on drm-tip/drm-tip] url: https://github.com/intel-lab-lkp/linux/commits/Maarten-Lankhorst/drm-i915-Handle-legacy-cursor-update-as-normal-update/20230621-195009 base: git://anongit.freedesktop.org/drm/drm-tip drm-tip patch link: https://lore.kernel.org/r/20230621114827.167713-2-maarten.lankhorst%40linux.intel.com patch subject: [Intel-gfx] [PATCH 2/2] drm/i915: Handle legacy cursor update as normal update config: x86_64-defconfig (https://download.01.org/0day-ci/archive/20230622/202306220634.fni3ogxp-...@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 reproduce: (https://download.01.org/0day-ci/archive/20230622/202306220634.fni3ogxp-...@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot | Closes: https://lore.kernel.org/oe-kbuild-all/202306220634.fni3ogxp-...@intel.com/ All errors (new ones prefixed by >>): drivers/gpu/drm/i915/display/intel_display.c: In function 'intel_atomic_cleanup_work': >> drivers/gpu/drm/i915/display/intel_display.c:6900:54: error: 'dev' >> undeclared (first use in this function); did you mean 'cdev'? 6900 | drm_atomic_helper_wait_for_flip_done(dev, >base); | ^~~ | cdev drivers/gpu/drm/i915/display/intel_display.c:6900:54: note: each undeclared identifier is reported only once for each function it appears in vim +6900 drivers/gpu/drm/i915/display/intel_display.c 6889 6890 static void intel_atomic_cleanup_work(struct work_struct *work) 6891 { 6892 struct intel_atomic_state *state = 6893 container_of(work, struct intel_atomic_state, base.commit_work); 6894 struct drm_i915_private *i915 = to_i915(state->base.dev); 6895 struct intel_crtc_state *old_crtc_state; 6896 struct intel_crtc *crtc; 6897 int i; 6898 6899 if (state->cursor_update) > 6900 drm_atomic_helper_wait_for_flip_done(dev, >base); 6901 6902 for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state, i) 6903 intel_color_cleanup_commit(old_crtc_state); 6904 6905 drm_atomic_helper_cleanup_planes(>drm, >base); 6906 drm_atomic_helper_commit_cleanup_done(>base); 6907 drm_atomic_state_put(>base); 6908 6909 intel_atomic_helper_free_state(i915); 6910 } 6911 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
[Intel-gfx] [PATCH 2/2] drm/i915: Handle legacy cursor update as normal update
Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_display.c | 15 ++- .../gpu/drm/i915/display/intel_display_types.h| 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 43bcd3d011bf5..3927dfb894c1a 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6864,6 +6864,9 @@ static void intel_atomic_cleanup_work(struct work_struct *work) struct intel_crtc *crtc; int i; + if (state->cursor_update) + drm_atomic_helper_wait_for_flip_done(dev, >base); + for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state, i) intel_color_cleanup_commit(old_crtc_state); @@ -7062,7 +7065,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) * - switch over to the vblank wait helper in the core after that since * we don't need out special handling any more. */ - drm_atomic_helper_wait_for_flip_done(dev, >base); + if (!state->cursor_update) + drm_atomic_helper_wait_for_flip_done(dev, >base); for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { if (new_crtc_state->do_async_flip) @@ -7247,6 +7251,15 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, state->base.legacy_cursor_update = false; } + if (state->base.legacy_cursor_update) { + /* +* If this is a legacy cursor update, handle like a normal update, +* but wait before calling cleanup +*/ + state->base.legacy_cursor_update = false; + state->cursor_update = true; + } + ret = intel_atomic_prepare_commit(state); if (ret) { drm_dbg_atomic(_priv->drm, diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index c85cf8adc7a69..01f7c8d24179c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -646,7 +646,7 @@ struct intel_atomic_state { /* Internal commit, as opposed to userspace/client initiated one */ bool internal; - bool dpll_set, modeset; + bool dpll_set, modeset, cursor_update; struct intel_shared_dpll_state shared_dpll[I915_NUM_PLLS]; -- 2.39.2