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/include/drm in bus_dmamap_load_pglist(...



details:   https://anonhg.NetBSD.org/src/rev/65db19eaba4f
branches:  trunk
changeset: 744994:65db19eaba4f
user:      mrg <mrg%NetBSD.org@localhost>
date:      Thu Feb 20 09:07:39 2020 +0000

description:
in bus_dmamap_load_pglist() try a 32-element array of
bus_dma_segment_t's before attempting to allocate.

this hopefully avoids hangs i've had in X since updating
from netbsd-8 to netbsd-9 that i've tracked down to this
function failing with ENOMEM.

XXX: maybe can avoid the alloc entirely by batching these
calls in 32 segments each.

XXX pullup-9

diffstat:

 sys/external/bsd/drm2/include/drm/bus_dma_hacks.h |  33 ++++++++++++++++------
 1 files changed, 24 insertions(+), 9 deletions(-)

diffs (68 lines):

diff -r 13e55a4dfbfe -r 65db19eaba4f sys/external/bsd/drm2/include/drm/bus_dma_hacks.h
--- a/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h Thu Feb 20 08:31:17 2020 +0000
+++ b/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h Thu Feb 20 09:07:39 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bus_dma_hacks.h,v 1.19 2020/01/22 07:53:45 jmcneill Exp $      */
+/*     $NetBSD: bus_dma_hacks.h,v 1.20 2020/02/20 09:07:39 mrg Exp $   */
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -118,12 +118,15 @@
 #endif
 }
 
+#define MAX_STACK_SEGS 32      /* XXXMRG: 512 bytes on 16 byte seg platforms */
+
 static inline int
 bus_dmamap_load_pglist(bus_dma_tag_t tag, bus_dmamap_t map,
     struct pglist *pglist, bus_size_t size, int flags)
 {
        km_flag_t kmflags;
        bus_dma_segment_t *segs;
+       bus_dma_segment_t stacksegs[MAX_STACK_SEGS];
        int nsegs, seg;
        struct vm_page *page;
        int error;
@@ -136,14 +139,23 @@
        }
 
        KASSERT(nsegs <= (SIZE_MAX / sizeof(segs[0])));
-       switch (flags & (BUS_DMA_WAITOK|BUS_DMA_NOWAIT)) {
-       case BUS_DMA_WAITOK:    kmflags = KM_SLEEP;     break;
-       case BUS_DMA_NOWAIT:    kmflags = KM_NOSLEEP;   break;
-       default:                panic("invalid flags: %d", flags);
+       if (nsegs > MAX_STACK_SEGS) {
+               switch (flags & (BUS_DMA_WAITOK|BUS_DMA_NOWAIT)) {
+               case BUS_DMA_WAITOK:
+                       kmflags = KM_SLEEP;
+                       break;
+               case BUS_DMA_NOWAIT:
+                       kmflags = KM_NOSLEEP;
+                       break;
+               default:
+                       panic("invalid flags: %d", flags);
+               }
+               segs = kmem_alloc((nsegs * sizeof(segs[0])), kmflags);
+               if (segs == NULL)
+                       return ENOMEM;
+       } else {
+               segs = stacksegs;
        }
-       segs = kmem_alloc((nsegs * sizeof(segs[0])), kmflags);
-       if (segs == NULL)
-               return ENOMEM;
 
        seg = 0;
        TAILQ_FOREACH(page, pglist, pageq.queue) {
@@ -166,7 +178,10 @@
 fail1: __unused
        bus_dmamap_unload(tag, map);
 fail0: KASSERT(error);
-out:   kmem_free(segs, (nsegs * sizeof(segs[0])));
+out:   if (segs != stacksegs) {
+               KASSERT(nsegs > MAX_STACK_SEGS);
+               kmem_free(segs, (nsegs * sizeof(segs[0])));
+       }
        return error;
 }
 



Home | Main Index | Thread Index | Old Index