Index | Thread | Search

From:
kisekinopureya <kisekinopureya@disroot.org>
Subject:
[PATCH 4/4] port gem and ttm memory management to uvm
To:
tech@openbsd.org
Date:
Thu, 10 Sep 2026 22:13:52 +0300

Download raw body.

Thread
 sys/dev/pci/drm/i915/gem/i915_gem_object.h |  4 +-
 sys/dev/pci/drm/i915/gem/i915_gem_shmem.c  | 23 ++++---
 sys/dev/pci/drm/i915/gem/i915_gem_ttm.c    | 72 ++++++++++++++++++----
 3 files changed, 75 insertions(+), 24 deletions(-)

diff --git a/sys/dev/pci/drm/i915/gem/i915_gem_object.h b/sys/dev/pci/drm/i915/gem/i915_gem_object.h
index b266814d3fb..5ac665209ec 100644
--- a/sys/dev/pci/drm/i915/gem/i915_gem_object.h
+++ b/sys/dev/pci/drm/i915/gem/i915_gem_object.h
@@ -855,10 +855,10 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
 			 size_t size, struct intel_memory_region *mr,
 			 struct address_space *mapping,
 			 unsigned int max_segment,
-			 struct drm_i915_gem_object *obj);
+			 struct uvm_object *uao);
 void shmem_sg_free_table(struct sg_table *st, struct address_space *mapping,
 			 bool dirty, bool backup,
-			 struct drm_i915_gem_object *obj);
+			 struct uvm_object *uao);
 #endif
 void __shmem_writeback(size_t size, struct address_space *mapping);
 
