From 66114c927286271c328c1ec3994dd87a491fa5f1 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Tue, 27 Aug 2024 07:31:25 -0700 Subject: [PATCH] memory: Account for alignment in direct memory suitability checks and add more debugging. --- src/core/memory.cpp | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 420416bfa..2722c68a9 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -45,6 +45,9 @@ void MemoryManager::SetupMemoryRegions(u64 flexible_size) { // Note that this should never be called after direct memory allocations have been made. dmem_map.clear(); dmem_map.emplace(0, DirectMemoryArea{0, total_direct_size}); + + LOG_INFO(Kernel_Vmm, "Configured memory regions: flexible size = {:#x}, direct size = {:#x}", + total_flexible_size, total_direct_size); } PAddr MemoryManager::Allocate(PAddr search_start, PAddr search_end, size_t size, u64 alignment, @@ -54,12 +57,17 @@ PAddr MemoryManager::Allocate(PAddr search_start, PAddr search_end, size_t size, auto dmem_area = FindDmemArea(search_start); const auto is_suitable = [&] { - return dmem_area->second.is_free && dmem_area->second.size >= size; + const auto aligned_base = alignment > 0 ? Common::AlignUp(dmem_area->second.base, alignment) + : dmem_area->second.base; + const auto alignment_size = aligned_base - dmem_area->second.base; + const auto remaining_size = + dmem_area->second.size >= alignment_size ? dmem_area->second.size - alignment_size : 0; + return dmem_area->second.is_free && remaining_size >= size; }; while (!is_suitable() && dmem_area->second.GetEnd() <= search_end) { dmem_area++; } - ASSERT_MSG(is_suitable(), "Unable to find free direct memory area"); + ASSERT_MSG(is_suitable(), "Unable to find free direct memory area: size = {:#x}", size); // Align free position PAddr free_addr = dmem_area->second.base; @@ -345,14 +353,19 @@ int MemoryManager::DirectQueryAvailable(PAddr search_start, PAddr search_end, si continue; } - if (dmem_area->second.size > max_size) { - paddr = dmem_area->second.base; - max_size = dmem_area->second.size; + const auto aligned_base = alignment > 0 ? Common::AlignUp(dmem_area->second.base, alignment) + : dmem_area->second.base; + const auto alignment_size = aligned_base - dmem_area->second.base; + const auto remaining_size = + dmem_area->second.size >= alignment_size ? dmem_area->second.size - alignment_size : 0; + if (remaining_size > max_size) { + paddr = aligned_base; + max_size = remaining_size; } dmem_area++; } - *phys_addr_out = alignment > 0 ? Common::AlignUp(paddr, alignment) : paddr; + *phys_addr_out = paddr; *size_out = max_size; return ORBIS_OK; } @@ -430,7 +443,8 @@ MemoryManager::DMemHandle MemoryManager::CarveDmemArea(PAddr addr, size_t size) const PAddr start_in_area = addr - area.base; const PAddr end_in_vma = start_in_area + size; - ASSERT_MSG(end_in_vma <= area.size, "Mapping cannot fit inside free region"); + ASSERT_MSG(end_in_vma <= area.size, "Mapping cannot fit inside free region: size = {:#x}", + size); if (end_in_vma != area.size) { // Split VMA at the end of the allocated region