From: Alexander Graf Date: Sun, 16 Sep 2018 15:05:29 +0000 (+0200) Subject: efi_loader: Merge memory map entries X-Git-Url: http://git.dujemihanovic.xyz/img/sics.gif?a=commitdiff_plain;h=7b05667ce23914f6989f8c2ade1ac96ce4ff4eb6;p=u-boot.git efi_loader: Merge memory map entries We currently do not combine memory entries that are adjacent and have the same attributes. The problem with that is that our memory map can easily grow multiple hundreds of entries in a simple UEFI Shell environment. So let's make sure we always combine all entries to make the memory map as small as possible. That way every other piece of code that loops through it should also gain some nice speed ups. Signed-off-by: Alexander Graf --- diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 4f8cb545ad..5bd4f4d7fc 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -65,9 +65,54 @@ static int efi_mem_cmp(void *priv, struct list_head *a, struct list_head *b) return -1; } +static uint64_t desc_get_end(struct efi_mem_desc *desc) +{ + return desc->physical_start + (desc->num_pages << EFI_PAGE_SHIFT); +} + static void efi_mem_sort(void) { + struct list_head *lhandle; + struct efi_mem_list *prevmem = NULL; + bool merge_again = true; + list_sort(NULL, &efi_mem, efi_mem_cmp); + + /* Now merge entries that can be merged */ + while (merge_again) { + merge_again = false; + list_for_each(lhandle, &efi_mem) { + struct efi_mem_list *lmem; + struct efi_mem_desc *prev = &prevmem->desc; + struct efi_mem_desc *cur; + uint64_t pages; + + lmem = list_entry(lhandle, struct efi_mem_list, link); + if (!prevmem) { + prevmem = lmem; + continue; + } + + cur = &lmem->desc; + + if ((desc_get_end(cur) == prev->physical_start) && + (prev->type == cur->type) && + (prev->attribute == cur->attribute)) { + /* There is an existing map before, reuse it */ + pages = cur->num_pages; + prev->num_pages += pages; + prev->physical_start -= pages << EFI_PAGE_SHIFT; + prev->virtual_start -= pages << EFI_PAGE_SHIFT; + list_del(&lmem->link); + free(lmem); + + merge_again = true; + break; + } + + prevmem = lmem; + } + } } /** efi_mem_carve_out - unmap memory region