Download raw body.
[PATCH 4/4] port gem and ttm memory management to uvm
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
}
/**
[PATCH 4/4] port gem and ttm memory management to uvm