2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2025-01-07 05:04:04 +08:00
linux-next/drivers/gpu/drm/nouveau
Lukas Wunner d61a5c1063 drm/nouveau: Fix deadlock on runtime suspend
nouveau'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
nouveau_connector_detect() which waits for the ongoing suspend to finish,
causing a deadlock.

Fix by not acquiring a runtime PM ref if nouveau_connector_detect() is
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.

Other contexts calling nouveau_connector_detect() do require a runtime
PM ref, these comprise:

  status_store() drm sysfs interface
  ->fill_modes drm callback
  drm_fb_helper_probe_connector_modes()
  drm_mode_getconnector()
  nouveau_connector_hotplug()
  nouveau_display_hpd_work()
  nv17_tv_set_property()

Stack trace for posterity:

  INFO: task kworker/0:1:58 blocked for more than 120 seconds.
  Workqueue: events output_poll_execute [drm_kms_helper]
  Call Trace:
   schedule+0x28/0x80
   rpm_resume+0x107/0x6e0
   __pm_runtime_resume+0x47/0x70
   nouveau_connector_detect+0x7e/0x4a0 [nouveau]
   nouveau_connector_detect_lvds+0x132/0x180 [nouveau]
   drm_helper_probe_detect_ctx+0x85/0xd0 [drm_kms_helper]
   output_poll_execute+0x11e/0x1c0 [drm_kms_helper]
   process_one_work+0x184/0x380
   worker_thread+0x2e/0x390

  INFO: task kworker/0:2:252 blocked for more than 120 seconds.
  Workqueue: pm pm_runtime_work
  Call Trace:
   schedule+0x28/0x80
   schedule_timeout+0x1e3/0x370
   wait_for_completion+0x123/0x190
   flush_work+0x142/0x1c0
   nouveau_pmops_runtime_suspend+0x7e/0xd0 [nouveau]
   pci_pm_runtime_suspend+0x5c/0x180
   vga_switcheroo_runtime_suspend+0x1e/0xa0
   __rpm_callback+0xc1/0x200
   rpm_callback+0x1f/0x70
   rpm_suspend+0x13c/0x640
   pm_runtime_work+0x6e/0x90
   process_one_work+0x184/0x380
   worker_thread+0x2e/0x390

