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
This commit is contained in:
parent
0b4ab1ab69
commit
aef93b36e3
|
@ -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_device *dev,
|
|||
{
|
||||
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_device *dev,
|
|||
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_device *dev,
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue