Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/external/bsd/drm2/dist/drm Implement drm userptr with uv...
details: https://anonhg.NetBSD.org/src/rev/5ccee9dedd49
branches: trunk
changeset: 744844:5ccee9dedd49
user: riastradh <riastradh%NetBSD.org@localhost>
date: Fri Feb 14 04:38:23 2020 +0000
description:
Implement drm userptr with uvm_vslock & bus_dmamap_load_uio.
diffstat:
sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_cs.c | 16 +-
sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_gem.c | 26 ++-
sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_ttm.c | 110 ++++++++++++++-
sys/external/bsd/drm2/dist/drm/radeon/radeon_cs.c | 16 +-
sys/external/bsd/drm2/dist/drm/radeon/radeon_gem.c | 26 ++-
sys/external/bsd/drm2/dist/drm/radeon/radeon_ttm.c | 115 ++++++++++++++--
6 files changed, 241 insertions(+), 68 deletions(-)
diffs (truncated from 647 to 300 lines):
diff -r b07dcaf85d1a -r 5ccee9dedd49 sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_cs.c
--- a/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_cs.c Fri Feb 14 04:38:13 2020 +0000
+++ b/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_cs.c Fri Feb 14 04:38:23 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: amdgpu_cs.c,v 1.3 2018/08/27 14:04:50 riastradh Exp $ */
+/* $NetBSD: amdgpu_cs.c,v 1.4 2020/02/14 04:38:23 riastradh Exp $ */
/*
* Copyright 2008 Jerome Glisse.
@@ -27,7 +27,7 @@
* Jerome Glisse <glisse%freedesktop.org@localhost>
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: amdgpu_cs.c,v 1.3 2018/08/27 14:04:50 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: amdgpu_cs.c,v 1.4 2020/02/14 04:38:23 riastradh Exp $");
#include <linux/list_sort.h>
#include <drm/drmP.h>
@@ -406,7 +406,7 @@
struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
struct amdgpu_cs_buckets buckets;
struct list_head duplicates;
- bool need_mmap_lock __diagused = false;
+ bool need_mmap_lock = false;
int i, r;
if (p->bo_list) {
@@ -426,9 +426,8 @@
list_add(&p->uf_entry.tv.head, &p->validated);
#ifdef __NetBSD__
- KASSERTMSG(!need_mmap_lock,
- "someone didn't finish adding support for userptr"
- " and it wasn't me");
+ if (need_mmap_lock)
+ vm_map_lock_read(&curproc->p_vmspace->vm_map);
#else
if (need_mmap_lock)
down_read(¤t->mm->mmap_sem);
@@ -450,7 +449,10 @@
ttm_eu_backoff_reservation(&p->ticket, &p->validated);
error_reserve:
-#ifndef __NetBSD__
+#ifdef __NetBSD__
+ if (need_mmap_lock)
+ vm_map_unlock_read(&curproc->p_vmspace->vm_map);
+#else
if (need_mmap_lock)
up_read(¤t->mm->mmap_sem);
#endif
diff -r b07dcaf85d1a -r 5ccee9dedd49 sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_gem.c
--- a/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_gem.c Fri Feb 14 04:38:13 2020 +0000
+++ b/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_gem.c Fri Feb 14 04:38:23 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: amdgpu_gem.c,v 1.5 2020/02/14 04:35:19 riastradh Exp $ */
+/* $NetBSD: amdgpu_gem.c,v 1.6 2020/02/14 04:38:23 riastradh Exp $ */
/*
* Copyright 2008 Advanced Micro Devices, Inc.
@@ -28,7 +28,7 @@
* Jerome Glisse
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: amdgpu_gem.c,v 1.5 2020/02/14 04:35:19 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: amdgpu_gem.c,v 1.6 2020/02/14 04:38:23 riastradh Exp $");
#include <linux/ktime.h>
#include <drm/drmP.h>
@@ -228,15 +228,6 @@
int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp)
{
-#ifdef __NetBSD__
- /*
- * XXX Too painful to contemplate for now. If you add this,
- * make sure to update amdgpu_cs.c amdgpu_cs_parser_relocs
- * (need_mmap_lock), and anything else using
- * amdgpu_ttm_tt_has_userptr.
- */
- return -ENODEV;
-#else
struct amdgpu_device *adev = dev->dev_private;
struct drm_amdgpu_gem_userptr *args = data;
struct drm_gem_object *gobj;
@@ -281,17 +272,29 @@
}
if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) {
+#ifdef __NetBSD__
+ vm_map_lock_read(&curproc->p_vmspace->vm_map);
+#else
down_read(¤t->mm->mmap_sem);
+#endif
r = amdgpu_bo_reserve(bo, true);
if (r) {
+#ifdef __NetBSD__
+ vm_map_unlock_read(&curproc->p_vmspace->vm_map);
+#else
up_read(¤t->mm->mmap_sem);
+#endif
goto release_object;
}
amdgpu_ttm_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_GTT);
r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
amdgpu_bo_unreserve(bo);
+#ifdef __NetBSD__
+ vm_map_unlock_read(&curproc->p_vmspace->vm_map);
+#else
up_read(¤t->mm->mmap_sem);
+#endif
if (r)
goto release_object;
}
@@ -312,7 +315,6 @@
r = amdgpu_gem_handle_lockup(adev, r);
return r;
-#endif
}
int amdgpu_mode_dumb_mmap(struct drm_file *filp,
diff -r b07dcaf85d1a -r 5ccee9dedd49 sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_ttm.c
--- a/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_ttm.c Fri Feb 14 04:38:13 2020 +0000
+++ b/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_ttm.c Fri Feb 14 04:38:23 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: amdgpu_ttm.c,v 1.4 2018/08/27 15:22:54 riastradh Exp $ */
+/* $NetBSD: amdgpu_ttm.c,v 1.5 2020/02/14 04:38:23 riastradh Exp $ */
/*
* Copyright 2009 Jerome Glisse.
@@ -32,7 +32,7 @@
* Dave Airlie
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: amdgpu_ttm.c,v 1.4 2018/08/27 15:22:54 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: amdgpu_ttm.c,v 1.5 2020/02/14 04:38:23 riastradh Exp $");
#include <ttm/ttm_bo_api.h>
#include <ttm/ttm_bo_driver.h>
@@ -488,39 +488,119 @@
struct amdgpu_device *adev;
u64 offset;
uint64_t userptr;
+#ifdef __NetBSD__
+ struct vmspace *usermm;
+#else
struct mm_struct *usermm;
+#endif
uint32_t userflags;
};
/* prepare the sg table with the user pages */
static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
{
-#ifdef __NetBSD__
- panic("we don't handle user pointers round these parts");
-#else
struct amdgpu_device *adev = amdgpu_get_adev(ttm->bdev);
struct amdgpu_ttm_tt *gtt = (void *)ttm;
+#ifndef __NetBSD__
unsigned pinned = 0, nents;
+#endif
int r;
int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);
+#ifndef __NetBSD__
enum dma_data_direction direction = write ?
DMA_BIDIRECTIONAL : DMA_TO_DEVICE;
+#endif
+#ifdef __NetBSD__
+ if (curproc->p_vmspace != gtt->usermm)
+ return -EPERM;
+#else
if (current->mm != gtt->usermm)
return -EPERM;
+#endif
if (gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) {
/* check that we only pin down anonymous memory
to prevent problems with writeback */
unsigned long end = gtt->userptr + ttm->num_pages * PAGE_SIZE;
+#ifdef __NetBSD__
+ /* XXX ??? TOCTOU, anyone? */
+ /* XXX should do range_test */
+ struct vm_map_entry *entry;
+ bool ok;
+ vm_map_lock_read(>t->usermm->vm_map);
+ ok = uvm_map_lookup_entry(>t->usermm->vm_map,
+ (vaddr_t)gtt->userptr, &entry);
+ if (ok)
+ ok = !UVM_ET_ISOBJ(entry) && end <= entry->end;
+ vm_map_unlock_read(>t->usermm->vm_map);
+ if (!ok)
+ return -EPERM;
+#else
struct vm_area_struct *vma;
vma = find_vma(gtt->usermm, gtt->userptr);
if (!vma || vma->vm_file || vma->vm_end < end)
return -EPERM;
+#endif
}
+#ifdef __NetBSD__
+ struct iovec iov = {
+ .iov_base = (void *)(vaddr_t)gtt->userptr,
+ .iov_len = ttm->num_pages << PAGE_SHIFT,
+ };
+ struct uio uio = {
+ .uio_iov = &iov,
+ .uio_iovcnt = 1,
+ .uio_offset = 0,
+ .uio_resid = ttm->num_pages << PAGE_SHIFT,
+ .uio_rw = (write ? UIO_READ : UIO_WRITE), /* XXX ??? */
+ .uio_vmspace = gtt->usermm,
+ };
+ unsigned long i;
+
+ /* Wire the relevant part of the user's address space. */
+ /* XXX What happens if user does munmap? */
+ /* XXX errno NetBSD->Linux */
+ r = -uvm_vslock(gtt->usermm, (void *)(vaddr_t)gtt->userptr,
+ ttm->num_pages << PAGE_SHIFT,
+ (write ? VM_PROT_WRITE : VM_PROT_READ)); /* XXX ??? */
+ if (r)
+ goto fail0;
+
+ /* Load it up for DMA. */
+ /* XXX errno NetBSD->Linux */
+ r = -bus_dmamap_load_uio(adev->ddev->dmat, gtt->ttm.dma_address, &uio,
+ BUS_DMA_WAITOK);
+ if (r)
+ goto fail1;
+
+ /* Get each of the pages as ttm requests. */
+ for (i = 0; i < ttm->num_pages; i++) {
+ vaddr_t va = (vaddr_t)gtt->userptr + (i << PAGE_SHIFT);
+ paddr_t pa;
+ struct vm_page *vmp;
+
+ if (!pmap_extract(gtt->usermm->vm_map.pmap, va, &pa)) {
+ r = -EFAULT;
+ goto fail2;
+ }
+ vmp = PHYS_TO_VM_PAGE(pa);
+ ttm->pages[i] = container_of(vmp, struct page, p_vmp);
+ }
+
+ /* Success! */
+ return 0;
+
+fail2: while (i --> 0)
+ ttm->pages[i] = NULL; /* paranoia */
+ bus_dmamap_unload(adev->ddev->dmat, gtt->ttm.dma_address);
+fail1: uvm_vsunlock(gtt->usermm, (void *)(vaddr_t)gtt->userptr,
+ ttm->num_pages << PAGE_SHIFT);
+fail0: return r;
+#else
do {
unsigned num_pages = ttm->num_pages - pinned;
uint64_t userptr = gtt->userptr + pinned * PAGE_SIZE;
@@ -563,7 +643,13 @@
static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
{
#ifdef __NetBSD__
- panic("some varmint pinned a userptr to my hat");
+ struct amdgpu_device *adev = amdgpu_get_adev(ttm->bdev);
+ struct amdgpu_ttm_tt *gtt = container_of(ttm, struct amdgpu_ttm_tt,
+ ttm.ttm);
+
+ bus_dmamap_unload(adev->ddev->dmat, gtt->ttm.dma_address);
+ uvm_vsunlock(gtt->usermm, (void *)(vaddr_t)gtt->userptr,
+ ttm->num_pages << PAGE_SHIFT);
#else
struct amdgpu_device *adev = amdgpu_get_adev(ttm->bdev);
struct amdgpu_ttm_tt *gtt = (void *)ttm;
@@ -696,16 +782,16 @@
if (gtt && gtt->userptr) {
#ifdef __NetBSD__
- panic("don't point at users, it's not polite");
+ ttm->sg = NULL;
#else
ttm->sg = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
if (!ttm->sg)
return -ENOMEM;
+#endif
ttm->page_flags |= TTM_PAGE_FLAG_SG;
ttm->state = tt_unbound;
return 0;
-#endif
}
if (slave && ttm->sg) {
@@ -823,19 +909,19 @@
int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
Home |
Main Index |
Thread Index |
Old Index