kernel_optimize_test/include/drm
Leo Li 4364bcb2cd drm: Get ref on CRTC commit object when waiting for flip_done
This fixes a general protection fault, caused by accessing the contents
of a flip_done completion object that has already been freed. It occurs
due to the preemption of a non-blocking commit worker thread W by
another commit thread X. X continues to clear its atomic state at the
end, destroying the CRTC commit object that W still needs. Switching
back to W and accessing the commit objects then leads to bad results.

Worker W becomes preemptable when waiting for flip_done to complete. At
this point, a frequently occurring commit thread X can take over. Here's
an example where W is a worker thread that flips on both CRTCs, and X
does a legacy cursor update on both CRTCs:

        ...
     1. W does flip work
     2. W runs commit_hw_done()
     3. W waits for flip_done on CRTC 1
     4. > flip_done for CRTC 1 completes
     5. W finishes waiting for CRTC 1
     6. W waits for flip_done on CRTC 2

     7. > Preempted by X
     8. > flip_done for CRTC 2 completes
     9. X atomic_check: hw_done and flip_done are complete on all CRTCs
    10. X updates cursor on both CRTCs
    11. X destroys atomic state
    12. X done

    13. > Switch back to W
    14. W waits for flip_done on CRTC 2
    15. W raises general protection fault

