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 Fix the logic around "parent is a subset ...



details:   https://anonhg.NetBSD.org/src/rev/e11627a2b761
branches:  trunk
changeset: 977460:e11627a2b761
user:      skrll <skrll%NetBSD.org@localhost>
date:      Sat Oct 24 14:51:59 2020 +0000

description:
Fix the logic around "parent is a subset and can be re-used" in
bus_dmatag_subregion.  Thanks to mrg@ for spotting the problem.

diffstat:

 sys/arch/arm/arm32/bus_dma.c |  29 +++++++++++++++--------------
 1 files changed, 15 insertions(+), 14 deletions(-)

diffs (67 lines):

diff -r 39f685f1813c -r e11627a2b761 sys/arch/arm/arm32/bus_dma.c
--- a/sys/arch/arm/arm32/bus_dma.c      Sat Oct 24 14:45:06 2020 +0000
+++ b/sys/arch/arm/arm32/bus_dma.c      Sat Oct 24 14:51:59 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bus_dma.c,v 1.123 2020/09/08 10:30:17 skrll Exp $      */
+/*     $NetBSD: bus_dma.c,v 1.124 2020/10/24 14:51:59 skrll Exp $      */
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 2020 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
 #include "opt_cputypes.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.123 2020/09/08 10:30:17 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.124 2020/10/24 14:51:59 skrll Exp $");
 
 #include <sys/param.h>
 
@@ -1816,35 +1816,36 @@
 
 #ifdef _ARM32_NEED_BUS_DMA_BOUNCE
        struct arm32_dma_range *dr;
-       bool subset = false;
+       bool psubset = true;
        size_t nranges = 0;
        size_t i;
        for (i = 0, dr = tag->_ranges; i < tag->_nranges; i++, dr++) {
                /*
-                * Are all the ranges in the parent tag a subset of the new
-                * range? If yes, we can continue to use the parent tag.
+                * If the new {min,max}_addr are narrower than any of the
+                * ranges in the parent tag then we need a new tag;
+                * otherwise the parent tag is a subset of the new
+                * range and can continue to be used.
                 */
-               if (dr->dr_sysbase >= min_addr
-                   && dr->dr_sysbase + dr->dr_len - 1 <= max_addr) {
-                       subset = true;
-               } else {
-                       subset = false;
+               if (min_addr > dr->dr_sysbase
+                   || max_addr < dr->dr_sysbase + dr->dr_len - 1) {
+                       psubset = false;
                }
                if (min_addr <= dr->dr_sysbase + dr->dr_len
                    && max_addr >= dr->dr_sysbase) {
                        nranges++;
                }
        }
-       if (subset) {
+       if (nranges == 0) {
+               nranges = 1;
+               psubset = false;
+       }
+       if (psubset) {
                *newtag = tag;
                /* if the tag must be freed, add a reference */
                if (tag->_tag_needs_free)
                        (tag->_tag_needs_free)++;
                return 0;
        }
-       if (nranges == 0) {
-               nranges = 1;
-       }
 
        const size_t tagsize = sizeof(*tag) + nranges * sizeof(*dr);
        if ((*newtag = kmem_intr_zalloc(tagsize,



Home | Main Index | Thread Index | Old Index