Bugzilla: https://bugs.archlinux.org/task/53497
Bugzilla: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=870523
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70388#c33
Fixes: 5addcf0a5f ("nouveau: add runtime PM support (v0.9)")
Cc: stable@vger.kernel.org # v3.12+: 27d4ee0307: workqueue: Allow retrieval of current task's work struct
Cc: stable@vger.kernel.org # v3.12+: 25c058ccaf: drm: Allow determining if current task is output poll worker
Cc: Ben Skeggs <bskeggs@redhat.com>
Cc: Dave Airlie <airlied@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Link: https://patchwork.freedesktop.org/patch/msgid/b7d2cbb609a80f59ccabfdf479b9d5907c603ea1.1518338789.git.lukas@wunner.de
2018-02-16 22:32:26 +01:00
..
dispnv04 main drm pull request for v4.15 2017-11-15 20:42:10 -08:00
include main drm pull request for v4.15 2017-11-15 20:42:10 -08:00
nvif drm/nouveau/mmu: define user interfaces to mmu vmm opertaions 2017-11-02 13:32:31 +10:00
nvkm Merge branch 'linux-4.15' of git://github.com/skeggsb/linux into drm-fixes 2018-01-09 12:03:10 +10:00
Kbuild drm/nouveau: separate constant-va tracking from nvkm vma structure 2017-11-02 13:32:21 +10:00
Kconfig drm/nouveau/mmu: implement new vmm backend 2017-11-02 13:32:27 +10:00
nouveau_abi16.c drm/nouveau: remove trivial cases of nvxx_device() usage 2017-11-02 13:32:32 +10:00
nouveau_abi16.h main drm pull request for v4.15 2017-11-15 20:42:10 -08:00
nouveau_acpi.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
nouveau_acpi.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
nouveau_backlight.c drm/nouveau: allocate device object for every client 2017-02-17 15:15:04 +10:00
nouveau_bios.c drm/nouveau/bios: make const arrays hwsq_signature and edid_sig static 2017-11-03 09:12:10 +10:00
nouveau_bios.h drm/nouveau/nouveau: bios pointers may be unaligned, use proper accessors 2016-10-12 17:29:02 +10:00
nouveau_bo.c drm/nouveau: use alternate memory type for system-memory buffers with kind != 0 2017-12-19 10:16:37 +10:00
nouveau_bo.h main drm pull request for v4.15 2017-11-15 20:42:10 -08:00
nouveau_chan.c drm/nouveau: switch over to new memory and vmm interfaces 2017-11-02 13:32:33 +10:00
nouveau_chan.h main drm pull request for v4.15 2017-11-15 20:42:10 -08:00
nouveau_connector.c drm/nouveau: Fix deadlock on runtime suspend 2018-02-16 22:32:26 +01:00
nouveau_connector.h drm: Don't include <drm/drm_encoder.h> in <drm/drm_crtc.h> 2016-12-18 16:29:29 +05:30
nouveau_crtc.h drm: nouveau: remove dead code and pointless local lut storage 2017-08-04 11:36:11 +02:00
nouveau_debugfs.c drm/nouveau: Remove nouveau_drm_debugfs_cleanup() 2017-03-01 16:09:52 +01:00
nouveau_debugfs.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
nouveau_display.c drm/nouveau/kms/nv04-nv40: prevent undisplayable framebuffers from creation 2017-08-22 18:04:34 +10:00
nouveau_display.h main drm pull request for v4.15 2017-11-15 20:42:10 -08:00
nouveau_dma.c drm/nouveau: separate constant-va tracking from nvkm vma structure 2017-11-02 13:32:21 +10:00
nouveau_dma.h drm/nouveau: separate constant-va tracking from nvkm vma structure 2017-11-02 13:32:21 +10:00
nouveau_dp.c drm/nouveau/kms/nv50: initial support for DP 1.2 multi-stream 2016-11-07 14:05:03 +10:00
nouveau_drm.c drm/nouveau: fix race when adding delayed work items 2017-12-23 08:56:59 +10:00
nouveau_drv.h Merge branch 'linux-4.15' of git://github.com/skeggsb/linux into drm-fixes 2017-12-19 13:21:11 +10:00
nouveau_encoder.h drm/nouveau/disp: introduce acquire/release display path methods 2017-06-16 14:04:57 +10:00
nouveau_fbcon.c drm/nouveau/fbcon: fix NULL pointer access in nouveau_fbcon_destroy 2017-12-19 10:16:37 +10:00
nouveau_fbcon.h drm/nouveau/fbcon: refcount the drm_framebuffer 2016-11-07 14:04:44 +10:00
nouveau_fence.c drm/nouveau: remove unused nouveau_fence_work() 2017-11-02 13:32:33 +10:00
nouveau_fence.h main drm pull request for v4.15 2017-11-15 20:42:10 -08:00
nouveau_gem.c drm/nouveau/mmu: remove old vmm frontend 2017-11-02 13:32:33 +10:00
nouveau_gem.h main drm pull request for v4.15 2017-11-15 20:42:10 -08:00
nouveau_hwmon.c drm/nouveau/hwmon: Change permissions to numeric 2017-06-16 14:05:03 +10:00
nouveau_hwmon.h
nouveau_ioc32.c
nouveau_ioctl.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
nouveau_led.c drm/nouveau/drm/nouveau/led: prevent a possible use-after-free 2017-02-17 17:38:07 +10:00
nouveau_led.h drm/nouveau/nouveau/led: prevent compiling the led-code if nouveau=y and leds=m 2017-01-31 20:05:25 +10:00
nouveau_mem.c drm/nouveau: use alternate memory type for system-memory buffers with kind != 0 2017-12-19 10:16:37 +10:00
nouveau_mem.h drm/nouveau: switch over to new memory and vmm interfaces 2017-11-02 13:32:33 +10:00
nouveau_nvif.c drm/nouveau/core/client: pass notification callback to nvkm_client_new 2017-02-17 15:15:00 +10:00
nouveau_platform.c drm/nouveau/platform: support for probing GP10B 2017-04-06 14:39:04 +10:00
nouveau_platform.h drm/nouveau: rename nouveau_drm.h to nouveau_drv.h 2016-05-20 14:43:04 +10:00
nouveau_prime.c drm/nouveau: pass nvif_client to nouveau_bo_new() instead of drm_device 2017-02-17 15:15:02 +10:00
nouveau_reg.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
nouveau_sgdma.c main drm pull request for v4.15 2017-11-15 20:42:10 -08:00
nouveau_ttm.c drm/nouveau: use alternate memory type for system-memory buffers with kind != 0 2017-12-19 10:16:37 +10:00
nouveau_ttm.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
nouveau_usif.c drm: Remove drm_pending_event->pid 2017-03-14 14:38:33 +01:00
nouveau_usif.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
nouveau_vga.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
nouveau_vga.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
nouveau_vmm.c drm/nouveau: fix obvious memory leak 2017-12-20 08:40:36 +10:00
nouveau_vmm.h drm/nouveau/mmu: remove old vmm frontend 2017-11-02 13:32:33 +10:00
nv04_fbcon.c drm/nouveau: allocate device object for every client 2017-02-17 15:15:04 +10:00
nv04_fence.c dma-buf: Rename struct fence to dma_fence 2016-10-25 14:40:39 +02:00
nv10_fence.c drm/nouveau/kms/nv50: remove code to support non-atomic page flips 2016-11-07 14:05:01 +10:00
nv10_fence.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
nv17_fence.c drm/nouveau: s/mem/reg/ for struct ttm_mem_reg variables 2017-02-17 15:15:04 +10:00
nv50_display.c main drm pull request for v4.15 2017-11-15 20:42:10 -08:00
nv50_display.h drm/nouveau/kms/nv50: remove code to support non-atomic page flips 2016-11-07 14:05:01 +10:00
nv50_fbcon.c drm/nouveau: separate constant-va tracking from nvkm vma structure 2017-11-02 13:32:21 +10:00
nv50_fence.c drm/nouveau: s/mem/reg/ for struct ttm_mem_reg variables 2017-02-17 15:15:04 +10:00
nv84_fence.c drm/nouveau: separate constant-va tracking from nvkm vma structure 2017-11-02 13:32:21 +10:00
nvc0_fbcon.c drm/nouveau: separate constant-va tracking from nvkm vma structure 2017-11-02 13:32:21 +10:00
nvc0_fence.c drm/nouveau: rename nouveau_drm.h to nouveau_drv.h 2016-05-20 14:43:04 +10:00