The branch stable/12 has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=f0350417eb3c39c6a03d311da79638fa7cdb0f3c

commit f0350417eb3c39c6a03d311da79638fa7cdb0f3c
Author:     Mark Johnston <[email protected]>
AuthorDate: 2020-12-18 16:04:48 +0000
Commit:     Mark Johnston <[email protected]>
CommitDate: 2021-01-06 14:41:09 +0000

    acpi: Ensure that adjacent memory affinity table entries are coalesced
    
    The SRAT may contain multiple distinct entries that together describe a
    contiguous region of physical memory.  In this case we were not
    coalescing the corresponding entries in the memory affinity table, which
    led to fragmented phys_avail[] entries.  Since r338431 the vm_phys_segs[]
    entries derived from phys_avail[] will be coalesced, resulting in a
    situation where vm_phys_segs[] entries do not have a covering
    phys_avail[] entry.  vm_page_startup() will not add such segments to the
    physical memory allocator, leaving them unused.
    
    Reported by:    Don Morris <[email protected]>
    Reviewed by:    kib, vangyzen
    
    (cherry picked from commit 0f8b212a1e41d6eabf2a17442bcbe4f128f023f8)
---
 sys/dev/acpica/acpi_pxm.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/sys/dev/acpica/acpi_pxm.c b/sys/dev/acpica/acpi_pxm.c
index 04be00e96b50..808886d744f0 100644
--- a/sys/dev/acpica/acpi_pxm.c
+++ b/sys/dev/acpica/acpi_pxm.c
@@ -265,6 +265,7 @@ srat_parse_entry(ACPI_SUBTABLE_HEADER *entry, void *arg)
        ACPI_SRAT_MEM_AFFINITY *mem;
        ACPI_SRAT_GICC_AFFINITY *gicc;
        static struct cpu_info *cpup;
+       uint64_t base, length;
        int domain, i, slot;
 
        switch (entry->Type) {
@@ -327,20 +328,22 @@ srat_parse_entry(ACPI_SUBTABLE_HEADER *entry, void *arg)
                break;
        case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
                mem = (ACPI_SRAT_MEM_AFFINITY *)entry;
+               base = mem->BaseAddress;
+               length = mem->Length;
+               domain = mem->ProximityDomain;
+
                if (bootverbose)
                        printf(
                    "SRAT: Found memory domain %d addr 0x%jx len 0x%jx: %s\n",
-                           mem->ProximityDomain, (uintmax_t)mem->BaseAddress,
-                           (uintmax_t)mem->Length,
+                           domain, (uintmax_t)base, (uintmax_t)length,
                            (mem->Flags & ACPI_SRAT_MEM_ENABLED) ?
                            "enabled" : "disabled");
                if (!(mem->Flags & ACPI_SRAT_MEM_ENABLED))
                        break;
-               if (mem->BaseAddress >= maxphyaddr ||
-                   !overlaps_phys_avail(mem->BaseAddress,
-                   mem->BaseAddress + mem->Length)) {
+               if (base >= maxphyaddr ||
+                   !overlaps_phys_avail(base, base + length)) {
                        printf("SRAT: Ignoring memory at addr 0x%jx\n",
-                           (uintmax_t)mem->BaseAddress);
+                           (uintmax_t)base);
                        break;
                }
                if (num_mem == VM_PHYSSEG_MAX) {
@@ -350,10 +353,20 @@ srat_parse_entry(ACPI_SUBTABLE_HEADER *entry, void *arg)
                }
                slot = num_mem;
                for (i = 0; i < num_mem; i++) {
-                       if (mem_info[i].end <= mem->BaseAddress)
+                       if (mem_info[i].domain == domain) {
+                               /* Try to extend an existing segment. */
+                               if (base == mem_info[i].end) {
+                                       mem_info[i].end += length;
+                                       return;
+                               }
+                               if (base + length == mem_info[i].start) {
+                                       mem_info[i].start -= length;
+                                       return;
+                               }
+                       }
+                       if (mem_info[i].end <= base)
                                continue;
-                       if (mem_info[i].start <
-                           (mem->BaseAddress + mem->Length)) {
+                       if (mem_info[i].start < base + length) {
                                printf("SRAT: Overlapping memory entries\n");
                                *(int *)arg = ENXIO;
                                return;
@@ -362,9 +375,9 @@ srat_parse_entry(ACPI_SUBTABLE_HEADER *entry, void *arg)
                }
                for (i = num_mem; i > slot; i--)
                        mem_info[i] = mem_info[i - 1];
-               mem_info[slot].start = mem->BaseAddress;
-               mem_info[slot].end = mem->BaseAddress + mem->Length;
-               mem_info[slot].domain = mem->ProximityDomain;
+               mem_info[slot].start = base;
+               mem_info[slot].end = base + length;
+               mem_info[slot].domain = domain;
                num_mem++;
                break;
        }
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to