Module Name: src
Committed By: riastradh
Date: Fri Jan 19 22:24:38 UTC 2024
Modified Files:
src/sys/external/bsd/drm2/dist/drm/i915/gem: i915_gem_stolen.c
Log Message:
i915_gem_stolen: Fill sg_pgs, with size/PAGE_SIZE entries.
Use sg_alloc_table_from_bus_dmamem to do this.
i915_gem_mman.c vm_fault_cpu and i915_gem_object_release_mmap_offset
both rely on sg_pgs to be a page array, so providing a table with
only one entry doesn't work (except by accident, if the object is
page-sized anyway). And they rely on the sg_pgs entries to be
initialized, which we weren't doing before, and which
sg_alloc_table_from_bus_dmamem does for us.
Related to PR kern/57833.
XXX pullup-10
To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 \
src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_stolen.c
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_stolen.c
diff -u src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_stolen.c:1.6 src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_stolen.c:1.7
--- src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_stolen.c:1.6 Fri Jan 19 22:24:27 2024
+++ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_stolen.c Fri Jan 19 22:24:38 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: i915_gem_stolen.c,v 1.6 2024/01/19 22:24:27 riastradh Exp $ */
+/* $NetBSD: i915_gem_stolen.c,v 1.7 2024/01/19 22:24:38 riastradh Exp $ */
/*
* SPDX-License-Identifier: MIT
@@ -7,7 +7,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: i915_gem_stolen.c,v 1.6 2024/01/19 22:24:27 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i915_gem_stolen.c,v 1.7 2024/01/19 22:24:38 riastradh Exp $");
#include <linux/errno.h>
#include <linux/mutex.h>
@@ -506,14 +506,13 @@ i915_pages_create_for_stolen(struct drm_
{
struct drm_i915_private *i915 = to_i915(dev);
struct sg_table *st;
+ struct scatterlist *sg;
#ifdef __NetBSD__
bus_dma_tag_t dmat = i915->drm.dmat;
bus_dma_segment_t *seg = NULL;
int nseg = 0, i;
bool loaded = false;
int ret;
-#else
- struct scatterlist *sg;
#endif
GEM_BUG_ON(range_overflows(offset, size, resource_size(&i915->dsm)));
@@ -527,11 +526,6 @@ i915_pages_create_for_stolen(struct drm_
if (st == NULL)
return ERR_PTR(-ENOMEM);
- if (sg_alloc_table(st, 1, GFP_KERNEL)) {
- kfree(st);
- return ERR_PTR(-ENOMEM);
- }
-
#ifdef __NetBSD__
KASSERT((size % PAGE_SIZE) == 0);
nseg = size / PAGE_SIZE;
@@ -548,6 +542,17 @@ i915_pages_create_for_stolen(struct drm_
seg[i].ds_len = PAGE_SIZE;
}
+ sg = NULL;
+
+ ret = sg_alloc_table_from_bus_dmamem(st, dmat, seg, nseg, GFP_KERNEL);
+ if (ret) {
+ DRM_ERROR("failed to alloc sg table for stolen object: %d\n",
+ ret);
+ ret = -ENOMEM;
+ goto out;
+ }
+ sg = st->sgl;
+
/* XXX errno NetBSD->Linux */
ret = -bus_dmamap_create(dmat, size, nseg, PAGE_SIZE, 0,
BUS_DMA_WAITOK, &st->sgl->sg_dmamap);
@@ -573,11 +578,19 @@ out: kmem_free(seg, nseg * sizeof(seg[0]
if (ret) {
if (loaded)
bus_dmamap_unload(dmat, st->sgl->sg_dmamap);
- sg_free_table(st);
+ if (sg && sg->sg_dmamap)
+ bus_dmamap_destroy(dmat, sg->sg_dmamap);
+ if (sg)
+ sg_free_table(st);
kfree(st);
return ERR_PTR(ret);
}
#else
+ if (sg_alloc_table(st, 1, GFP_KERNEL)) {
+ kfree(st);
+ return ERR_PTR(-ENOMEM);
+ }
+
sg = st->sgl;
sg->offset = 0;
sg->length = size;