diff mbox

drm/nouveau: fix suspend bug in nvc0 fence implementation

Message ID CAMuW1wcx8BEkase+S_+bmZp6b+CFunrmAd6PDNaZONFYLfpG-g@mail.gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Maarten Lankhorst Feb. 19, 2013, 10:20 a.m. UTC
Everywhere else the constant is multiplied by 16/4, so it looks like
nvc0_fence_suspend/resume is buggy here.

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

---

Comments

Marcin Ślusarz Feb. 19, 2013, 7:49 p.m. UTC | #1
On Tue, Feb 19, 2013 at 10:20:55AM +0000, Maarten Lankhorst wrote:
> Everywhere else the constant is multiplied by 16/4, so it looks like
> nvc0_fence_suspend/resume is buggy here.
> 
> Signed-off-by: Maarten Lankhorst <m.b.lankhorst@gmail.com>
> Cc: stable@vger.kernel.org [3.7+]

Yay. It will probably fix https://bugs.freedesktop.org/show_bug.cgi?id=59168.
(note: it doesn't apply on top of nouveau/master)

Reviewed-by: Marcin Slusarz <marcin.slusarz@gmail.com>

> ---
> 
> diff --git a/drivers/gpu/drm/nouveau/nvc0_fence.c
> b/drivers/gpu/drm/nouveau/nvc0_fence.c
> index 85a0e78..4f46d8b 100644
> --- a/drivers/gpu/drm/nouveau/nvc0_fence.c
> +++ b/drivers/gpu/drm/nouveau/nvc0_fence.c
> @@ -161,11 +161,12 @@ nvc0_fence_suspend(struct nouveau_drm *drm)
>  	struct nouveau_fifo *pfifo = nouveau_fifo(drm->device);
>  	struct nvc0_fence_priv *priv = drm->fence;
>  	int i;
> +	u32 chan = pfifo->max + 1;
> 
> -	priv->suspend = vmalloc((pfifo->max + 1) * sizeof(u32));
> +	priv->suspend = vmalloc(chan * sizeof(u32));
>  	if (priv->suspend) {
> -		for (i = 0; i <= pfifo->max; i++)
> -			priv->suspend[i] = nouveau_bo_rd32(priv->bo, i);
> +		for (i = 0; i < chan; i++)
> +			priv->suspend[i] = nouveau_bo_rd32(priv->bo, i * 16/4);
>  	}
> 
>  	return priv->suspend != NULL;
> @@ -177,10 +178,11 @@ nvc0_fence_resume(struct nouveau_drm *drm)
>  	struct nouveau_fifo *pfifo = nouveau_fifo(drm->device);
>  	struct nvc0_fence_priv *priv = drm->fence;
>  	int i;
> +	u32 chan = pfifo->max + 1;
> 
>  	if (priv->suspend) {
> -		for (i = 0; i <= pfifo->max; i++)
> -			nouveau_bo_wr32(priv->bo, i, priv->suspend[i]);
> +		for (i = 0; i < chan; i++)
> +			nouveau_bo_wr32(priv->bo, i * 16/4, priv->suspend[i]);
>  		vfree(priv->suspend);
>  		priv->suspend = NULL;
>  	}
Michael Weirauch Feb. 19, 2013, 9:09 p.m. UTC | #2
2013/2/19 Marcin Slusarz <marcin.slusarz@gmail.com>:
> Yay. It will probably fix https://bugs.freedesktop.org/show_bug.cgi?id=59168.
> (note: it doesn't apply on top of nouveau/master)

Please correct me if I am wrong, but doesn't nv84_fence_[resume,suspend]
on current nouveau-3.8.0_rc7 (master) which is "used" by nvc0_fence.c
"identical" to what this patch does?

nvc0_fence_create->
nv84_fence_create sets up:
	priv->base.suspend = nv84_fence_suspend;
	priv->base.resume = nv84_fence_resume;

There is no dedicated nvc0_fence_[resume,suspend] impl from what I grasped.

c.f.:
http://cgit.freedesktop.org/nouveau/linux-2.6/tree/drivers/gpu/drm/nouveau/nv84_fence.c#n178

Michael
Marcin Ślusarz Feb. 19, 2013, 9:17 p.m. UTC | #3
On Tue, Feb 19, 2013 at 10:09:12PM +0100, Michael Weirauch wrote:
> 2013/2/19 Marcin Slusarz <marcin.slusarz@gmail.com>:
> > Yay. It will probably fix https://bugs.freedesktop.org/show_bug.cgi?id=59168.
> > (note: it doesn't apply on top of nouveau/master)
> 
> Please correct me if I am wrong, but doesn't nv84_fence_[resume,suspend]
> on current nouveau-3.8.0_rc7 (master) which is "used" by nvc0_fence.c
> "identical" to what this patch does?
> 
> nvc0_fence_create->
> nv84_fence_create sets up:
> 	priv->base.suspend = nv84_fence_suspend;
> 	priv->base.resume = nv84_fence_resume;
> 
> There is no dedicated nvc0_fence_[resume,suspend] impl from what I grasped.
> 
> c.f.:
> http://cgit.freedesktop.org/nouveau/linux-2.6/tree/drivers/gpu/drm/nouveau/nv84_fence.c#n178

This patch is only for 3.7 and 3.8 kernels. Nouveau/master contains refactored
fence code which will be submitted for 3.9.

Marcin
Michael Weirauch Feb. 19, 2013, 9:25 p.m. UTC | #4
2013/2/19 Marcin Slusarz <marcin.slusarz@gmail.com>:
> This patch is only for 3.7 and 3.8 kernels. Nouveau/master contains refactored
> fence code which will be submitted for 3.9.

Then, nevertheless, nouveau/master - which apparently carries
identical code - doesn't
fix the issue (fdo#59168) for me. (Or I screw up big time.)

I am testing nouveau/master regularly when new commits arrive.

Michael
diff mbox

Patch

diff --git a/drivers/gpu/drm/nouveau/nvc0_fence.c
b/drivers/gpu/drm/nouveau/nvc0_fence.c
index 85a0e78..4f46d8b 100644
--- a/drivers/gpu/drm/nouveau/nvc0_fence.c
+++ b/drivers/gpu/drm/nouveau/nvc0_fence.c
@@ -161,11 +161,12 @@  nvc0_fence_suspend(struct nouveau_drm *drm)
 	struct nouveau_fifo *pfifo = nouveau_fifo(drm->device);
 	struct nvc0_fence_priv *priv = drm->fence;
 	int i;
+	u32 chan = pfifo->max + 1;

-	priv->suspend = vmalloc((pfifo->max + 1) * sizeof(u32));
+	priv->suspend = vmalloc(chan * sizeof(u32));
 	if (priv->suspend) {
-		for (i = 0; i <= pfifo->max; i++)
-			priv->suspend[i] = nouveau_bo_rd32(priv->bo, i);
+		for (i = 0; i < chan; i++)
+			priv->suspend[i] = nouveau_bo_rd32(priv->bo, i * 16/4);
 	}

 	return priv->suspend != NULL;
@@ -177,10 +178,11 @@  nvc0_fence_resume(struct nouveau_drm *drm)
 	struct nouveau_fifo *pfifo = nouveau_fifo(drm->device);
 	struct nvc0_fence_priv *priv = drm->fence;
 	int i;
+	u32 chan = pfifo->max + 1;

 	if (priv->suspend) {
-		for (i = 0; i <= pfifo->max; i++)
-			nouveau_bo_wr32(priv->bo, i, priv->suspend[i]);
+		for (i = 0; i < chan; i++)
+			nouveau_bo_wr32(priv->bo, i * 16/4, priv->suspend[i]);
 		vfree(priv->suspend);
 		priv->suspend = NULL;
 	}