linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] drm/nouveau: CRTC Runtime PM ref tracking fixes
@ 2019-08-07 23:47 Lyude Paul
  2019-08-07 23:47 ` [PATCH v2 1/2] drm/nouveau/dispnv04: Remove runtime PM Lyude Paul
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Lyude Paul @ 2019-08-07 23:47 UTC (permalink / raw)
  To: nouveau
  Cc: Daniel Vetter, David Airlie, linux-kernel, dri-devel, Ben Skeggs,
	Lyude Paul, Laurent Pinchart, Karol Herbst, Ilia Mirkin

Just some runtime PM fixes for some much less noticeable runtime PM ref
tracking issues that I got reminded of when fixing some unrelated issues
with nouveau.

Changes since v1:
* Don't fix CRTC RPM code in dispnv04, because it's not actually doing
  anything in the first place. Just get rid of it. - imirkin

Lyude Paul (2):
  drm/nouveau/dispnv04: Remove runtime PM
  drm/nouveau/dispnv50: Fix runtime PM ref tracking for non-blocking
    modesets

 drivers/gpu/drm/nouveau/dispnv04/crtc.c | 51 +------------------------
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 38 +++++++++---------
 drivers/gpu/drm/nouveau/nouveau_drv.h   |  3 --
 3 files changed, 18 insertions(+), 74 deletions(-)

-- 
2.21.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2 1/2] drm/nouveau/dispnv04: Remove runtime PM
  2019-08-07 23:47 [PATCH v2 0/2] drm/nouveau: CRTC Runtime PM ref tracking fixes Lyude Paul
@ 2019-08-07 23:47 ` Lyude Paul
  2019-08-07 23:47 ` [PATCH v2 2/2] drm/nouveau/dispnv50: Fix runtime PM ref tracking for non-blocking modesets Lyude Paul
  2019-08-13  4:42 ` [PATCH v2 0/2] drm/nouveau: CRTC Runtime PM ref tracking fixes Ben Skeggs
  2 siblings, 0 replies; 4+ messages in thread
From: Lyude Paul @ 2019-08-07 23:47 UTC (permalink / raw)
  To: nouveau; +Cc: Ben Skeggs, David Airlie, Daniel Vetter, dri-devel, linux-kernel

Originally when trying to fix the issue of runtime PM references with
non-blocking CRTCs on nv50, I ended up stumbling on this code when
trying to remove nouveau_drm->have_disp_power_ref, and attempted to fix
it to remove the dependency on have_disp_power_ref. However, Ilia Mirkin
pointed out that this code is actually completely useless, as pre-nv50
never had runtime PM support in the first place! Go figure.

So, since it's useless just get rid of it. Note that since the only
thing nouveau_crtc_set_config() was doing was grabbing a runtime PM ref,
calling drm_crtc_helper_set_config() then dropping the ref; we can just
remove the function entirely and just call drm_crtc_helper_set_config()
directly.

Signed-off-by: Lyude Paul <lyude@redhat.com>
---
 drivers/gpu/drm/nouveau/dispnv04/crtc.c | 51 +------------------------
 1 file changed, 1 insertion(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
index f22f01020625..050eb5b7dd13 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
@@ -22,8 +22,6 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
-#include <linux/pm_runtime.h>
-
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_plane_helper.h>
@@ -1031,53 +1029,6 @@ nv04_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
 	return 0;
 }
 
