diff options
author | Tom Rini <trini@konsulko.com> | 2024-12-30 13:22:15 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2024-12-30 13:22:15 -0600 |
commit | a3d3d869b6f5860660718d05ee9b4d040d938e0f (patch) | |
tree | 7568cb0d3cf66d65e53aa1dc908b7c19c05a9105 /lib/lmb.c | |
parent | 793e21b83dc83c118940602caa4eb973f6ccb566 (diff) | |
parent | 1a25191bc1381f320a359a5dc9c835dde4658175 (diff) |
Merge patch series "Cleanup the LMB subsystem"
Ilias Apalodimas <ilias.apalodimas@linaro.org> says:
The LMB subsystem was used opportunistically for a number of years.
A while back Sughosh merged it with the EFI subsystem in order to have a
common allocator and avoid subsystems overwriting memory they shouldn't.
This is an initial cleanup of all the crud we gathered over the years.
There's no functional change expected from the patches as they just cleanup
some abstraction functions and rename a few variables to make more
sense.
I plan to make even bigger changes -- e.g I don't see the point of
having *_alloc() and *_reserve() versions of the functions since they
do the same thing and just cause confusion. lmb_alloc_addr_flags()
returning the base address on success makes little sense since we
already *request* the address on the function arguments, etc.
Since this patchset grew enough already, I'd like to get it in
before more refactoring happens.
It's worth noting that although some patches slightly increase the code
size due to an extra flags argument being carried around, the final
result is eventually smaller.
# qemu_arm64_lwip_defconfig (version string adds another 20b)
add/remove: 0/5 grow/shrink: 15/1 up/down: 568/-628 (-60)
Function old new delta
lmb_alloc_base 80 324 +244
lmb_alloc_addr 8 144 +136
lmb_reserve 8 96 +88
version_string 50 70 +20
boot_relocate_fdt 488 508 +20
boot_ramdisk_high 268 284 +16
lmb_add_region_flags 696 704 +8
boot_fdt_reserve_region 100 108 +8
load_serial 548 552 +4
lmb_alloc 8 12 +4
image_setup_libfdt 368 372 +4
do_load 728 732 +4
do_bootz 332 336 +4
do_booti 520 524 +4
bootm_run_states 2176 2180 +4
lmb_alloc_addr_flags 4 - -4
boot_fdt_add_mem_rsv_regions 284 280 -4
lmb_alloc_base_flags 76 - -76
lmb_reserve_flags 96 - -96
_lmb_alloc_addr 144 - -144
_lmb_alloc_base 304 - -304
Total: Before=1020102, After=1020042, chg -0.01%
# sandbox_defconfig (version string adds another 20b)
add/remove: 0/3 grow/shrink: 24/3 up/down: 523/-501 (22)
Function old new delta
lmb_alloc_base 48 299 +251
lmb_alloc_addr 4 92 +88
lmb_reserve 4 58 +54
test_alloc_addr 2933 2963 +30
version_string 50 70 +20
lib_test_lmb_overlapping_reserve 1018 1030 +12
lmb_add_region_flags 600 610 +10
test_multi_alloc.constprop 3034 3042 +8
test_get_unreserved_size 1032 1038 +6
boot_relocate_fdt 599 605 +6
boot_fdt_reserve_region 67 73 +6
lmb_alloc 4 9 +5
lmb_free_flags 190 194 +4
wget_handler 1530 1533 +3
tftp_handler 1190 1192 +2
test_noreserved 1207 1209 +2
test_bigblock 911 913 +2
load_serial 946 948 +2
lib_test_lmb_flags 2101 2103 +2
do_spi_flash 3150 3152 +2
do_bootz 526 528 +2
do_bootm_linux 2067 2069 +2
bootm_run_states 5275 5277 +2
_fs_read.lto_priv 331 333 +2
lmb_dump_region.lto_priv 356 353 -3
lmb_add 59 52 -7
efi_allocate_pages.part 303 249 -54
lmb_reserve_flags 65 - -65
_lmb_alloc_addr.lto_priv 92 - -92
_lmb_alloc_base.lto_priv 280 - -280
Total: Before=2492722, After=2492744, chg +0.00%
Link: https://lore.kernel.org/r/20241218070251.686383-1-ilias.apalodimas@linaro.org
Diffstat (limited to 'lib/lmb.c')
-rw-r--r-- | lib/lmb.c | 136 |
1 files changed, 45 insertions, 91 deletions
diff --git a/lib/lmb.c b/lib/lmb.c index f9880a8dc62..7ca44591e1d 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -188,7 +188,7 @@ static long lmb_resize_regions(struct alist *lmb_rgn_lst, * * %-1 - Failure */ static long lmb_add_region_flags(struct alist *lmb_rgn_lst, phys_addr_t base, - phys_size_t size, enum lmb_flags flags) + phys_size_t size, u32 flags) { unsigned long coalesced = 0; long ret, i; @@ -201,7 +201,7 @@ static long lmb_add_region_flags(struct alist *lmb_rgn_lst, phys_addr_t base, for (i = 0; i < lmb_rgn_lst->count; i++) { phys_addr_t rgnbase = rgn[i].base; phys_size_t rgnsize = rgn[i].size; - enum lmb_flags rgnflags = rgn[i].flags; + u32 rgnflags = rgn[i].flags; ret = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); if (ret > 0) { @@ -342,11 +342,6 @@ static long lmb_overlaps_region(struct alist *lmb_rgn_lst, phys_addr_t base, return (i < lmb_rgn_lst->count) ? i : -1; } -static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size) -{ - return addr & ~(size - 1); -} - /* * IOVA LMB memory maps using lmb pointers instead of the global LMB memory map. */ @@ -355,7 +350,7 @@ int io_lmb_setup(struct lmb *io_lmb) { int ret; - ret = alist_init(&io_lmb->free_mem, sizeof(struct lmb_region), + ret = alist_init(&io_lmb->available_mem, sizeof(struct lmb_region), (uint)LMB_ALIST_INITIAL_SIZE); if (!ret) { log_debug("Unable to initialise the list for LMB free IOVA\n"); @@ -376,13 +371,13 @@ int io_lmb_setup(struct lmb *io_lmb) void io_lmb_teardown(struct lmb *io_lmb) { - alist_uninit(&io_lmb->free_mem); + alist_uninit(&io_lmb->available_mem); alist_uninit(&io_lmb->used_mem); } long io_lmb_add(struct lmb *io_lmb, phys_addr_t base, phys_size_t size) { - return lmb_add_region_flags(&io_lmb->free_mem, base, size, LMB_NONE); + return lmb_add_region_flags(&io_lmb->available_mem, base, size, LMB_NONE); } /* derived and simplified from _lmb_alloc_base() */ @@ -392,15 +387,15 @@ phys_addr_t io_lmb_alloc(struct lmb *io_lmb, phys_size_t size, ulong align) phys_addr_t base = 0; phys_addr_t res_base; struct lmb_region *lmb_used = io_lmb->used_mem.data; - struct lmb_region *lmb_memory = io_lmb->free_mem.data; + struct lmb_region *lmb_memory = io_lmb->available_mem.data; - for (i = io_lmb->free_mem.count - 1; i >= 0; i--) { + for (i = io_lmb->available_mem.count - 1; i >= 0; i--) { phys_addr_t lmbbase = lmb_memory[i].base; phys_size_t lmbsize = lmb_memory[i].size; if (lmbsize < size) continue; - base = lmb_align_down(lmbbase + lmbsize - size, align); + base = ALIGN_DOWN(lmbbase + lmbsize - size, align); while (base && lmbbase <= base) { rgn = lmb_overlaps_region(&io_lmb->used_mem, base, size); @@ -416,7 +411,7 @@ phys_addr_t io_lmb_alloc(struct lmb *io_lmb, phys_size_t size, ulong align) res_base = lmb_used[rgn].base; if (res_base < size) break; - base = lmb_align_down(res_base - size, align); + base = ALIGN_DOWN(res_base - size, align); } } return 0; @@ -435,14 +430,14 @@ long io_lmb_free(struct lmb *io_lmb, phys_addr_t base, phys_size_t size) static struct lmb lmb; -static bool lmb_should_notify(enum lmb_flags flags) +static bool lmb_should_notify(u32 flags) { return !lmb.test && !(flags & LMB_NONOTIFY) && CONFIG_IS_ENABLED(EFI_LOADER); } static int lmb_map_update_notify(phys_addr_t addr, phys_size_t size, u8 op, - enum lmb_flags flags) + u32 flags) { u64 efi_addr; u64 pages; @@ -475,7 +470,7 @@ static int lmb_map_update_notify(phys_addr_t addr, phys_size_t size, u8 op, return 0; } -static void lmb_print_region_flags(enum lmb_flags flags) +static void lmb_print_region_flags(u32 flags) { const char * const flag_str[] = { "none", "no-map", "no-overwrite", "no-notify" }; @@ -500,7 +495,7 @@ static void lmb_dump_region(struct alist *lmb_rgn_lst, char *name) { struct lmb_region *rgn = lmb_rgn_lst->data; unsigned long long base, size, end; - enum lmb_flags flags; + u32 flags; int i; printf(" %s.count = %#x\n", name, lmb_rgn_lst->count); @@ -520,7 +515,7 @@ static void lmb_dump_region(struct alist *lmb_rgn_lst, char *name) void lmb_dump_all_force(void) { printf("lmb_dump_all:\n"); - lmb_dump_region(&lmb.free_mem, "memory"); + lmb_dump_region(&lmb.available_mem, "memory"); lmb_dump_region(&lmb.used_mem, "reserved"); } @@ -558,12 +553,11 @@ static void lmb_reserve_uboot_region(void) if (bank_end > end) bank_end = end - 1; - lmb_reserve_flags(rsv_start, bank_end - rsv_start + 1, - LMB_NOOVERWRITE); + lmb_reserve(rsv_start, bank_end - rsv_start + 1, LMB_NOOVERWRITE); if (gd->flags & GD_FLG_SKIP_RELOC) - lmb_reserve_flags((phys_addr_t)(uintptr_t)_start, - gd->mon_len, LMB_NOOVERWRITE); + lmb_reserve((phys_addr_t)(uintptr_t)_start, + gd->mon_len, LMB_NOOVERWRITE); break; } @@ -589,7 +583,7 @@ static __maybe_unused void lmb_reserve_common_spl(void) if (IS_ENABLED(CONFIG_SPL_STACK_R_ADDR)) { rsv_start = gd->start_addr_sp - 16384; rsv_size = 16384; - lmb_reserve_flags(rsv_start, rsv_size, LMB_NOOVERWRITE); + lmb_reserve(rsv_start, rsv_size, LMB_NOOVERWRITE); } if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS)) { @@ -597,7 +591,7 @@ static __maybe_unused void lmb_reserve_common_spl(void) rsv_start = (phys_addr_t)(uintptr_t)__bss_start; rsv_size = (phys_addr_t)(uintptr_t)__bss_end - (phys_addr_t)(uintptr_t)__bss_start; - lmb_reserve_flags(rsv_start, rsv_size, LMB_NOOVERWRITE); + lmb_reserve(rsv_start, rsv_size, LMB_NOOVERWRITE); } } @@ -629,28 +623,22 @@ void lmb_add_memory(void) * allocated */ if (bd->bi_dram[i].start >= ram_top) - lmb_reserve_flags(bd->bi_dram[i].start, size, - LMB_NOOVERWRITE); + lmb_reserve(bd->bi_dram[i].start, size, + LMB_NOOVERWRITE); else if (bank_end > ram_top) - lmb_reserve_flags(ram_top, bank_end - ram_top, - LMB_NOOVERWRITE); + lmb_reserve(ram_top, bank_end - ram_top, + LMB_NOOVERWRITE); } } } -static long lmb_add_region(struct alist *lmb_rgn_lst, phys_addr_t base, - phys_size_t size) -{ - return lmb_add_region_flags(lmb_rgn_lst, base, size, LMB_NONE); -} - /* This routine may be called with relocation disabled. */ long lmb_add(phys_addr_t base, phys_size_t size) { long ret; - struct alist *lmb_rgn_lst = &lmb.free_mem; + struct alist *lmb_rgn_lst = &lmb.available_mem; - ret = lmb_add_region(lmb_rgn_lst, base, size); + ret = lmb_add_region_flags(lmb_rgn_lst, base, size, LMB_NONE); if (ret) return ret; @@ -674,7 +662,7 @@ long lmb_free(phys_addr_t base, phys_size_t size) return lmb_free_flags(base, size, LMB_NONE); } -long lmb_reserve_flags(phys_addr_t base, phys_size_t size, enum lmb_flags flags) +long lmb_reserve(phys_addr_t base, phys_size_t size, u32 flags) { long ret = 0; struct alist *lmb_rgn_lst = &lmb.used_mem; @@ -686,22 +674,17 @@ long lmb_reserve_flags(phys_addr_t base, phys_size_t size, enum lmb_flags flags) return lmb_map_update_notify(base, size, MAP_OP_RESERVE, flags); } -long lmb_reserve(phys_addr_t base, phys_size_t size) -{ - return lmb_reserve_flags(base, size, LMB_NONE); -} - static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align, - phys_addr_t max_addr, enum lmb_flags flags) + phys_addr_t max_addr, u32 flags) { int ret; long i, rgn; phys_addr_t base = 0; phys_addr_t res_base; struct lmb_region *lmb_used = lmb.used_mem.data; - struct lmb_region *lmb_memory = lmb.free_mem.data; + struct lmb_region *lmb_memory = lmb.available_mem.data; - for (i = lmb.free_mem.count - 1; i >= 0; i--) { + for (i = lmb.available_mem.count - 1; i >= 0; i--) { phys_addr_t lmbbase = lmb_memory[i].base; phys_size_t lmbsize = lmb_memory[i].size; @@ -709,13 +692,13 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align, continue; if (max_addr == LMB_ALLOC_ANYWHERE) { - base = lmb_align_down(lmbbase + lmbsize - size, align); + base = ALIGN_DOWN(lmbbase + lmbsize - size, align); } else if (lmbbase < max_addr) { base = lmbbase + lmbsize; if (base < lmbbase) base = -1; base = min(base, max_addr); - base = lmb_align_down(base - size, align); + base = ALIGN_DOWN(base - size, align); } else { continue; } @@ -740,7 +723,7 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align, res_base = lmb_used[rgn].base; if (res_base < size) break; - base = lmb_align_down(res_base - size, align); + base = ALIGN_DOWN(res_base - size, align); } } return 0; @@ -748,24 +731,11 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t lmb_alloc(phys_size_t size, ulong align) { - return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE); -} - -phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) -{ - phys_addr_t alloc; - - alloc = _lmb_alloc_base(size, align, max_addr, LMB_NONE); - - if (alloc == 0) - printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", - (ulong)size, (ulong)max_addr); - - return alloc; + return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE, LMB_NONE); } -phys_addr_t lmb_alloc_base_flags(phys_size_t size, ulong align, - phys_addr_t max_addr, uint flags) +phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr, + uint flags) { phys_addr_t alloc; @@ -778,14 +748,13 @@ phys_addr_t lmb_alloc_base_flags(phys_size_t size, ulong align, return alloc; } -static phys_addr_t _lmb_alloc_addr(phys_addr_t base, phys_size_t size, - enum lmb_flags flags) +phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags) { long rgn; - struct lmb_region *lmb_memory = lmb.free_mem.data; + struct lmb_region *lmb_memory = lmb.available_mem.data; /* Check if the requested address is in one of the memory regions */ - rgn = lmb_overlaps_region(&lmb.free_mem, base, size); + rgn = lmb_overlaps_region(&lmb.available_mem, base, size); if (rgn >= 0) { /* * Check if the requested end address is in the same memory @@ -795,7 +764,7 @@ static phys_addr_t _lmb_alloc_addr(phys_addr_t base, phys_size_t size, lmb_memory[rgn].size, base + size - 1, 1)) { /* ok, reserve the memory */ - if (!lmb_reserve_flags(base, size, flags)) + if (!lmb_reserve(base, size, flags)) return base; } } @@ -803,31 +772,16 @@ static phys_addr_t _lmb_alloc_addr(phys_addr_t base, phys_size_t size, return 0; } -/* - * Try to allocate a specific address range: must be in defined memory but not - * reserved - */ -phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) -{ - return _lmb_alloc_addr(base, size, LMB_NONE); -} - -phys_addr_t lmb_alloc_addr_flags(phys_addr_t base, phys_size_t size, - uint flags) -{ - return _lmb_alloc_addr(base, size, flags); -} - /* Return number of bytes from a given address that are free */ phys_size_t lmb_get_free_size(phys_addr_t addr) { int i; long rgn; struct lmb_region *lmb_used = lmb.used_mem.data; - struct lmb_region *lmb_memory = lmb.free_mem.data; + struct lmb_region *lmb_memory = lmb.available_mem.data; /* check if the requested address is in the memory regions */ - rgn = lmb_overlaps_region(&lmb.free_mem, addr, 1); + rgn = lmb_overlaps_region(&lmb.available_mem, addr, 1); if (rgn >= 0) { for (i = 0; i < lmb.used_mem.count; i++) { if (addr < lmb_used[i].base) { @@ -841,8 +795,8 @@ phys_size_t lmb_get_free_size(phys_addr_t addr) } } /* if we come here: no reserved ranges above requested addr */ - return lmb_memory[lmb.free_mem.count - 1].base + - lmb_memory[lmb.free_mem.count - 1].size - addr; + return lmb_memory[lmb.available_mem.count - 1].base + + lmb_memory[lmb.available_mem.count - 1].size - addr; } return 0; } @@ -865,7 +819,7 @@ static int lmb_setup(bool test) { bool ret; - ret = alist_init(&lmb.free_mem, sizeof(struct lmb_region), + ret = alist_init(&lmb.available_mem, sizeof(struct lmb_region), (uint)LMB_ALIST_INITIAL_SIZE); if (!ret) { log_debug("Unable to initialise the list for LMB free memory\n"); @@ -925,7 +879,7 @@ int lmb_push(struct lmb *store) void lmb_pop(struct lmb *store) { - alist_uninit(&lmb.free_mem); + alist_uninit(&lmb.available_mem); alist_uninit(&lmb.used_mem); lmb = *store; } |