The error looks like so:

    general protection fault: 0000 [#1] PREEMPT SMP PTI
    **snip**
    Call Trace:
     lock_acquire+0xa2/0x1b0
     _raw_spin_lock_irq+0x39/0x70
     wait_for_completion_timeout+0x31/0x130
     drm_atomic_helper_wait_for_flip_done+0x64/0x90 [drm_kms_helper]
     amdgpu_dm_atomic_commit_tail+0xcae/0xdd0 [amdgpu]
     commit_tail+0x3d/0x70 [drm_kms_helper]
     process_one_work+0x212/0x650
     worker_thread+0x49/0x420
     kthread+0xfb/0x130
     ret_from_fork+0x3a/0x50
    Modules linked in: x86_pkg_temp_thermal amdgpu(O) chash(O)
    gpu_sched(O) drm_kms_helper(O) syscopyarea sysfillrect sysimgblt
    fb_sys_fops ttm(O) drm(O)

Note that i915 has this issue masked, since hw_done is signaled after
waiting for flip_done. Doing so will block the cursor update from
happening until hw_done is signaled, preventing the cursor commit from
destroying the state.

v2: The reference on the commit object needs to be obtained before
    hw_done() is signaled, since that's the point where another commit
    is allowed to modify the state. Assuming that the
    new_crtc_state->commit object still exists within flip_done() is
    incorrect.

    Fix by getting a reference in setup_commit(), and releasing it
    during default_clear().

Signed-off-by: Leo Li <sunpeng.li@amd.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1539611200-6184-1-git-send-email-sunpeng.li@amd.com
2018-10-18 14:23:13 -04:00
..
bridge drm for v4.18-rc1 2018-06-06 08:16:33 -07:00
i2c
tinydrm drm/tinydrm: Fix doc build warnings 2018-07-11 22:24:02 +02:00
ttm drm/ttm: Add ttm_set_pages_wc and ttm_set_pages_uc helper 2018-08-01 17:23:05 -05:00
amd_asic_type.h drm/amdgpu: Add vega20 to asic_type enum. 2018-05-17 10:13:09 -05:00
ati_pcigart.h
drm_agpsupport.h
drm_atomic_helper.h drm/crtc: Add a generic infrastructure to fake VBLANK events 2018-07-07 07:53:09 +02:00
drm_atomic.h drm: Get ref on CRTC commit object when waiting for flip_done 2018-10-18 14:23:13 -04:00
drm_audio_component.h ALSA: hda: Make audio component support more generic 2018-07-17 22:25:48 +02:00
drm_auth.h
drm_blend.h drm/blend: Add a generic alpha property 2018-04-16 21:17:29 +02:00
drm_bridge.h drm/bridge: Move the struct drm_bridge member kerneldoc inline. 2018-06-21 14:00:06 -07:00
drm_cache.h
drm_client.h drm/cma-helper: Fix crash in fbdev error path 2018-10-02 13:03:34 +02:00
drm_color_mgmt.h
drm_connector.h drm: drop _mode_ from remaining connector functions 2018-07-13 18:40:27 +02:00
drm_crtc_helper.h
drm_crtc.h drm/doc: use inline kerneldoc style for drm_crtc_state 2018-07-13 18:40:28 +02:00
drm_debugfs_crc.h drm/crc: Only report a single overflow when a CRC fd is opened 2018-07-06 14:57:03 +02:00
drm_debugfs.h
drm_device.h drm: Begin an API for in-kernel clients 2018-07-10 14:51:37 +02:00
drm_displayid.h
drm_dp_dual_mode_helper.h
drm_dp_helper.h drm: add support for DisplayPort CEC-Tunneling-over-AUX 2018-07-13 17:58:19 +03:00
drm_dp_mst_helper.h
drm_drv.h drm: fix drm_drv_uses_atomic_modeset on non modesetting drivers. 2018-09-18 11:17:06 +02:00
drm_edid.h drm/edid: VSDB yCBCr420 Deep Color mode bit definitions 2018-10-16 16:38:16 +03:00
drm_encoder_slave.h
drm_encoder.h drm: Add drm_encoder_mask() 2018-07-02 18:45:55 +03:00
drm_fb_cma_helper.h drm/cma-helper: Remove drm_fb_cma_fbdev_init_with_funcs() 2018-07-10 14:54:50 +02:00
drm_fb_helper.h drm/fb-helper: Finish the generic fbdev emulation 2018-07-10 14:54:09 +02:00
drm_file.h drm: writeback: Add client capability for exposing writeback connectors 2018-06-20 15:30:20 +01:00
drm_fixed.h
drm_flip_work.h
drm_fourcc.h drm/fourcc: Add is_yuv field to drm_format_info to denote if the format is yuv 2018-07-18 16:56:45 +01:00
drm_framebuffer.h
drm_gem_cma_helper.h
drm_gem_framebuffer_helper.h drm: Move simple_display_pipe prepare_fb helper into gem fb helpers 2018-04-24 13:57:22 +02:00
drm_gem.h
drm_global.h
drm_hashtab.h
drm_hdcp.h drm: Fix HDCP downstream dev count read 2018-04-16 12:10:48 -04:00
drm_ioctl.h drm: remove all control node code 2018-05-03 21:26:32 +02:00
drm_irq.h
drm_lease.h
drm_legacy.h drm: prefer inline over __inline__ 2018-03-28 09:34:12 +03:00
drm_mipi_dsi.h
drm_mm.h drm/mm: Add a search-by-address variant to only inspect a single hole 2018-05-24 15:04:30 +01:00
drm_mode_config.h drm: Document mode_config.max_width/height as the max fb dimensions 2018-06-21 19:16:07 +03:00
drm_mode_object.h
drm_modes.h drm: drop _mode_ from remaining connector functions 2018-07-13 18:40:27 +02:00
drm_modeset_helper_vtables.h drm: drop _mode_ from update_edit_property() 2018-07-13 18:40:27 +02:00
drm_modeset_helper.h
drm_modeset_lock.h
drm_of.h drm: of: Export and rename drm_crtc_port_mask() 2018-06-27 21:44:04 +02:00
drm_os_linux.h
drm_panel.h Revert "drm/panel: Add device_link from panel device to DRM device" 2018-09-27 11:00:42 -04:00
drm_pci.h drm: drop drm_pcie_get_speed_cap_mask and drm_pcie_get_max_link_width 2018-07-05 16:40:00 -05:00
drm_pciids.h
drm_plane_helper.h drm: add missing ctx argument to plane transitional helpers 2018-07-03 09:30:19 +02:00
drm_plane.h drm: switch drm_plane to inline comments 2018-07-13 18:40:28 +02:00
drm_prime.h dma-buf: remove kmap_atomic interface 2018-06-20 15:59:34 +02:00
drm_print.h drm: Add puts callback for the coredump printer 2018-07-30 08:49:41 -04:00
drm_property.h drm: Fix kerneldoc for DRM_MODE_PROP_IMMUTABLE 2018-07-13 12:18:03 -04:00
drm_rect.h drm/rect: Handle rounding errors in drm_rect_clip_scaled, v3. 2018-05-04 11:09:54 +02:00
drm_scdc_helper.h
drm_simple_kms_helper.h drm: Move simple_display_pipe prepare_fb helper into gem fb helpers 2018-04-24 13:57:22 +02:00
drm_syncobj.h
drm_sysfs.h
drm_utils.h
drm_vblank.h
drm_vma_manager.h drm/i915: Prevent writing into a read-only object via a GGTT mmap 2018-07-13 16:14:04 +01:00
drm_writeback.h drm/atomic: Avoid connector to writeback_connector casts 2018-07-07 07:51:19 +02:00
drmP.h drm: move drv test macros out of drmP.h 2018-07-13 18:40:27 +02:00
gma_drm.h
gpu_scheduler.h drm/scheduler: only kill entity if last user is killed v2 2018-07-31 16:58:20 -05:00
i915_component.h drm/i915: Split audio component to a generic type 2018-07-17 22:25:19 +02:00
i915_drm.h x86/gpu: reserve ICL's graphics stolen memory 2018-07-10 16:28:47 -07:00
i915_pciids.h drm/i915/aml: Introducing Amber Lake platform 2018-06-18 10:49:57 -07:00
intel_lpe_audio.h
intel-gtt.h
spsc_queue.h