drm/nouveau: support synchronous pushbuf submission
authorBen Skeggs <bskeggs@redhat.com>
Thu, 23 Jan 2020 05:52:12 +0000 (15:52 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 29 Jan 2020 05:49:56 +0000 (15:49 +1000)
This is useful for debugging GPU hangs.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_gem.c
include/uapi/drm/nouveau_drm.h

index 8f97534e996c94be5cfaba35eaa2b5f4fac4b279..f5ece1f9497348a892ca8a7ddc97354df409d60b 100644 (file)
@@ -688,7 +688,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
        struct validate_op op;
        struct nouveau_fence *fence = NULL;
        int i, j, ret = 0;
-       bool do_reloc = false;
+       bool do_reloc = false, sync = false;
 
        if (unlikely(!abi16))
                return -ENOMEM;
@@ -705,6 +705,8 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
        if (unlikely(atomic_read(&chan->killed)))
                return nouveau_abi16_put(abi16, -ENODEV);
 
+       sync = req->vram_available & NOUVEAU_GEM_PUSHBUF_SYNC;
+
        req->vram_available = drm->gem.vram_available;
        req->gart_available = drm->gem.gart_available;
        if (unlikely(req->nr_push == 0))
@@ -852,6 +854,13 @@ revalidate:
                goto out;
        }
 
+       if (sync) {
+               if (!(ret = nouveau_fence_wait(fence, false, false))) {
+                       if ((ret = dma_fence_get_status(&fence->base)) == 1)
+                               ret = 0;
+               }
+       }
+
 out:
        validate_fini(&op, chan, fence, bo);
        nouveau_fence_unref(&fence);
index 9459a6e3bc1f4eee615f548e1617ac2d46114a40..853a327433d3fbc7cbbc00680cd732ce95023cae 100644 (file)
@@ -110,6 +110,7 @@ struct drm_nouveau_gem_pushbuf {
        __u64 push;
        __u32 suffix0;
        __u32 suffix1;
+#define NOUVEAU_GEM_PUSHBUF_SYNC                                    (1ULL << 0)
        __u64 vram_available;
        __u64 gart_available;
 };