Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19ca10d8 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/gem: lookup VMAs for buffers referenced by pushbuf ioctl



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: default avatarBen Skeggs <bskeggs@redhat.com>
parent 4b2c71ed
Loading
Loading
Loading
Loading
+1 −9
Original line number Original line Diff line number Diff line
@@ -80,18 +80,10 @@ READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout)
}
}


void
void
nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo,
nv50_dma_push(struct nouveau_channel *chan, u64 offset, int length)
	      int delta, int length)
{
{
	struct nouveau_cli *cli = (void *)chan->user.client;
	struct nouveau_bo *pb = chan->push.buffer;
	struct nouveau_bo *pb = chan->push.buffer;
	struct nouveau_vma *vma;
	int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base;
	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);
	BUG_ON(chan->dma.ib_free < 1);


+2 −3
Original line number Original line Diff line number Diff line
@@ -31,8 +31,7 @@
#include "nouveau_chan.h"
#include "nouveau_chan.h"


int nouveau_dma_wait(struct nouveau_channel *, int slots, int size);
int nouveau_dma_wait(struct nouveau_channel *, int slots, int size);
void nv50_dma_push(struct nouveau_channel *, struct nouveau_bo *,
void nv50_dma_push(struct nouveau_channel *, u64 addr, int length);
		   int delta, int length);


/*
/*
 * There's a hw race condition where you can't jump to your PUT offset,
 * 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;
	chan->accel_done = true;


	if (chan->dma.ib_max) {
	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);
			      (chan->dma.cur - chan->dma.put) << 2);
	} else {
	} else {
		WRITE_PUT(chan->dma.cur);
		WRITE_PUT(chan->dma.cur);
+16 −3
Original line number Original line Diff line number Diff line
@@ -432,7 +432,20 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv,
			}
			}
		}
		}


		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;
			b->user_priv = (uint64_t)(unsigned long)nvbo;
		}

		nvbo->reserved_by = file_priv;
		nvbo->reserved_by = file_priv;
		nvbo->pbbo_index = i;
		nvbo->pbbo_index = i;
		if ((b->valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
		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++) {
		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;
				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);
				      push[i].length);
		}
		}
	} else
	} else