drm/nouveau/gem: lookup VMAs for buffers referenced by pushbuf ioctl
authorBen Skeggs <bskeggs@redhat.com>
Tue, 8 May 2018 10:39:47 +0000 (20:39 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 18 May 2018 05:01:26 +0000 (15:01 +1000)
We previously only did this for push buffers, but an upcoming patch will
need to attach fences to all VMAs to resolve another issue.

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

index 10e84f6ca2b733329d6c09e6eaf8dfa3e9ad159b..e0664d28802bfaf4a2286abfcef3ac81fc49ce37 100644 (file)
@@ -80,18 +80,10 @@ READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout)
 }
 
 void
-nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo,
-             int delta, int length)
+nv50_dma_push(struct nouveau_channel *chan, u64 offset, int length)
 {
-       struct nouveau_cli *cli = (void *)chan->user.client;
        struct nouveau_bo *pb = chan->push.buffer;
-       struct nouveau_vma *vma;
        int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base;
-       u64 offset;
-
-       vma = nouveau_vma_find(bo, &cli->vmm);
-       BUG_ON(!vma);
-       offset = vma->addr + delta;
 
        BUG_ON(chan->dma.ib_free < 1);
 
index 74e10b14a7da27fa9d008a286f3121ee37c6b9aa..89c87111bbbddc145b41b49eea14c6d39ca1137f 100644 (file)
@@ -31,8 +31,7 @@
 #include "nouveau_chan.h"
 
 int nouveau_dma_wait(struct nouveau_channel *, int slots, int size);
-void nv50_dma_push(struct nouveau_channel *, struct nouveau_bo *,
-                  int delta, int length);
+void nv50_dma_push(struct nouveau_channel *, u64 addr, int length);
 
 /*
  * There's a hw race condition where you can't jump to your PUT offset,
@@ -151,7 +150,7 @@ FIRE_RING(struct nouveau_channel *chan)
        chan->accel_done = true;
 
        if (chan->dma.ib_max) {
-               nv50_dma_push(chan, chan->push.buffer, chan->dma.put << 2,
+               nv50_dma_push(chan, chan->push.addr + (chan->dma.put << 2),
                              (chan->dma.cur - chan->dma.put) << 2);
        } else {
                WRITE_PUT(chan->dma.cur);
index e72a7e37eb0af435851ddd5e25da26a5afa25965..707e02c80f1826dd01ab674264b9f03e635ffd5d 100644 (file)
@@ -432,7 +432,20 @@ retry:
                        }
                }
 
-               b->user_priv = (uint64_t)(unsigned long)nvbo;
+               if (cli->vmm.vmm.object.oclass >= NVIF_CLASS_VMM_NV50) {
+                       struct nouveau_vmm *vmm = &cli->vmm;
+                       struct nouveau_vma *vma = nouveau_vma_find(nvbo, vmm);
+                       if (!vma) {
+                               NV_PRINTK(err, cli, "vma not found!\n");
+                               ret = -EINVAL;
+                               break;
+                       }
+
+                       b->user_priv = (uint64_t)(unsigned long)vma;
+               } else {
+                       b->user_priv = (uint64_t)(unsigned long)nvbo;
+               }
+
                nvbo->reserved_by = file_priv;
                nvbo->pbbo_index = i;
                if ((b->valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
@@ -763,10 +776,10 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
                }
 
                for (i = 0; i < req->nr_push; i++) {
-                       struct nouveau_bo *nvbo = (void *)(unsigned long)
+                       struct nouveau_vma *vma = (void *)(unsigned long)
                                bo[push[i].bo_index].user_priv;
 
-                       nv50_dma_push(chan, nvbo, push[i].offset,
+                       nv50_dma_push(chan, vma->addr + push[i].offset,
                                      push[i].length);
                }
        } else