Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/arm32 Use kmem instead of malloc.



details:   https://anonhg.NetBSD.org/src/rev/b83a57cf9b60
branches:  trunk
changeset: 327033:b83a57cf9b60
user:      matt <matt%NetBSD.org@localhost>
date:      Wed Feb 26 01:05:52 2014 +0000

description:
Use kmem instead of malloc.
Fix various corner cases with bounce buffers.
Use PMAP_NOCACHE instead of manipulating PTEs directly.

diffstat:

 sys/arch/arm/arm32/bus_dma.c |  82 +++++++++++++++++++++++++------------------
 1 files changed, 47 insertions(+), 35 deletions(-)

diffs (236 lines):

diff -r e2b29346d93e -r b83a57cf9b60 sys/arch/arm/arm32/bus_dma.c
--- a/sys/arch/arm/arm32/bus_dma.c      Wed Feb 26 01:03:03 2014 +0000
+++ b/sys/arch/arm/arm32/bus_dma.c      Wed Feb 26 01:05:52 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bus_dma.c,v 1.80 2013/02/18 16:03:25 matt Exp $        */
+/*     $NetBSD: bus_dma.c,v 1.81 2014/02/26 01:05:52 matt Exp $        */
 
 /*-
  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -32,8 +32,10 @@
 
 #define _ARM32_BUS_DMA_PRIVATE
 
+#include "opt_arm_bus_space.h"
+
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.80 2013/02/18 16:03:25 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.81 2014/02/26 01:05:52 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -43,7 +45,7 @@
 #include <sys/reboot.h>
 #include <sys/conf.h>
 #include <sys/file.h>
-#include <sys/malloc.h>
+#include <sys/kmem.h>
 #include <sys/mbuf.h>
 #include <sys/vnode.h>
 #include <sys/device.h>
@@ -64,6 +66,8 @@
        EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "busdma", "loads");
 static struct evcnt bus_dma_bounced_loads =
        EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "busdma", "bounced loads");
+static struct evcnt bus_dma_coherent_loads =
+       EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "busdma", "coherent loads");
 static struct evcnt bus_dma_read_bounces =
        EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "busdma", "read bounces");
 static struct evcnt bus_dma_write_bounces =
@@ -97,6 +101,7 @@
 EVCNT_ATTACH_STATIC(bus_dma_bounced_creates);
 EVCNT_ATTACH_STATIC(bus_dma_loads);
 EVCNT_ATTACH_STATIC(bus_dma_bounced_loads);
+EVCNT_ATTACH_STATIC(bus_dma_coherent_loads);
 EVCNT_ATTACH_STATIC(bus_dma_read_bounces);
 EVCNT_ATTACH_STATIC(bus_dma_write_bounces);
 EVCNT_ATTACH_STATIC(bus_dma_unloads);
@@ -315,7 +320,6 @@
 {
        struct arm32_bus_dmamap *map;
        void *mapstore;
-       size_t mapsize;
 
 #ifdef DEBUG_DMA
        printf("dmamap_create: t=%p size=%lx nseg=%x msegsz=%lx boundary=%lx flags=%x\n",
@@ -334,10 +338,10 @@
         * The bus_dmamap_t includes one bus_dma_segment_t, hence
         * the (nsegments - 1).
         */
-       mapsize = sizeof(struct arm32_bus_dmamap) +
+       const size_t mapsize = sizeof(struct arm32_bus_dmamap) +
            (sizeof(bus_dma_segment_t) * (nsegments - 1));
-       const int mallocflags = M_ZERO|(flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK;
-       if ((mapstore = malloc(mapsize, M_DMAMAP, mallocflags)) == NULL)
+       const int zallocflags = (flags & BUS_DMA_NOWAIT) ? KM_NOSLEEP : KM_SLEEP;
+       if ((mapstore = kmem_intr_zalloc(mapsize, zallocflags)) == NULL)
                return (ENOMEM);
 
        map = (struct arm32_bus_dmamap *)mapstore;
@@ -360,7 +364,6 @@
        struct arm32_bus_dma_cookie *cookie;
        int cookieflags;
        void *cookiestore;
-       size_t cookiesize;
        int error;
 
        cookieflags = 0;
@@ -379,13 +382,13 @@
                return 0;
        }
 
-       cookiesize = sizeof(struct arm32_bus_dma_cookie) +
+       const size_t cookiesize = sizeof(struct arm32_bus_dma_cookie) +
            (sizeof(bus_dma_segment_t) * map->_dm_segcnt);
 
        /*
         * Allocate our cookie.
         */
