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