diff --git a/sys/dev/pci/drm/i915/gem/i915_gem_shmem.c b/sys/dev/pci/drm/i915/gem/i915_gem_shmem.c
index ee8034c9c63..c2e5a09fa09 100644
--- a/sys/dev/pci/drm/i915/gem/i915_gem_shmem.c
+++ b/sys/dev/pci/drm/i915/gem/i915_gem_shmem.c
@@ -34,12 +34,15 @@ static void check_release_folio_batch(struct folio_batch *fbatch)
 
 void shmem_sg_free_table(struct sg_table *st, struct address_space *mapping,
 			 bool dirty, bool backup,
-			 struct drm_i915_gem_object *obj)
+			 struct uvm_object *uao)
 {
 	struct sgt_iter sgt_iter;
 	struct folio_batch fbatch;
 	struct folio *last = NULL;
 	struct vm_page *page;
+#ifdef __OpenBSD__
+	size_t size = 0;
+#endif
 
 #ifdef __linux__
 	mapping_clear_unevictable(mapping);
@@ -63,13 +66,14 @@ void shmem_sg_free_table(struct sg_table *st, struct address_space *mapping,
 #else
 		if (dirty)
 			set_page_dirty(page);
+		size += PAGE_SIZE;
 #endif
 	}
 #ifdef __linux__
 	if (fbatch.nr)
 		check_release_folio_batch(&fbatch);
 #else
-	uvm_obj_unwire(obj->base.uao, 0, obj->base.size);
+	uvm_obj_unwire(uao, 0, size);
 #endif
 
 	sg_free_table(st);
@@ -79,7 +83,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
 			 size_t size, struct intel_memory_region *mr,
 			 struct address_space *mapping,
 			 unsigned int max_segment,
-			 struct drm_i915_gem_object *obj)
+			 struct uvm_object *uao)
 {
 	unsigned int page_count; /* restricted by sg_alloc_table */
 	unsigned long i;
@@ -201,7 +205,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
 	st->nents = 0;
 
 	TAILQ_INIT(&plist);
-	if (uvm_obj_wire(obj->base.uao, 0, obj->base.size, &plist)) {
+	if (uvm_obj_wire(uao, 0, size, &plist)) {
 		ret = -ENOMEM;
 		goto err_sg;
 	}
@@ -225,7 +229,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
 err_sg:
 	sg_mark_end(sg);
 	if (sg != st->sgl) {
-		shmem_sg_free_table(st, mapping, false, false, obj);
+		shmem_sg_free_table(st, mapping, false, false, uao);
 	} else {
 		mapping_clear_unevictable(mapping);
 		sg_free_table(st);
@@ -275,7 +279,7 @@ rebuild_st:
 				   max_segment);
 #else
 	ret = shmem_sg_alloc_table(i915, st, obj->base.size, mem, NULL,
-				   max_segment, obj);
+				   max_segment, obj->base.uao);
 #endif
 	if (ret)
 		goto err_st;
@@ -291,7 +295,7 @@ rebuild_st:
 #ifdef __linux__
 			shmem_sg_free_table(st, mapping, false, false);
 #else
-			shmem_sg_free_table(st, NULL, false, false, obj);
+			shmem_sg_free_table(st, NULL, false, false, obj->base.uao);
 #endif
 			sg_free_table(st);
 			kfree(st);
@@ -320,7 +324,7 @@ err_pages:
 #ifdef __linux__
 	shmem_sg_free_table(st, mapping, false, false);
 #else
-	shmem_sg_free_table(st, NULL, false, false, obj);
+	shmem_sg_free_table(st, NULL, false, false, obj->base.uao);
 #endif
 	/*
 	 * shmemfs first checks if there is enough memory to allocate the page
@@ -459,7 +463,8 @@ void i915_gem_object_put_pages_shmem(struct drm_i915_gem_object *obj, struct sg_
 			    obj->mm.dirty, obj->mm.madv == I915_MADV_WILLNEED);
 #else
 	shmem_sg_free_table(pages, NULL,
-			    obj->mm.dirty, obj->mm.madv == I915_MADV_WILLNEED, obj);
+			    obj->mm.dirty, obj->mm.madv == I915_MADV_WILLNEED,
+			    obj->base.uao);
 #endif
 	kfree(pages);
 	obj->mm.dirty = false;
diff --git a/sys/dev/pci/drm/i915/gem/i915_gem_ttm.c b/sys/dev/pci/drm/i915/gem/i915_gem_ttm.c
index 570d0971fd4..340ede9e68d 100644
--- a/sys/dev/pci/drm/i915/gem/i915_gem_ttm.c
+++ b/sys/dev/pci/drm/i915/gem/i915_gem_ttm.c
@@ -54,6 +54,9 @@ struct i915_ttm_tt {
 
 	bool is_shmem;
 	struct file *filp;
+#ifdef __OpenBSD__
+	struct uvm_object *uao;
+#endif
 };
 
 static const struct ttm_place sys_placement_flags = {
@@ -183,21 +186,24 @@ static int i915_ttm_tt_shmem_populate(struct ttm_device *bdev,
 				      struct ttm_tt *ttm,
 				      struct ttm_operation_ctx *ctx)
 {
-	STUB();
-	return -ENOSYS;
-#ifdef notyet
 	struct drm_i915_private *i915 = container_of(bdev, typeof(*i915), bdev);
 	struct intel_memory_region *mr = i915->mm.regions[INTEL_MEMORY_SYSTEM];
 	struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm);
 	const unsigned int max_segment = i915_sg_segment_size(i915->drm.dev);
 	const size_t size = (size_t)ttm->num_pages << PAGE_SHIFT;
+#ifdef __linux__
 	struct file *filp = i915_tt->filp;
+#else
+	struct uvm_object *uao = i915_tt->uao;
+#endif
+
 	struct sgt_iter sgt_iter;
 	struct sg_table *st;
 	struct vm_page *page;
 	unsigned long i;
 	int err;
 
+#ifdef __linux__
 	if (!filp) {
 		struct address_space *mapping;
 		gfp_t mask;
@@ -214,17 +220,33 @@ static int i915_ttm_tt_shmem_populate(struct ttm_device *bdev,
 
 		i915_tt->filp = filp;
 	}
+#else
+	if (!uao) {
+		uao = uao_create(size, 0);
+		if (uao == NULL)
+			return -ENOMEM;
+
+		i915_tt->uao = uao;
+	}
+#endif
 
 	st = &i915_tt->cached_rsgt.table;
+#ifdef __linux__
 	err = shmem_sg_alloc_table(i915, st, size, mr, filp->f_mapping,
 				   max_segment);
+#else
+	err = shmem_sg_alloc_table(i915, st, size, mr, NULL,
+				   max_segment, uao);
+#endif
 	if (err)
 		return err;
 
+#ifdef __linux__
 	err = dma_map_sgtable(i915_tt->dev, st, DMA_BIDIRECTIONAL,
 			      DMA_ATTR_SKIP_CPU_SYNC);
 	if (err)
 		goto err_free_st;
+#endif
 
 	i = 0;
 	for_each_sgt_page(page, sgt_iter, st)
@@ -235,23 +257,25 @@ static int i915_ttm_tt_shmem_populate(struct ttm_device *bdev,
 
 	return 0;
 
+#ifdef __linux__
 err_free_st:
 	shmem_sg_free_table(st, filp->f_mapping, false, false);
+#endif
 
 	return err;
-#endif
 }
 
 static void i915_ttm_tt_shmem_unpopulate(struct ttm_tt *ttm)
 {
-	STUB();
-#ifdef notyet
 	struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm);
 	bool backup = ttm->page_flags & TTM_TT_FLAG_SWAPPED;
 	struct sg_table *st = &i915_tt->cached_rsgt.table;
 
+#ifdef __linux__
 	shmem_sg_free_table(st, file_inode(i915_tt->filp)->i_mapping,
 			    backup, backup);
+#else
+	shmem_sg_free_table(st, NULL, backup, backup, i915_tt->uao);
 #endif
 }
 
@@ -334,13 +358,13 @@ static int i915_ttm_tt_populate(struct ttm_device *bdev,
 
 static void i915_ttm_tt_unpopulate(struct ttm_device *bdev, struct ttm_tt *ttm)
 {
-	STUB();
-#ifdef notyet
 	struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm);
 	struct sg_table *st = &i915_tt->cached_rsgt.table;
 
+#ifdef __linux__
 	if (st->sgl)
 		dma_unmap_sgtable(i915_tt->dev, st, DMA_BIDIRECTIONAL, 0);
+#endif
 
 	if (i915_tt->is_shmem) {
 		i915_ttm_tt_shmem_unpopulate(ttm);
@@ -348,7 +372,6 @@ static void i915_ttm_tt_unpopulate(struct ttm_device *bdev, struct ttm_tt *ttm)
 		sg_free_table(st);
 		ttm_pool_free(&bdev->pool, ttm);
 	}
-#endif
 }
 
 static void i915_ttm_tt_destroy(struct ttm_device *bdev, struct ttm_tt *ttm)
@@ -357,6 +380,10 @@ static void i915_ttm_tt_destroy(struct ttm_device *bdev, struct ttm_tt *ttm)
 
 	if (i915_tt->filp)
 		fput(i915_tt->filp);
+#ifdef __OpenBSD__
+	if (i915_tt->uao)
+		uao_detach(i915_tt->uao);
+#endif
 
 	ttm_tt_fini(ttm);
 	i915_refct_sgt_put(&i915_tt->cached_rsgt);
@@ -544,17 +571,19 @@ static void i915_ttm_delete_mem_notify(struct ttm_buffer_object *bo)
 
 static struct i915_refct_sgt *i915_ttm_tt_get_st(struct ttm_tt *ttm)
 {
-	STUB();
-	return ERR_PTR(-ENOSYS);
-#ifdef notyet
 	struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm);
 	struct sg_table *st;
 	int ret;
+#ifdef __OpenBSD__
+	struct scatterlist *sg;
+	unsigned long i;
+#endif
 
 	if (i915_tt->cached_rsgt.table.sgl)
 		return i915_refct_sgt_get(&i915_tt->cached_rsgt);
 
 	st = &i915_tt->cached_rsgt.table;
+#ifdef __linux__
 	ret = sg_alloc_table_from_pages_segment(st,
 			ttm->pages, ttm->num_pages,
 			0, (unsigned long)ttm->num_pages << PAGE_SHIFT,
@@ -563,15 +592,32 @@ static struct i915_refct_sgt *i915_ttm_tt_get_st(struct ttm_tt *ttm)
 		st->sgl = NULL;
 		return ERR_PTR(ret);
 	}
+#else
+	ret = sg_alloc_table(st, ttm->num_pages, GFP_KERNEL);
+	if (ret) {
+		st->sgl = NULL;
+		return ERR_PTR(ret);
+	}
 
+	sg = st->sgl;
+	st->nents = 0;
+	for (i = 0; i < ttm->num_pages; i++) {
+		if (i)
+			sg = sg_next(sg);
+		st->nents++;
+		sg_set_page(sg, ttm->pages[i], PAGE_SIZE, 0);
+	}
+#endif
+
+#ifdef __linux__
 	ret = dma_map_sgtable(i915_tt->dev, st, DMA_BIDIRECTIONAL, 0);
 	if (ret) {
 		sg_free_table(st);
 		return ERR_PTR(ret);
 	}
+#endif
 
 	return i915_refct_sgt_get(&i915_tt->cached_rsgt);
-#endif
 }
 
 /**