linux/drivers/gpu/drm/i915
Chris Wilson ad46cb533d drm/i915: Prevent recursive deadlock on releasing a busy userptr
During release of the GEM object we hold the struct_mutex. As the
object may be holding onto the last reference for the task->mm,
calling mmput() may trigger exit_mmap() which close the vma
which will call drm_gem_vm_close() and attempt to reacquire
the struct_mutex. In order to avoid that recursion, we have
to defer the mmput() until after we drop the struct_mutex,
i.e. we need to schedule a worker to do the clean up. A further issue
spotted by Tvrtko was caused when we took a GTT mmapping of a userptr
buffer object. In that case, we would never call mmput as the object
would be cyclically referenced by the GTT mmapping and not freed upon
process exit - keeping the entire process mm alive after the process
task was reaped. The fix employed is to replace the mm_users/mmput()
reference handling to mm_count/mmdrop() for the shared i915_mm_struct.

   INFO: task test_surfaces:1632 blocked for more than 120 seconds.
         Tainted: GF          O 3.14.5+ #1
   "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
   test_surfaces   D 0000000000000000     0  1632   1590 0x00000082
    ffff88014914baa8 0000000000000046 0000000000000000 ffff88014914a010
    0000000000012c40 0000000000012c40 ffff8800a0058210 ffff88014784b010
    ffff88014914a010 ffff880037b1c820 ffff8800a0058210 ffff880037b1c824
   Call Trace:
    [<ffffffff81582499>] schedule+0x29/0x70
    [<ffffffff815825fe>] schedule_preempt_disabled+0xe/0x10
    [<ffffffff81583b93>] __mutex_lock_slowpath+0x183/0x220
    [<ffffffff81583c53>] mutex_lock+0x23/0x40
    [<ffffffffa005c2a3>] drm_gem_vm_close+0x33/0x70 [drm]
    [<ffffffff8115a483>] remove_vma+0x33/0x70
    [<ffffffff8115a5dc>] exit_mmap+0x11c/0x170
    [<ffffffff8104d6eb>] mmput+0x6b/0x100
    [<ffffffffa00f44b9>] i915_gem_userptr_release+0x89/0xc0 [i915]
    [<ffffffffa00e6706>] i915_gem_free_object+0x126/0x250 [i915]
    [<ffffffffa005c06a>] drm_gem_object_free+0x2a/0x40 [drm]
    [<ffffffffa005cc32>] drm_gem_object_handle_unreference_unlocked+0xe2/0x120 [drm]
    [<ffffffffa005ccd4>] drm_gem_object_release_handle+0x64/0x90 [drm]
    [<ffffffff8127ffeb>] idr_for_each+0xab/0x100
    [<ffffffffa005cc70>] ?  drm_gem_object_handle_unreference_unlocked+0x120/0x120 [drm]
    [<ffffffff81583c46>] ? mutex_lock+0x16/0x40
    [<ffffffffa005c354>] drm_gem_release+0x24/0x40 [drm]
    [<ffffffffa005b82b>] drm_release+0x3fb/0x480 [drm]
    [<ffffffff8118d482>] __fput+0xb2/0x260
    [<ffffffff8118d6de>] ____fput+0xe/0x10
    [<ffffffff8106f27f>] task_work_run+0x8f/0xf0
    [<ffffffff81052228>] do_exit+0x1a8/0x480
    [<ffffffff81052551>] do_group_exit+0x51/0xc0
    [<ffffffff810525d7>] SyS_exit_group+0x17/0x20
    [<ffffffff8158e092>] system_call_fastpath+0x16/0x1b

v2: Incorporate feedback from Tvrtko and remove the unnessary mm
referencing when creating the i915_mm_struct and improve some of the
function names and comments.

