Received: by 2002:a25:b794:0:0:0:0:0 with SMTP id n20csp6075828ybh; Wed, 7 Aug 2019 16:53:32 -0700 (PDT) X-Google-Smtp-Source: APXvYqzYgopbwCxTtb2ecgaClVxSoBN7xOsC/hX50vOuKLdPHGY+G7jJfN8ozMJVfl5ZDS2ST9oc X-Received: by 2002:a62:2b81:: with SMTP id r123mr11713212pfr.108.1565222012146; Wed, 07 Aug 2019 16:53:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1565222012; cv=none; d=google.com; s=arc-20160816; b=vQPK173i+sXYImbhMC1ggF0L1jvCLc8BQep2+EkBxM7nttExXMe+FeOdbbES8Zkvrm Vde8B5UyfpLgZooWxySdtkgfTVcFf3QPLYAD8kxIwAMvXhmhRDKJc00vYu7C/E5AweFz 1Torl+vcFhGuA9tYs0e9f7vul4uhw2JHVdrNtA2H8VVAw1MC2xtfOZkDwsO43nQpRg6q mByULkfJ+nSwGIIdAjim0N2WX3WPA9p2gKi1mw9ZGohhzrso4+8CTX44GQholi05RQXE Xs70AcFhnyr1v2kg7tDI6WCKXXQiVwxzymeYDAtsgdNrzrb9as9jCbTk8o2JZ0tE+dj0 Ps9A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=51lk85rmznon0hBMq0lZx3Xj5HHF63Xr8oihSeou4uE=; b=f2bKIsVe+BXHTcXMeX0BX/wdi/jC4MzVP1BLUWGyktqZzly1oRKRgctTv5AsNiLPHk /OaYv1LvJybGBiVQ1QuA48vt4ckH0cb893CE/VbpgWvUIdbxDqwF1pAPQ6HOCftATt7J s7wZmZfURlZFOlcolM7O4YKWPziUfLTtn0mzkMN7vVu3rkqjlDBXbZ1aksRlFoc8hfOa pNOESsFVeCuI6P6r+wBouhV9vCcM0Knvp0tmfRcq/RE3JbnlPmaDi3QDmVTe0HP7BOiZ g1DJGMzjaxn19I6D9b+uYRktcHZb6bBgJrIMBEVyKwPw9z+pFuNGLmSZDtmLo9FAx2mw NDJA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s38si51415512pgl.138.2019.08.07.16.53.15; Wed, 07 Aug 2019 16:53:32 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389082AbfHGXrZ (ORCPT + 99 others); Wed, 7 Aug 2019 19:47:25 -0400 Received: from mx1.redhat.com ([209.132.183.28]:42476 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388906AbfHGXrY (ORCPT ); Wed, 7 Aug 2019 19:47:24 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D1C92EE58F; Wed, 7 Aug 2019 23:47:23 +0000 (UTC) Received: from whitewolf.redhat.com (ovpn-121-222.rdu2.redhat.com [10.10.121.222]) by smtp.corp.redhat.com (Postfix) with ESMTP id 800E35D9E1; Wed, 7 Aug 2019 23:47:22 +0000 (UTC) From: Lyude Paul To: nouveau@lists.freedesktop.org Cc: Ben Skeggs , David Airlie , Daniel Vetter , Karol Herbst , Laurent Pinchart , Ilia Mirkin , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 2/2] drm/nouveau/dispnv50: Fix runtime PM ref tracking for non-blocking modesets Date: Wed, 7 Aug 2019 19:47:06 -0400 Message-Id: <20190807234709.6076-3-lyude@redhat.com> In-Reply-To: <20190807234709.6076-1-lyude@redhat.com> References: <20190807234709.6076-1-lyude@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 07 Aug 2019 23:47:23 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 38 +++++++++++-------------- drivers/gpu/drm/nouveau/nouveau_drv.h | 3 -- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 126703816794..659e6fa645cb 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1826,8 +1826,11 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) NV_ATOMIC(drm, "%s: clr %04x (set %04x)\n", crtc->name, asyh->clr.mask, asyh->set.mask); - if (old_crtc_state->active && !new_crtc_state->active) + + if (old_crtc_state->active && !new_crtc_state->active) { + pm_runtime_put_noidle(dev->dev); drm_crtc_vblank_off(crtc); + } if (asyh->clr.mask) { nv50_head_flush_clr(head, asyh, atom->flush_disable); @@ -1913,8 +1916,10 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) } if (new_crtc_state->active) { - if (!old_crtc_state->active) + if (!old_crtc_state->active) { drm_crtc_vblank_on(crtc); + pm_runtime_get_noresume(dev->dev); + } if (new_crtc_state->event) drm_crtc_vblank_get(crtc); } @@ -1979,6 +1984,10 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) drm_atomic_helper_cleanup_planes(dev, state); drm_atomic_helper_commit_cleanup_done(state); drm_atomic_state_put(state); + + /* Drop the RPM ref we got from nv50_disp_atomic_commit() */ + pm_runtime_mark_last_busy(dev->dev); + pm_runtime_put_autosuspend(dev->dev); } static void @@ -1993,11 +2002,8 @@ static int nv50_disp_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state, bool nonblock) { - struct nouveau_drm *drm = nouveau_drm(dev); struct drm_plane_state *new_plane_state; struct drm_plane *plane; - struct drm_crtc *crtc; - bool active = false; int ret, i; ret = pm_runtime_get_sync(dev->dev); @@ -2034,27 +2040,17 @@ nv50_disp_atomic_commit(struct drm_device *dev, drm_atomic_state_get(state); + /* + * Grab another RPM ref for the commit tail, which will release the + * ref when it's finished + */ + pm_runtime_get_noresume(dev->dev); + if (nonblock) queue_work(system_unbound_wq, &state->commit_work); else nv50_disp_atomic_commit_tail(state); - drm_for_each_crtc(crtc, dev) { - if (crtc->state->active) { - if (!drm->have_disp_power_ref) { - drm->have_disp_power_ref = true; - return 0; - } - active = true; - break; - } - } - - if (!active && drm->have_disp_power_ref) { - pm_runtime_put_autosuspend(dev->dev); - drm->have_disp_power_ref = false; - } - err_cleanup: if (ret) drm_atomic_helper_cleanup_planes(dev, state); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index aae035816383..411352dd5390 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -204,9 +204,6 @@ struct nouveau_drm { /* led management */ struct nouveau_led *led; - /* display power reference */ - bool have_disp_power_ref; - struct dev_pm_domain vga_pm_domain; struct nouveau_svm *svm; -- 2.21.0