svn commit: r334028 - head/sys/arm/arm

Andrew Turner andrew at FreeBSD.org
Tue May 22 10:14:21 UTC 2018


Author: andrew
Date: Tue May 22 10:14:20 2018
New Revision: 334028
URL: https://svnweb.freebsd.org/changeset/base/334028

Log:
  Coalesce adjacent physical mappings.
  
  This reduces the overhead when we have many small mappings, e.g. on some
  EFI systems. This is to help use this code on arm64 where we may have a
  large number of entries from the EFI firmware.
  
  Obtained from:	ABT Systems Ltd
  Sponsored by:	Turing Robotic Industries
  Differential Revision:	https://reviews.freebsd.org/D15477

Modified:
  head/sys/arm/arm/physmem.c

Modified: head/sys/arm/arm/physmem.c
==============================================================================
--- head/sys/arm/arm/physmem.c	Tue May 22 08:51:16 2018	(r334027)
+++ head/sys/arm/arm/physmem.c	Tue May 22 10:14:20 2018	(r334028)
@@ -216,8 +216,13 @@ regions_to_avail(vm_paddr_t *avail, uint32_t exflags, 
 			 * could affect the remainder of this hw region.
 			 */
 			if ((xstart > start) && (xend < end)) {
-				avail[acnt++] = (vm_paddr_t)start;
-				avail[acnt++] = (vm_paddr_t)xstart;
+				if (acnt > 0 &&
+				    avail[acnt - 1] == (vm_paddr_t)start) {
+					avail[acnt - 1] = (vm_paddr_t)xstart;
+				} else {
+					avail[acnt++] = (vm_paddr_t)start;
+					avail[acnt++] = (vm_paddr_t)xstart;
+				}
 				availmem += 
 				    arm32_btop((vm_offset_t)(xstart - start));
 				start = xend;
@@ -238,8 +243,12 @@ regions_to_avail(vm_paddr_t *avail, uint32_t exflags, 
 		 * available entry for it.
 		 */
 		if (end > start) {
-			avail[acnt++] = (vm_paddr_t)start;
-			avail[acnt++] = (vm_paddr_t)end;
+			if (acnt > 0 && avail[acnt - 1] == (vm_paddr_t)start) {
+				avail[acnt - 1] = (vm_paddr_t)end;
+			} else {
+				avail[acnt++] = (vm_paddr_t)start;
+				avail[acnt++] = (vm_paddr_t)end;
+			}
 			availmem += arm32_btop((vm_offset_t)(end - start));
 		}
 		if (acnt >= MAX_AVAIL_ENTRIES)
@@ -254,7 +263,7 @@ regions_to_avail(vm_paddr_t *avail, uint32_t exflags, 
 /*
  * Insertion-sort a new entry into a regions list; sorted by start address.
  */
-static void
+static size_t
 insert_region(struct region *regions, size_t rcnt, vm_paddr_t addr,
     vm_size_t size, uint32_t flags)
 {
@@ -263,6 +272,16 @@ insert_region(struct region *regions, size_t rcnt, vm_
 
 	ep = regions + rcnt;
 	for (i = 0, rp = regions; i < rcnt; ++i, ++rp) {
+		if (flags == rp->flags) {
+			if (addr + size == rp->addr) {
+				rp->addr = addr;
+				rp->size += size;
+				return (rcnt);
+			} else if (rp->addr + rp->size == addr) {
+				rp->size += size;
+				return (rcnt);
+			}
+		}
 		if (addr < rp->addr) {
 			bcopy(rp, rp + 1, (ep - rp) * sizeof(*rp));
 			break;
@@ -271,6 +290,9 @@ insert_region(struct region *regions, size_t rcnt, vm_
 	rp->addr  = addr;
 	rp->size  = size;
 	rp->flags = flags;
+	rcnt++;
+
+	return (rcnt);
 }
 
 /*
@@ -322,7 +344,7 @@ arm_physmem_hardware_region(uint64_t pa, uint64_t sz)
 	sz  = trunc_page(sz - adj);
 
 	if (sz > 0 && hwcnt < nitems(hwregions))
-		insert_region(hwregions, hwcnt++, pa, sz, 0);
+		hwcnt = insert_region(hwregions, hwcnt, pa, sz, 0);
 }
 
 /*
@@ -341,7 +363,7 @@ void arm_physmem_exclude_region(vm_paddr_t pa, vm_size
 	sz  = round_page(sz + adj);
 
 	if (excnt < nitems(exregions))
-		insert_region(exregions, excnt++, pa, sz, exflags);
+		excnt = insert_region(exregions, excnt, pa, sz, exflags);
 }
 
 /*


More information about the svn-src-all mailing list