Reported-by: Jacek Danecki <jacek.danecki@intel.com>
Test-case: igt/gem_userptr_blits/process-exit*
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Tested-by: "Gong, Zhipeng" <zhipeng.gong@intel.com>
Cc: Jacek Danecki <jacek.danecki@intel.com>
Cc: "Ursulin, Tvrtko" <tvrtko.ursulin@intel.com>
Reviewed-by: "Ursulin, Tvrtko" <tvrtko.ursulin@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@vger.kernel.org # hold off until 3.17 ships for additional testing
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2014-09-08 08:38:49 +03:00
..
dvo_ch7xxx.c drm/i915: Remove spurious semicolons 2014-04-09 21:54:33 +02:00
dvo_ch7017.c
dvo_ivch.c drm/i915: Remove spurious semicolons 2014-04-09 21:54:33 +02:00
dvo_ns2501.c drm/i915: Remove spurious semicolons 2014-04-09 21:54:33 +02:00
dvo_sil164.c drm/i915: Remove spurious semicolons 2014-04-09 21:54:33 +02:00
dvo_tfp410.c drm/i915: Remove spurious semicolons 2014-04-09 21:54:33 +02:00
dvo.h
i915_cmd_parser.c drm/i915: Add some L3 registers to the parser whitelist 2014-06-18 00:48:35 +02:00
i915_debugfs.c Merge remote-tracking branch 'airlied/drm-next' into drm-intel-next 2014-07-29 20:49:36 +02:00
i915_dma.c Linux 3.16 2014-08-05 09:04:59 +10:00
i915_drv.c drm/i915: make sure VDD is turned off during system suspend 2014-08-18 16:49:36 +03:00
i915_drv.h drm/i915: Prevent recursive deadlock on releasing a busy userptr 2014-09-08 08:38:49 +03:00
i915_gem_context.c drm/i915: Reorder ctx unref on ppgtt cleanup 2014-07-23 07:05:39 +02:00
i915_gem_debug.c
i915_gem_dmabuf.c dma-buf: use reservation objects 2014-07-08 13:03:20 -07:00
i915_gem_evict.c drm/i915: Prevent negative relocation deltas from wrapping 2014-05-27 11:18:40 +03:00
i915_gem_execbuffer.c Revert "drm: drop redundant drm_file->is_master" 2014-08-08 07:30:53 +10:00
i915_gem_gtt.c drm/i915: work around warning in i915_gem_gtt 2014-08-07 11:07:15 +02:00
i915_gem_gtt.h drm/i915: Added write-enable pte bit supportt 2014-06-17 09:21:47 +02:00
i915_gem_render_state.c drm/i915: fix freeze with blank screen booting highmem 2014-07-22 08:10:36 +02:00
i915_gem_stolen.c Linux 3.16 2014-08-05 09:04:59 +10:00
i915_gem_tiling.c
i915_gem_userptr.c drm/i915: Prevent recursive deadlock on releasing a busy userptr 2014-09-08 08:38:49 +03:00
i915_gem.c Merge tag 'drm-intel-fixes-2014-08-08' of git://anongit.freedesktop.org/drm-intel 2014-08-08 10:24:36 -07:00
i915_gpu_error.c drm/i915: Fix DEIER and GTIER collecting for BDW. 2014-08-07 14:04:08 +02:00
i915_ioc32.c drm: Remove DRM_ARRAY_SIZE() for ARRAY_SIZE() 2014-06-10 09:36:17 +10:00
i915_irq.c drm/i915: fix HPD IRQ reenable work cancelation 2014-08-18 16:16:00 +03:00
i915_params.c Revert "drm/i915: Enable PSR by default." 2014-08-08 11:48:26 -10:00
i915_reg.h drm/i915: Fix drain latency precision multipler for VLV 2014-08-07 11:07:21 +02:00
i915_suspend.c drm/i915: disable GT power saving early during system suspend 2014-05-22 21:53:27 +02:00
i915_sysfs.c drm/i915/chv: calculate rc6 residency correctly 2014-07-12 11:13:47 +02:00
i915_trace_points.c
i915_trace.h drm/i915: s/intel_ring_buffer/intel_engine_cs 2014-05-22 23:01:05 +02:00
i915_ums.c
intel_acpi.c
intel_bios.c drm/i915: Remove bogus __init annotation from DMI callbacks 2014-08-28 09:54:27 +03:00
intel_bios.h drm/i915: Detect if MIPI panel based on VBT and initialize only if present 2014-06-05 08:52:33 +02:00
intel_crt.c drm/i915: Remove bogus __init annotation from DMI callbacks 2014-08-28 09:54:27 +03:00
intel_ddi.c Merge tag 'drm-intel-next-2014-07-25-merged' of git://anongit.freedesktop.org/drm-intel into drm-next 2014-08-04 17:57:34 +10:00
intel_display.c drm/i915: Move intel_ddi_set_vc_payload_alloc(false) to haswell_crtc_disable() 2014-08-26 15:01:18 +03:00
intel_dp_mst.c drm/i915: fix build without fbdev. 2014-07-22 20:11:29 +10:00
intel_dp.c drm/i915: handle G45/GM45 pulse detection connected state. 2014-09-01 16:47:01 +03:00
intel_drv.h drm/i915: make sure VDD is turned off during system suspend 2014-08-18 16:49:36 +03:00
intel_dsi_cmd.c drm/i915: wait for all DSI FIFOs to be empty 2014-08-07 11:07:15 +02:00
intel_dsi_cmd.h drm/i915: wait for all DSI FIFOs to be empty 2014-08-07 11:07:15 +02:00
intel_dsi_panel_vbt.c drm/i915: Fix checkpatch errors 2014-06-11 16:57:33 +02:00
intel_dsi_pll.c drm/i915: Add correct hw/sw config check for DSI encoder 2014-08-07 11:07:17 +02:00
intel_dsi.c drm/i915: Add correct hw/sw config check for DSI encoder 2014-08-07 11:07:17 +02:00
intel_dsi.h drm/i915: Add correct hw/sw config check for DSI encoder 2014-08-07 11:07:17 +02:00
intel_dvo.c Merge tag 'drm-intel-next-2014-06-20' of git://anongit.freedesktop.org/drm-intel into drm-next 2014-07-09 10:38:42 +10:00
intel_fbdev.c drm/i915: fix initial fbdev setup warnings 2014-07-24 10:27:42 +10:00
intel_hdmi.c Merge remote-tracking branch 'airlied/drm-next' into drm-intel-next 2014-07-29 20:49:36 +02:00
intel_i2c.c drm/i915: Kill duplicated cdclk readout code from i2c 2014-07-07 11:27:52 +02:00
intel_lvds.c drm/i915: Remove bogus __init annotation from DMI callbacks 2014-08-28 09:54:27 +03:00
intel_modes.c
intel_opregion.c Linux 3.16 2014-08-05 09:04:59 +10:00
intel_overlay.c drm/i915: use helpers 2014-07-18 14:25:15 +10:00
intel_panel.c drm/i915: don't warn if backlight unexpectedly enabled 2014-08-27 11:23:10 +03:00
intel_pm.c Merge tag 'drm-intel-fixes-2014-08-08' of git://anongit.freedesktop.org/drm-intel 2014-08-08 10:24:36 -07:00
intel_renderstate_gen6.c drm/i915: Simplify processing of the golden render context state 2014-06-16 19:53:09 +02:00
intel_renderstate_gen7.c drm/i915: Simplify processing of the golden render context state 2014-06-16 19:53:09 +02:00
intel_renderstate_gen8.c drm/i915: Simplify processing of the golden render context state 2014-06-16 19:53:09 +02:00
intel_renderstate.h drm/i915: Simplify processing of the golden render context state 2014-06-16 19:53:09 +02:00
intel_ringbuffer.c drm/i915: read HEAD register back in init_ring_common() to enforce ordering 2014-08-08 16:22:18 +02:00
intel_ringbuffer.h drm/i915: Don't accumulate hangcheck score on forward progress 2014-08-07 14:04:07 +02:00
intel_sdvo_regs.h
intel_sdvo.c Merge tag 'topic/core-stuff-2014-06-30' of git://anongit.freedesktop.org/drm-intel into drm-next 2014-07-08 11:04:35 +10:00
intel_sideband.c drm/i915: vlv/chv: fix DSI sideband register accessing 2014-05-19 17:50:14 +02:00
intel_sprite.c Merge remote-tracking branch 'airlied/drm-next' into drm-intel-next 2014-07-29 20:49:36 +02:00
intel_tv.c drm/i915: Fix lock dropping in intel_tv_detect() 2014-09-02 12:58:51 +03:00
intel_uncore.c drm/i915: BDW can also detect unclaimed registers 2014-07-23 07:05:37 +02:00
Kconfig drm/i915: Ditch UMS config option 2014-07-24 10:59:53 +02:00
Makefile drm/i915: add DP 1.2 MST support (v0.7) 2014-07-22 11:20:26 +10:00