drm/nouveau/fifo/g84-: ack non-stall interrupt before handling it
authorBen Skeggs <bskeggs@redhat.com>
Mon, 1 Dec 2014 01:44:27 +0000 (11:44 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 2 Dec 2014 05:33:22 +0000 (15:33 +1000)
Closes a very unlikely race that can occur if another NonStallInterrupt
method passes between checking fences and acking the previous interrupt.

With this change, the interrupt will re-fire under such conditions.

Tested-by: Tobias Klausmann <tobias.johannes.klausmann@mni.thm.de>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c
drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c

index 5ae6a43893b5996c0e13981851c71ed30947c5ad..1931057f996205d68ca93c94805211536c31aa4d 100644 (file)
@@ -551,8 +551,8 @@ nv04_fifo_intr(struct nouveau_subdev *subdev)
                        }
 
                        if (status & 0x40000000) {
-                               nouveau_fifo_uevent(&priv->base);
                                nv_wr32(priv, 0x002100, 0x40000000);
+                               nouveau_fifo_uevent(&priv->base);
                                status &= ~0x40000000;
                        }
                }
index 1fe1f8fbda0c0ab279d29630e7582fa48c607593..074d434c3077a53b74410b033a495ae58c3cd666 100644 (file)
@@ -740,6 +740,8 @@ nvc0_fifo_intr_engine_unit(struct nvc0_fifo_priv *priv, int engn)
        u32 inte = nv_rd32(priv, 0x002628);
        u32 unkn;
 
+       nv_wr32(priv, 0x0025a8 + (engn * 0x04), intr);
+
        for (unkn = 0; unkn < 8; unkn++) {
                u32 ints = (intr >> (unkn * 0x04)) & inte;
                if (ints & 0x1) {
@@ -751,8 +753,6 @@ nvc0_fifo_intr_engine_unit(struct nvc0_fifo_priv *priv, int engn)
                        nv_mask(priv, 0x002628, ints, 0);
                }
        }
-
-       nv_wr32(priv, 0x0025a8 + (engn * 0x04), intr);
 }
 
 static void
index d2f0fd39c1453c82e905c42ecf00551df7125f69..f8734eb74eaa083a3633256bf58ccb2f0298a337 100644 (file)
@@ -952,8 +952,8 @@ nve0_fifo_intr(struct nouveau_subdev *subdev)
        }
 
        if (stat & 0x80000000) {
-               nve0_fifo_intr_engine(priv);
                nv_wr32(priv, 0x002100, 0x80000000);
+               nve0_fifo_intr_engine(priv);
                stat &= ~0x80000000;
        }