Noticed two problems here: * We're not dropping our runtime PM refs after getting an error * We're not backing off when pm_runtime_get() indicates that there's already a resume in progress (-EINPROGRESS) (after which any delayed fbcon events will get handled anyway) So, let's fix those. Signed-off-by: Lyude Paul <lyude@xxxxxxxxxx> Fixes: 7fec8f5379fb ("drm/nouveau/drm/nouveau: Fix deadlock with fb_helper with async RPM requests") Cc: stable@xxxxxxxxxxxxxxx Cc: Ben Skeggs <bskeggs@xxxxxxxxxx> Cc: dri-devel@xxxxxxxxxxxxxxxxxxxxx Cc: nouveau@xxxxxxxxxxxxxxxxxxxxx Cc: <stable@xxxxxxxxxxxxxxx> # v4.19+ --- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 4d9f3b5ae72d2..b936bf1c14dec 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -503,10 +503,7 @@ nouveau_fbcon_output_poll_changed(struct drm_device *dev) ret = pm_runtime_get(dev->dev); if (ret == 1 || ret == -EACCES) { drm_fb_helper_hotplug_event(&fbcon->helper); - - pm_runtime_mark_last_busy(dev->dev); - pm_runtime_put_autosuspend(dev->dev); - } else if (ret == 0) { + } else if (ret == 0 || ret == -EINPROGRESS) { /* If the GPU was already in the process of suspending before * this event happened, then we can't block here as we'll * deadlock the runtime pmops since they wait for us to @@ -516,11 +513,15 @@ nouveau_fbcon_output_poll_changed(struct drm_device *dev) NV_DEBUG(drm, "fbcon HPD event deferred until runtime resume\n"); fbcon->hotplug_waiting = true; pm_runtime_put_noidle(drm->dev->dev); + goto out; } else { DRM_WARN("fbcon HPD event lost due to RPM failure: %d\n", ret); } + pm_runtime_mark_last_busy(dev->dev); + pm_runtime_put_autosuspend(dev->dev); +out: mutex_unlock(&fbcon->hotplug_lock); } -- 2.26.2