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