-static int
-nouveau_crtc_set_config(struct drm_mode_set *set,
-			struct drm_modeset_acquire_ctx *ctx)
-{
-	struct drm_device *dev;
-	struct nouveau_drm *drm;
-	int ret;
-	struct drm_crtc *crtc;
-	bool active = false;
-	if (!set || !set->crtc)
-		return -EINVAL;
-
-	dev = set->crtc->dev;
-
-	/* get a pm reference here */
-	ret = pm_runtime_get_sync(dev->dev);
-	if (ret < 0 && ret != -EACCES)
-		return ret;
-
-	ret = drm_crtc_helper_set_config(set, ctx);
-
-	drm = nouveau_drm(dev);
-
-	/* if we get here with no crtcs active then we can drop a reference */
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		if (crtc->enabled)
-			active = true;
-	}
-
-	pm_runtime_mark_last_busy(dev->dev);
-	/* if we have active crtcs and we don't have a power ref,
-	   take the current one */
-	if (active && !drm->have_disp_power_ref) {
-		drm->have_disp_power_ref = true;
-		return ret;
-	}
-	/* if we have no active crtcs, then drop the power ref
-	   we got before */
-	if (!active && drm->have_disp_power_ref) {
-		pm_runtime_put_autosuspend(dev->dev);
-		drm->have_disp_power_ref = false;
-	}
-	/* drop the power reference we got coming in here */
-	pm_runtime_put_autosuspend(dev->dev);
-	return ret;
-}
-
 struct nv04_page_flip_state {
 	struct list_head head;
 	struct drm_pending_vblank_event *event;
@@ -1293,7 +1244,7 @@ static const struct drm_crtc_funcs nv04_crtc_funcs = {
 	.cursor_set = nv04_crtc_cursor_set,
 	.cursor_move = nv04_crtc_cursor_move,
 	.gamma_set = nv_crtc_gamma_set,
-	.set_config = nouveau_crtc_set_config,
+	.set_config = drm_crtc_helper_set_config,
 	.page_flip = nv04_crtc_page_flip,
 	.destroy = nv_crtc_destroy,
 };
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 2/2] drm/nouveau/dispnv50: Fix runtime PM ref tracking for non-blocking modesets
  2019-08-07 23:47 [PATCH v2 0/2] drm/nouveau: CRTC Runtime PM ref tracking fixes Lyude Paul
  2019-08-07 23:47 ` [PATCH v2 1/2] drm/nouveau/dispnv04: Remove runtime PM Lyude Paul
@ 2019-08-07 23:47 ` Lyude Paul
  2019-08-13  4:42 ` [PATCH v2 0/2] drm/nouveau: CRTC Runtime PM ref tracking fixes Ben Skeggs
  2 siblings, 0 replies; 4+ messages in thread
From: Lyude Paul @ 2019-08-07 23:47 UTC (permalink / raw)
  To: nouveau
  Cc: Ben Skeggs, David Airlie, Daniel Vetter, Karol Herbst,
	Laurent Pinchart, Ilia Mirkin, dri-devel, linux-kernel

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>
---
 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


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 0/2] drm/nouveau: CRTC Runtime PM ref tracking fixes
  2019-08-07 23:47 [PATCH v2 0/2] drm/nouveau: CRTC Runtime PM ref tracking fixes Lyude Paul
  2019-08-07 23:47 ` [PATCH v2 1/2] drm/nouveau/dispnv04: Remove runtime PM Lyude Paul
  2019-08-07 23:47 ` [PATCH v2 2/2] drm/nouveau/dispnv50: Fix runtime PM ref tracking for non-blocking modesets Lyude Paul
@ 2019-08-13  4:42 ` Ben Skeggs
  2 siblings, 0 replies; 4+ messages in thread
From: Ben Skeggs @ 2019-08-13  4:42 UTC (permalink / raw)
  To: Lyude Paul
  Cc: ML nouveau, David Airlie, linux-kernel, ML dri-devel,
	Karol Herbst, Ben Skeggs, Laurent Pinchart

On Thu, 8 Aug 2019 at 09:47, Lyude Paul <lyude@redhat.com> wrote:
>
> Just some runtime PM fixes for some much less noticeable runtime PM ref
> tracking issues that I got reminded of when fixing some unrelated issues
> with nouveau.
>
> Changes since v1:
> * Don't fix CRTC RPM code in dispnv04, because it's not actually doing
>   anything in the first place. Just get rid of it. - imirkin
>
> Lyude Paul (2):
>   drm/nouveau/dispnv04: Remove runtime PM
>   drm/nouveau/dispnv50: Fix runtime PM ref tracking for non-blocking
>     modesets
>
>  drivers/gpu/drm/nouveau/dispnv04/crtc.c | 51 +------------------------
>  drivers/gpu/drm/nouveau/dispnv50/disp.c | 38 +++++++++---------
>  drivers/gpu/drm/nouveau/nouveau_drv.h   |  3 --
>  3 files changed, 18 insertions(+), 74 deletions(-)
For the series:  Acked-by: Ben Skeggs <bskeggs@redhat.com>

>
> --
> 2.21.0
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-08-13  4:42 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-07 23:47 [PATCH v2 0/2] drm/nouveau: CRTC Runtime PM ref tracking fixes Lyude Paul
2019-08-07 23:47 ` [PATCH v2 1/2] drm/nouveau/dispnv04: Remove runtime PM Lyude Paul
2019-08-07 23:47 ` [PATCH v2 2/2] drm/nouveau/dispnv50: Fix runtime PM ref tracking for non-blocking modesets Lyude Paul
2019-08-13  4:42 ` [PATCH v2 0/2] drm/nouveau: CRTC Runtime PM ref tracking fixes Ben Skeggs

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).