From 6afb3bd10d178ae87487aa95e130e1f784ba94df Mon Sep 17 00:00:00 2001 From: Max Wash Date: Mon, 6 Feb 2023 20:38:32 +0000 Subject: [PATCH] memblock: add alignment parameter to alloc functions --- include/socks/memblock.h | 10 ++++++++-- vm/bootstrap.c | 2 +- vm/memblock.c | 25 +++++++++++++++---------- vm/page.c | 2 +- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/include/socks/memblock.h b/include/socks/memblock.h index 37df045..0f5cdf7 100644 --- a/include/socks/memblock.h +++ b/include/socks/memblock.h @@ -251,8 +251,11 @@ extern int memblock_reserve(phys_addr_t base, size_t size); previous calls to memblock_alloc() @param size the size of the buffer to allocate in bytes. + @param align the alignment to use. for example, an alignment of 4096 + will result in the returned pointer being a multiple + of 4096. this must be a power of 2. */ -extern void *memblock_alloc(size_t size); +extern void *memblock_alloc(size_t size, phys_addr_t align); /* allocate a block of memory, returning a physical address. @@ -270,8 +273,11 @@ extern void *memblock_alloc(size_t size); previous calls to memblock_alloc() @param size the size of the buffer to allocate in bytes. + @param align the alignment to use. for example, an alignment of 4096 + will result in the returned pointer being a multiple + of 4096. this must be a power of 2. */ -extern phys_addr_t memblock_alloc_phys(size_t size); +extern phys_addr_t memblock_alloc_phys(size_t size, phys_addr_t align); /* free a block of memory using its virtual address. diff --git a/vm/bootstrap.c b/vm/bootstrap.c index 7430c4f..975ca20 100644 --- a/vm/bootstrap.c +++ b/vm/bootstrap.c @@ -14,7 +14,7 @@ kern_status_t vm_bootstrap(const vm_zone_descriptor_t *zones, size_t nr_zones) int numa_count = 1; /* we're only worrying about UMA systems for now */ - node_data = memblock_alloc(sizeof(vm_pg_data_t) * numa_count); + node_data = memblock_alloc(sizeof(vm_pg_data_t) * numa_count, 8); vm_page_init_array(); diff --git a/vm/memblock.c b/vm/memblock.c index aed712e..0a87167 100644 --- a/vm/memblock.c +++ b/vm/memblock.c @@ -41,7 +41,7 @@ static memblock_region_t init_memory_regions[MEMBLOCK_INIT_MEMORY_REGION_COUNT]; static memblock_region_t init_reserved_regions[MEMBLOCK_INIT_RESERVED_REGION_COUNT]; -static phys_addr_t do_alloc(size_t size); +static phys_addr_t do_alloc(size_t size, phys_addr_t align); memblock_t memblock = { .memory.regions = init_memory_regions, @@ -59,7 +59,7 @@ static void memblock_double_capacity(memblock_type_t *type) { size_t new_max = type->max * 2; - phys_addr_t new_regions_p = do_alloc(new_max * sizeof(memblock_region_t)); + phys_addr_t new_regions_p = do_alloc(new_max * sizeof(memblock_region_t), 8); void *new_regions = (void *)(new_regions_p + memblock.m_voffset); memcpy(new_regions, type->regions, type->count * sizeof(memblock_region_t)); @@ -228,8 +228,13 @@ int memblock_reserve(uintptr_t base, size_t size) return memblock_add_range(&memblock.reserved, base, size, MEMBLOCK_RESERVED); } -static phys_addr_t do_alloc(size_t size) +static phys_addr_t do_alloc(size_t size, phys_addr_t align) { + if (!align) { + /* align to 8-byte boundary by default */ + align = 0x8; + } + phys_addr_t allocated_base = ADDR_MAX; phys_addr_t region_start = memblock.m_alloc_start - memblock.m_voffset; @@ -237,9 +242,9 @@ static phys_addr_t do_alloc(size_t size) memblock_iter_t it; for_each_free_mem_range (&it, region_start, region_end) { - if (it.it_base & 0xF) { - it.it_base &= ~0xF; - it.it_base += 0x10; + if (it.it_base & (align - 1)) { + it.it_base &= ~(align - 1); + it.it_base += align; } size_t region_size = it.it_limit - it.it_base + 1; @@ -261,13 +266,13 @@ static phys_addr_t do_alloc(size_t size) return allocated_base; } -void *memblock_alloc(size_t size) +void *memblock_alloc(size_t size, phys_addr_t align) { if (memblock.reserved.count >= memblock.reserved.max - 2) { memblock_double_capacity(&memblock.reserved); } - phys_addr_t p = do_alloc(size); + phys_addr_t p = do_alloc(size, align); if (p) { p += memblock.m_voffset; } @@ -275,13 +280,13 @@ void *memblock_alloc(size_t size) return (void *)p; } -phys_addr_t memblock_alloc_phys(size_t size) +phys_addr_t memblock_alloc_phys(size_t size, phys_addr_t align) { if (memblock.reserved.count >= memblock.reserved.max - 2) { memblock_double_capacity(&memblock.reserved); } - return do_alloc(size); + return do_alloc(size, align); } int memblock_free(void *p, size_t size) diff --git a/vm/page.c b/vm/page.c index 7f3fad2..7afaa08 100644 --- a/vm/page.c +++ b/vm/page.c @@ -69,7 +69,7 @@ void vm_page_init_array() nr_pages++; } - page_array = memblock_alloc(sizeof(vm_page_t) * nr_pages); + page_array = memblock_alloc(sizeof(vm_page_t) * nr_pages, 8); page_array_count = nr_pages; for (size_t i = 0; i < nr_pages; i++) {