Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/external/bsd/drm2/dist/drm/nouveau/nvkm/subdev/mmu reorg...
details: https://anonhg.NetBSD.org/src/rev/d1ec87ec5c13
branches: trunk
changeset: 366597:d1ec87ec5c13
user: mrg <mrg%NetBSD.org@localhost>
date: Tue May 31 20:53:35 2022 +0000
description:
reorganise most of the NetBSD portion of nvkm_mem_dtor().
when nvkm_mem_new_host() is called via the in-kernel ioctl method,
we copy the supplied dmamap, use it's dm_nsegs value for allocation
of "mem->dma", and assume it remains valid until we're done.
when this path is taken "mem->mem" remains NULL so all the code in
nvkm_mem_dtor() is ignored, and the "mem->dma" is leaked. this is
one leak seen in PR#56826. as "dmamap->dm_nsegs" can become invalid
before the dtor call, store the value in "mem->nseg" for use in the
dtor, and convert the dtor to free "mem->dma" if "mem->dma" is set.
additionally, "mem->pages" should end up being the same value as
"nseg" here, ASSERT() this.
while here properly mark NetBSD specific code in nvkm_mem_new_host().
additionally, destroy the dmamap created in the non-ioctl path of
nvkm_mem_new_host(). this is another leak seen in PR#56826.
with both of these fixes my "kmem-04096" pool does not grow rapidly
while using "mpv -vo gpu". infact, once i loaded the relevant file
into memory, this pool remains stable after at least one minute of
video playback.
ok riastradh@
diffstat:
sys/external/bsd/drm2/dist/drm/nouveau/nvkm/subdev/mmu/nouveau_nvkm_subdev_mmu_mem.c | 26 +++++++--
1 files changed, 20 insertions(+), 6 deletions(-)
diffs (91 lines):
diff -r 9cd77c9e433d -r d1ec87ec5c13 sys/external/bsd/drm2/dist/drm/nouveau/nvkm/subdev/mmu/nouveau_nvkm_subdev_mmu_mem.c
--- a/sys/external/bsd/drm2/dist/drm/nouveau/nvkm/subdev/mmu/nouveau_nvkm_subdev_mmu_mem.c Tue May 31 20:28:57 2022 +0000
+++ b/sys/external/bsd/drm2/dist/drm/nouveau/nvkm/subdev/mmu/nouveau_nvkm_subdev_mmu_mem.c Tue May 31 20:53:35 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nouveau_nvkm_subdev_mmu_mem.c,v 1.7 2021/12/19 11:06:44 riastradh Exp $ */
+/* $NetBSD: nouveau_nvkm_subdev_mmu_mem.c,v 1.8 2022/05/31 20:53:35 mrg Exp $ */
/*
* Copyright 2017 Red Hat Inc.
@@ -22,7 +22,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_subdev_mmu_mem.c,v 1.7 2021/12/19 11:06:44 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_subdev_mmu_mem.c,v 1.8 2022/05/31 20:53:35 mrg Exp $");
#define nvkm_mem(p) container_of((p), struct nvkm_mem, memory)
#include "mem.h"
@@ -97,16 +97,21 @@
nvkm_mem_dtor(struct nvkm_memory *memory)
{
struct nvkm_mem *mem = nvkm_mem(memory);
+#ifdef __NetBSD__
+ if (mem->dma) {
+ kmem_free(mem->dma, mem->nseg * sizeof(mem->dma[0]));
+ }
if (mem->mem) {
-#ifdef __NetBSD__
struct nvkm_device *device = mem->mmu->subdev.device;
bus_dma_tag_t dmat = device->func->dma_tag(device);
- kmem_free(mem->dma,
- mem->dmamap->dm_nsegs * sizeof(mem->dma[0]));
+
bus_dmamap_unload(dmat, mem->dmamap);
bus_dmamem_free(dmat, mem->mem, mem->nseg);
+ bus_dmamap_destroy(dmat, mem->dmamap);
kmem_free(mem->mem, mem->pages * sizeof(mem->mem[0]));
+ }
#else
+ if (mem->mem) {
while (mem->pages--) {
dma_unmap_page(mem->mmu->subdev.device->dev,
mem->dma[mem->pages], PAGE_SIZE,
@@ -115,8 +120,8 @@
}
kvfree(mem->dma);
kvfree(mem->mem);
+ }
#endif
- }
return mem;
}
@@ -218,7 +223,11 @@
if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) {
if (args->v0.dma) {
nvkm_memory_ctor(&nvkm_mem_dma, &mem->memory);
+#ifndef __NetBSD__
+ mem->dma = args->v0.dma;
+#else
mem->dmamap = args->v0.dma;
+ mem->nseg = mem->dmamap->dm_nsegs;
mem->dma = kmem_zalloc(mem->dmamap->dm_nsegs *
sizeof(mem->dma[0]), KM_SLEEP);
for (unsigned i = 0; i < mem->dmamap->dm_nsegs; i++) {
@@ -226,6 +235,7 @@
PAGE_SIZE);
mem->dma[i] = mem->dmamap->dm_segs[i].ds_addr;
}
+#endif
} else {
#ifdef __NetBSD__
return -ENODEV;
@@ -238,6 +248,9 @@
if (!IS_ALIGNED(size, PAGE_SIZE))
return -EINVAL;
mem->pages = size >> PAGE_SHIFT;
+#ifdef __NetBSD__
+ KASSERT(mem->pages == mem->nseg);
+#endif
return 0;
} else
if ( (ret = nvif_unvers(ret, &argv, &argc, args->vn))) {
@@ -283,6 +296,7 @@
mem->dma[i] = mem->dmamap->dm_segs[i].ds_addr;
}
mem->pages = size;
+ KASSERT(mem->pages == mem->nseg);
#else
if (!(mem->mem = kvmalloc_array(size, sizeof(*mem->mem), GFP_KERNEL)))
return -ENOMEM;
Home |
Main Index |
Thread Index |
Old Index