• Lukas Wunner's avatar
    drm/radeon: Fix deadlock on runtime suspend · 15734fef
    Lukas Wunner authored
    radeon's ->runtime_suspend hook calls drm_kms_helper_poll_disable(),
    which waits for the output poll worker to finish if it's running.
    
    The output poll worker meanwhile calls pm_runtime_get_sync() in
    radeon's ->detect hooks, which waits for the ongoing suspend to finish,
    causing a deadlock.
    
    Fix by not acquiring a runtime PM ref if the ->detect hooks are called
    in the output poll worker's context.  This is safe because the poll
    worker is only enabled while runtime active and we know that
    ->runtime_suspend waits for it to finish.
    
    Stack trace for posterity:
    
      INFO: task kworker/0:3:31847 blocked for more than 120 seconds
      Workqueue: events output_poll_execute [drm_kms_helper]
      Call Trace:
       schedule+0x3c/0x90
       rpm_resume+0x1e2/0x690
       __pm_runtime_resume+0x3f/0x60
       radeon_lvds_detect+0x39/0xf0 [radeon]
       output_poll_execute+0xda/0x1e0 [drm_kms_helper]
       process_one_work+0x14b/0x440
       worker_thread+0x48/0x4a0
    
      INFO: task kworker/2:0:10493 blocked for more than 120 seconds.
      Workqueue: pm pm_runtime_work
      Call Trace:
       schedule+0x3c/0x90
       schedule_timeout+0x1b3/0x240
       wait_for_common+0xc2/0x180
       wait_for_completion+0x1d/0x20
       flush_work+0xfc/0x1a0
       __cancel_work_timer+0xa5/0x1d0
       cancel_delayed_work_sync+0x13/0x20
       drm_kms_helper_poll_disable+0x1f/0x30 [drm_kms_helper]
       radeon_pmops_runtime_suspend+0x3d/0xa0 [radeon]
       pci_pm_runtime_suspend+0x61/0x1a0
       vga_switcheroo_runtime_suspend+0x21/0x70
       __rpm_callback+0x32/0x70
       rpm_callback+0x24/0x80
       rpm_suspend+0x12b/0x640
       pm_runtime_work+0x6f/0xb0
       process_one_work+0x14b/0x440
       worker_thread+0x48/0x4a0
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94147
    Fixes: 10ebc0bc ("drm/radeon: add runtime PM support (v2)")
    Cc: stable@vger.kernel.org # v3.13+: 27d4ee03: workqueue: Allow retrieval of current task's work struct
    Cc: stable@vger.kernel.org # v3.13+: 25c058cc: drm: Allow determining if current task is output poll worker
    Cc: Ismo Toijala <ismo.toijala@gmail.com>
    Cc: Alex Deucher <alexander.deucher@amd.com>
    Cc: Dave Airlie <airlied@redhat.com>
    Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
    Signed-off-by: default avatarLukas Wunner <lukas@wunner.de>
    Link: https://patchwork.freedesktop.org/patch/msgid/64ea02c44f91dda19bc563902b97bbc699040392.1518338789.git.lukas@wunner.de
    15734fef
radeon_connectors.c 83.9 KB