-       if ((cookiestore = malloc(cookiesize, M_DMAMAP, mallocflags)) == NULL) {
+       if ((cookiestore = kmem_intr_zalloc(cookiesize, zallocflags)) == NULL) {
                error = ENOMEM;
                goto out;
        }
@@ -426,13 +429,16 @@
         * Free any bounce pages this map might hold.
         */
        if (cookie != NULL) {
+               const size_t cookiesize = sizeof(struct arm32_bus_dma_cookie) +
+                   (sizeof(bus_dma_segment_t) * map->_dm_segcnt);
+
                if (cookie->id_flags & _BUS_DMA_IS_BOUNCING)
                        STAT_INCR(bounced_unloads);
                map->dm_nsegs = 0;
                if (cookie->id_flags & _BUS_DMA_HAS_BOUNCE)
                        _bus_dma_free_bouncebuf(t, map);
                STAT_INCR(bounced_destroys);
-               free(cookie, M_DMAMAP);
+               kmem_intr_free(cookie, cookiesize);
        } else
 #endif
        STAT_INCR(destroys);
@@ -440,7 +446,9 @@
        if (map->dm_nsegs > 0)
                STAT_INCR(unloads);
 
-       free(map, M_DMAMAP);
+       const size_t mapsize = sizeof(struct arm32_bus_dmamap) +
+           (sizeof(bus_dma_segment_t) * (map->_dm_segcnt - 1));
+       kmem_intr_free(map, mapsize);
 }
 
 /*
@@ -501,6 +509,11 @@
                map->_dm_vmspace = vm;
                map->_dm_origbuf = buf;
                map->_dm_buftype = _BUS_DMA_BUFTYPE_LINEAR;
+               if (map->_dm_flags & _BUS_DMAMAP_COHERENT) {
+                       STAT_INCR(coherent_loads);
+               } else {
+                       STAT_INCR(loads);
+               }
                return 0;
        }
 #ifdef _ARM32_NEED_BUS_DMA_BOUNCE
@@ -640,6 +653,11 @@
                map->_dm_origbuf = m0;
                map->_dm_buftype = _BUS_DMA_BUFTYPE_MBUF;
                map->_dm_vmspace = vmspace_kernel();    /* always kernel */
+               if (map->_dm_flags & _BUS_DMAMAP_COHERENT) {
+                       STAT_INCR(coherent_loads);
+               } else {
+                       STAT_INCR(loads);
+               }
                return 0;
        }
 #ifdef _ARM32_NEED_BUS_DMA_BOUNCE
@@ -698,6 +716,11 @@
                map->_dm_origbuf = uio;
                map->_dm_buftype = _BUS_DMA_BUFTYPE_UIO;
                map->_dm_vmspace = uio->uio_vmspace;
+               if (map->_dm_flags & _BUS_DMAMAP_COHERENT) {
+                       STAT_INCR(coherent_loads);
+               } else {
+                       STAT_INCR(loads);
+               }
        }
        return (error);
 }
@@ -1242,7 +1265,6 @@
        vaddr_t va;
        paddr_t pa;
        int curseg;
-       pt_entry_t *ptep;
        const uvm_flag_t kmflags = UVM_KMF_VAONLY
            | ((flags & BUS_DMA_NOWAIT) != 0 ? UVM_KMF_NOWAIT : 0);
        vsize_t align = 0;
@@ -1299,7 +1321,7 @@
                if (size >= L1_S_SIZE)
                        align = L1_S_SIZE;
                else
-                       align = L2_S_SIZE;
+                       align = L2_L_SIZE;
        }
 
        va = uvm_km_alloc(kernel_map, size, align, kmflags);
@@ -1335,8 +1357,8 @@
                                uncached = false;
                        }
 
-                       pmap_kenter_pa(va, pa,
-                           VM_PROT_READ | VM_PROT_WRITE, PMAP_WIRED);
+                       pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE,
+                           PMAP_WIRED | (uncached ? PMAP_NOCACHE : 0));
 
                        /*
                         * If the memory must remain coherent with the
@@ -1346,19 +1368,6 @@
                         * contain the virtal addresses we are making
                         * uncacheable.
                         */
-                       if (uncached) {
-                               cpu_dcache_wbinv_range(va, PAGE_SIZE);
-                               cpu_sdcache_wbinv_range(va, pa, PAGE_SIZE);
-                               cpu_drain_writebuf();
-                               ptep = vtopte(va);
-                               *ptep &= ~L2_S_CACHE_MASK;
-                               PTE_SYNC(ptep);
-                               tlb_flush();
-                       }
-#ifdef DEBUG_DMA
-                       ptep = vtopte(va);
-                       printf(" pte=v%p *pte=%x\n", ptep, *ptep);
-#endif /* DEBUG_DMA */
                }
        }
        pmap_update(pmap_kernel());
@@ -1766,9 +1775,9 @@
                nranges = 1;
        }
 
-       size_t mallocsize = sizeof(*tag) + nranges * sizeof(*dr);
-       if ((*newtag = malloc(mallocsize, M_DMAMAP,
-           (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL)
+       const size_t tagsize = sizeof(*tag) + nranges * sizeof(*dr);
+       if ((*newtag = kmem_intr_zalloc(tagsize,
+           (flags & BUS_DMA_NOWAIT) ? KM_NOSLEEP : KM_SLEEP)) == NULL)
                return ENOMEM;
 
        dr = (void *)(*newtag + 1);
@@ -1813,10 +1822,13 @@
 #ifdef _ARM32_NEED_BUS_DMA_BOUNCE
        switch (tag->_tag_needs_free) {
        case 0:
-               break;                          /* not allocated with malloc */
-       case 1:
-               free(tag, M_DMAMAP);            /* last reference to tag */
+               break;                          /* not allocated with kmem */
+       case 1: {
+               const size_t tagsize = sizeof(*tag)
+                   + tag->_nranges * sizeof(*tag->_ranges);
+               kmem_intr_free(tag, tagsize);   /* last reference to tag */
                break;
+       }
        default:
                (tag->_tag_needs_free)--;       /* one less reference */
        }



Home | Main Index | Thread Index | Old Index