drm/nouveau/dispnv50: Fix runtime PM ref tracking for non-blocking modesets
authorLyude Paul <lyude@redhat.com>
Wed, 7 Aug 2019 23:47:06 +0000 (19:47 -0400)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 23 Aug 2019 02:55:34 +0000 (12:55 +1000)
commited22eb56f2bf2908fef7a108809ffa208ff62c0c
tree2e72e1eec2391c3f8f853944c368686d3de403e3
parent2b7e7bb16812cd3a8f85f1d8e2752ab66130a0fe
drm/nouveau/dispnv50: Fix runtime PM ref tracking for non-blocking modesets

This is something that got noticed a while ago back when I was fixing a
large number of runtime PM related issues in nouveau, but never got
fixed:

https://patchwork.freedesktop.org/series/46815/#rev7

It's not safe to iterate the entire list of CRTCs in
nv50_disp_atomic_commit(), as we could be doing a non-blocking modeset
on one CRTC in parallel with one or more other CRTCs. Likewise, this
means it's also not safe to do so in order to track runtime PM state.
While this code is certainly wrong, so far the only issues I've seen
this cause in the wild is the occasional PM ref unbalance after an
atomic check failure + module reloading (since the PCI device will
outlive nouveau in such scenarios).

So, do this far more elegantly: grab a runtime PM ref across the modeset
and commit tail, then grab/put references for each CRTC enable/disable.
This also ends up being much simpler then the previous broken solution
we had.

Finally, since we've removed all it's users: get rid of
nouveau_drm->have_disp_power_ref.

Signed-off-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/dispnv50/disp.c
drivers/gpu/drm/nouveau/nouveau_drv.h