diff mbox

drm/nouveau: idle all channels before suspending

Message ID 5162B231.2060900@canonical.com (mailing list archive)
State New, archived
Headers show

Commit Message

Maarten Lankhorst April 8, 2013, 12:04 p.m. UTC
Seems to make suspend slightly more reliable on my system.

Cc: stable@vger.kernel.org [3.7+]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
---

Comments

Ben Skeggs April 8, 2013, 11:14 p.m. UTC | #1
On Mon, Apr 8, 2013 at 10:04 PM, Maarten Lankhorst <
maarten.lankhorst@canonical.com> wrote:

> Seems to make suspend slightly more reliable on my system.
>
NACK.

"Seems to", and "slightly" don't make a very good argument for this.
 Likely all you've done is change the timing of certain things happening.

The PFIFO and engine (PGRAPH etc) modules already take care of idling and
unloading active channels.  If something is broken there, that's where it
needs fixing, not this hack that "maybe" "possibly" "slightly" works.

Ben.


> Cc: stable@vger.kernel.org [3.7+]
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
> ---
> diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c
> b/drivers/gpu/drm/nouveau/nouveau_drm.c
> index b6bdc9f..5032c31 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_drm.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
> @@ -464,6 +464,23 @@ nouveau_do_suspend(struct drm_device *dev)
>         NV_INFO(drm, "evicting buffers...\n");
>         ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM);
>
> +       list_for_each_entry(cli, &drm->clients, head) {
> +               struct nouveau_abi16 *abi16 = cli->abi16;
> +               struct nouveau_abi16_chan *chan;
> +
> +               if (!abi16)
> +                       continue;
> +
> +               list_for_each_entry(chan, &abi16->channels, head)
> +                       nouveau_channel_idle(chan->chan);
> +       }
> +
> +       if (drm->channel)
> +               nouveau_channel_idle(drm->channel);
> +
> +       if (drm->cechan)
> +               nouveau_channel_idle(drm->cechan);
> +
>         if (drm->fence && nouveau_fence(drm)->suspend) {
>                 if (!nouveau_fence(drm)->suspend(drm))
>                         return -ENOMEM;
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
Maarten Lankhorst April 9, 2013, 6:44 a.m. UTC | #2
Op 09-04-13 01:14, Ben Skeggs schreef:
> On Mon, Apr 8, 2013 at 10:04 PM, Maarten Lankhorst <
> maarten.lankhorst@canonical.com> wrote:
>
>> Seems to make suspend slightly more reliable on my system.
>>
> NACK.
>
> "Seems to", and "slightly" don't make a very good argument for this.
>  Likely all you've done is change the timing of certain things happening.
>
> The PFIFO and engine (PGRAPH etc) modules already take care of idling and
> unloading active channels.  If something is broken there, that's where it
> needs fixing, not this hack that "maybe" "possibly" "slightly" works.
The channel idle was not for PFIFO or PGRAPH, it's for nouveau_fence suspend.
If you want to save the fence seqnos, you have to be sure that all channels are idle first,
or move the saving of fence seqnos until after you're done with unloading all the fifo engines.

~Maarten
diff mbox

Patch

diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index b6bdc9f..5032c31 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -464,6 +464,23 @@  nouveau_do_suspend(struct drm_device *dev)
 	NV_INFO(drm, "evicting buffers...\n");
 	ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM);
 
+	list_for_each_entry(cli, &drm->clients, head) {
+		struct nouveau_abi16 *abi16 = cli->abi16;
+		struct nouveau_abi16_chan *chan;
+
+		if (!abi16)
+			continue;
+
+		list_for_each_entry(chan, &abi16->channels, head)
+			nouveau_channel_idle(chan->chan);
+	}
+
+	if (drm->channel)
+		nouveau_channel_idle(drm->channel);
+
+	if (drm->cechan)
+		nouveau_channel_idle(drm->cechan);
+
 	if (drm->fence && nouveau_fence(drm)->suspend) {
 		if (!nouveau_fence(drm)->suspend(drm))
 			return -ENOMEM;