Module Name: src
Committed By: riastradh
Date: Sun Dec 19 12:26:55 UTC 2021
Modified Files:
src/sys/external/bsd/drm2/dist/drm/i915/gem: i915_gem_mman.c
i915_gem_object_types.h
Log Message:
i915: Rearrange how mmap offsets work.
Rather than use the magic offsets in each GEM object's uvm object
itself, just create a separate uvm object for each mapping type and
start at zero within each uvm object. This should avoid problems
with things like ubc_uiomove which don't know to adjust the starting
offset.
To generate a diff of this commit:
cvs rdiff -u -r1.20 -r1.21 \
src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c
cvs rdiff -u -r1.6 -r1.7 \
src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object_types.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c
diff -u src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c:1.20 src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c:1.21
--- src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c:1.20 Sun Dec 19 12:13:31 2021
+++ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c Sun Dec 19 12:26:55 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: i915_gem_mman.c,v 1.20 2021/12/19 12:13:31 riastradh Exp $ */
+/* $NetBSD: i915_gem_mman.c,v 1.21 2021/12/19 12:26:55 riastradh Exp $ */
/*
* SPDX-License-Identifier: MIT
@@ -7,7 +7,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: i915_gem_mman.c,v 1.20 2021/12/19 12:13:31 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i915_gem_mman.c,v 1.21 2021/12/19 12:26:55 riastradh Exp $");
#include <linux/anon_inodes.h>
#include <linux/mman.h>
@@ -28,7 +28,9 @@ __KERNEL_RCSID(0, "$NetBSD: i915_gem_mma
#include "i915_user_extensions.h"
#include "i915_vma.h"
-#ifndef __NetBSD__
+#ifdef __NetBSD__
+static const struct uvm_pagerops i915_mmo_gem_uvm_ops;
+#else
static inline bool
__vma_matches(struct vm_area_struct *vma, struct file *filp,
unsigned long addr, unsigned long size)
@@ -338,8 +340,6 @@ static vm_fault_t vm_fault_cpu(struct vm
paddr_t paddr;
int i;
- startpage -= drm_vma_node_start(&mmo->vma_node);
-
for (i = 0; i < npages; i++) {
if ((flags & PGO_ALLPAGES) == 0 && i != centeridx)
continue;
@@ -411,7 +411,6 @@ static vm_fault_t vm_fault_gtt(struct vm
#ifdef __NetBSD__
page_offset = (ufi->entry->offset + (vaddr - ufi->entry->start))
>> PAGE_SHIFT;
- page_offset -= drm_vma_node_start(&mmo->vma_node);
#else
/* We don't use vmf->pgoff since that has the fake offset */
page_offset = (vmf->address - area->vm_start) >> PAGE_SHIFT;
@@ -546,14 +545,9 @@ i915_gem_fault(struct uvm_faultinfo *ufi
int npages, int centeridx, vm_prot_t access_type, int flags)
{
struct uvm_object *uobj = ufi->entry->object.uvm_obj;
- voff_t uoffset;
- unsigned long startpage;
- struct drm_gem_object *gem =
- container_of(uobj, struct drm_gem_object, gemo_uvmobj);
- struct drm_i915_gem_object *obj = to_intel_bo(gem);
- struct drm_device *dev = obj->base.dev;
- struct drm_vma_offset_node *node;
- struct i915_mmap_offset *mmo;
+ struct i915_mmap_offset *mmo =
+ container_of(uobj, struct i915_mmap_offset, uobj);
+ struct drm_i915_gem_object *obj = mmo->obj;
bool pinned = false;
int error;
@@ -574,44 +568,6 @@ i915_gem_fault(struct uvm_faultinfo *ufi
*/
rw_exit(obj->base.filp->vmobjlock);
- KASSERT(ufi->entry->start <= vaddr);
- KASSERT((ufi->entry->offset & (PAGE_SIZE - 1)) == 0);
- uoffset = ufi->entry->offset + (vaddr - ufi->entry->start);
- startpage = uoffset >> PAGE_SHIFT;
-
- /*
- * Look up the mmo again because we can't conveniently store it
- * alongside the mapping unless we create a separate uvm object
- * for it. XXX Consider creating a separate uvm object as a
- * kind of subobject of the main object.
- *
- * We use drm_vma_offset_lookup_locked because the number of
- * pages we're faulting in here may be different from the
- * number of pages that were mapped.
- */
- rcu_read_lock();
- drm_vma_offset_lock_lookup(dev->vma_offset_manager);
- node = drm_vma_offset_lookup_locked(dev->vma_offset_manager,
- startpage, npages);
- drm_vma_offset_unlock_lookup(dev->vma_offset_manager);
- rcu_read_unlock();
-
- /*
- * The mmo had better be there -- hope we can't remove the mmo
- * without unmapping first!
- */
- KASSERT(node);
- KASSERTMSG((ufi->entry->offset >> PAGE_SHIFT ==
- drm_vma_node_start(node)),
- /*
- * Always provided by i915_gem_mmap_object, but in
- * principle we could relax this.
- */
- "map startpage=%lx =/= node startpage=%lx",
- ufi->entry->offset >> PAGE_SHIFT, drm_vma_node_start(node));
- mmo = container_of(node, struct i915_mmap_offset, vma_node);
- KASSERT(obj == mmo->obj);
-
/* XXX errno Linux->NetBSD */
error = -i915_gem_object_pin_pages(obj);
if (error)
@@ -814,6 +770,7 @@ insert_mmo(struct drm_i915_gem_object *o
if (to_free) {
drm_vma_offset_remove(obj->base.dev->vma_offset_manager,
&to_free->vma_node);
+ uvm_obj_destroy(&to_free->uobj, /*free lock*/true);
drm_vma_node_destroy(&to_free->vma_node);
kfree(to_free);
}
@@ -873,6 +830,9 @@ mmap_offset_attach(struct drm_i915_gem_o
mmo->mmap_type = mmap_type;
#ifdef __NetBSD__
drm_vma_node_init(&mmo->vma_node);
+ uvm_obj_init(&mmo->uobj, &i915_mmo_gem_uvm_ops, /*allocate lock*/false,
+ /*nrefs*/1);
+ uvm_obj_setlock(&mmo->uobj, obj->base.filp->vmobjlock);
#else
drm_vma_node_reset(&mmo->vma_node);
#endif
@@ -902,6 +862,9 @@ out:
return mmo;
err:
+#ifdef __NetBSD__
+ uvm_obj_destroy(&mmo->uobj, /*free lock*/true);
+#endif
drm_vma_node_destroy(&mmo->vma_node);
kfree(mmo);
return ERR_PTR(err);
@@ -1036,9 +999,43 @@ i915_gem_mmap_offset_ioctl(struct drm_de
#ifdef __NetBSD__
+static int
+i915_gem_nofault(struct uvm_faultinfo *ufi, vaddr_t vaddr,
+ struct vm_page **pps, int npages, int centeridx, vm_prot_t access_type,
+ int flags)
+{
+ panic("i915 main gem object should not be mmapped directly");
+}
+
const struct uvm_pagerops i915_gem_uvm_ops = {
.pgo_reference = drm_gem_pager_reference,
.pgo_detach = drm_gem_pager_detach,
+ .pgo_fault = i915_gem_nofault,
+};
+
+static void
+i915_mmo_reference(struct uvm_object *uobj)
+{
+ struct i915_mmap_offset *mmo =
+ container_of(uobj, struct i915_mmap_offset, uobj);
+ struct drm_i915_gem_object *obj = mmo->obj;
+
+ drm_gem_object_get(&obj->base);
+}
+
+static void
+i915_mmo_detach(struct uvm_object *uobj)
+{
+ struct i915_mmap_offset *mmo =
+ container_of(uobj, struct i915_mmap_offset, uobj);
+ struct drm_i915_gem_object *obj = mmo->obj;
+
+ drm_gem_object_put_unlocked(&obj->base);
+}
+
+static const struct uvm_pagerops i915_mmo_gem_uvm_ops = {
+ .pgo_reference = i915_mmo_reference,
+ .pgo_detach = i915_mmo_detach,
.pgo_fault = i915_gem_fault,
};
@@ -1082,8 +1079,8 @@ i915_gem_mmap_object(struct drm_device *
}
/* Success! */
- *uobjp = &obj->base.gemo_uvmobj;
- *uoffsetp = (voff_t)startpage << PAGE_SHIFT;
+ *uobjp = &mmo->uobj;
+ *uoffsetp = 0;
return 0;
}
Index: src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object_types.h
diff -u src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object_types.h:1.6 src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object_types.h:1.7
--- src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object_types.h:1.6 Sun Dec 19 11:33:30 2021
+++ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object_types.h Sun Dec 19 12:26:55 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: i915_gem_object_types.h,v 1.6 2021/12/19 11:33:30 riastradh Exp $ */
+/* $NetBSD: i915_gem_object_types.h,v 1.7 2021/12/19 12:26:55 riastradh Exp $ */
/*
* SPDX-License-Identifier: MIT
@@ -78,7 +78,11 @@ struct i915_mmap_offset {
struct drm_i915_gem_object *obj;
enum i915_mmap_type mmap_type;
+#ifdef __NetBSD__
+ struct uvm_object uobj;
+#else
struct rb_node offset;
+#endif
};
struct drm_i915_gem_object {