From 4b3608b58d6ebe6b37290cb6dd96388d23623fb8 Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Sat, 1 Aug 2026 03:07:57 -0400 Subject: [PATCH] debug uma impl --- src/common/host_memory.cpp | 135 +++++++++++++++++++++---------------- 1 file changed, 76 insertions(+), 59 deletions(-) diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp index 5199dd88b1..66ff190257 100644 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp @@ -703,76 +703,93 @@ public: backing_size >> 20, total_physical >> 20); return false; } - constexpr size_t window_size = 256ULL << 20; - const AHardwareBuffer_Desc window_desc = MakeBlobDesc(window_size); - if (is_supported(&window_desc) == 0) { - LOG_WARNING(HW_Memory, "Allocator rejects {} MiB hardware buffer windows", - window_size >> 20); - return false; - } if (!ProbeAhbBacking(get_native_handle)) { return false; } - const size_t num_windows = (backing_size + window_size - 1) / window_size; - std::vector buffers; - std::vector buffer_fds; - const auto cleanup = [&] { - for (AHardwareBuffer* buffer : buffers) { - AHardwareBuffer_release(buffer); + const auto try_window_size = [&](size_t window_size) -> bool { + const size_t num_windows = (backing_size + window_size - 1) / window_size; + std::vector buffers; + std::vector buffer_fds; + const auto cleanup = [&] { + for (AHardwareBuffer* buffer : buffers) { + AHardwareBuffer_release(buffer); + } + buffers.clear(); + buffer_fds.clear(); + }; + for (size_t i = 0; i < num_windows; ++i) { + const size_t len = (std::min)(window_size, backing_size - i * window_size); + const AHardwareBuffer_Desc desc = MakeBlobDesc(len); + AHardwareBuffer* buffer{}; + if (AHardwareBuffer_allocate(&desc, &buffer) != 0 || buffer == nullptr) { + LOG_WARNING(HW_Memory, "Hardware buffer allocation failed for window {}", i); + cleanup(); + return false; + } + buffers.push_back(buffer); + const NativeHandle* const handle = get_native_handle(buffer); + if (handle == nullptr || handle->numFds < 1) { + LOG_WARNING(HW_Memory, "Hardware buffer has no mappable file descriptor"); + cleanup(); + return false; + } + const int buffer_fd = handle->data[0]; + const off_t buffer_len = lseek(buffer_fd, 0, SEEK_END); + if (buffer_len < static_cast(len)) { + LOG_WARNING(HW_Memory, "Hardware buffer descriptor smaller than requested"); + cleanup(); + return false; + } + buffer_fds.push_back(buffer_fd); } - buffers.clear(); - buffer_fds.clear(); - }; - for (size_t i = 0; i < num_windows; ++i) { - const size_t len = (std::min)(window_size, backing_size - i * window_size); - const AHardwareBuffer_Desc desc = MakeBlobDesc(len); - AHardwareBuffer* buffer{}; - if (AHardwareBuffer_allocate(&desc, &buffer) != 0 || buffer == nullptr) { - LOG_WARNING(HW_Memory, "Hardware buffer allocation failed for window {}", i); + u8* const base = + static_cast(mmap(nullptr, backing_size, PROT_NONE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0)); + if (base == MAP_FAILED) { cleanup(); return false; } - buffers.push_back(buffer); - const NativeHandle* const handle = get_native_handle(buffer); - if (handle == nullptr || handle->numFds < 1) { - LOG_WARNING(HW_Memory, "Hardware buffer has no mappable file descriptor"); - cleanup(); - return false; + for (size_t i = 0; i < num_windows; ++i) { + const size_t len = (std::min)(window_size, backing_size - i * window_size); + if (mmap(base + i * window_size, len, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_FIXED, buffer_fds[i], 0) == MAP_FAILED) { + LOG_WARNING(HW_Memory, "Hardware buffer mmap failed: {}", strerror(errno)); + munmap(base, backing_size); + cleanup(); + return false; + } } - const int buffer_fd = handle->data[0]; - const off_t buffer_len = lseek(buffer_fd, 0, SEEK_END); - if (buffer_len < static_cast(len)) { - LOG_WARNING(HW_Memory, "Hardware buffer descriptor smaller than requested"); - cleanup(); - return false; + backing_base = base; + ahb_windows = std::move(buffers); + ahb_fds = std::move(buffer_fds); + ahb_window_size = window_size; + ahb_backing = true; + committed_backing_size.store(backing_size, std::memory_order_relaxed); + LOG_INFO(HW_Memory, + "Guest memory backed by {} hardware buffer windows of {} MiB, {} MiB committed", + ahb_windows.size(), window_size >> 20, backing_size >> 20); + return true; + }; + static constexpr size_t candidate_window_sizes[] = { + 1024ULL << 20, + 512ULL << 20, + 256ULL << 20, + 128ULL << 20, + }; + for (const size_t candidate : candidate_window_sizes) { + const AHardwareBuffer_Desc window_desc = MakeBlobDesc(candidate); + if (is_supported(&window_desc) == 0) { + LOG_DEBUG(HW_Memory, "Allocator rejects {} MiB hardware buffer windows", + candidate >> 20); + continue; } - buffer_fds.push_back(buffer_fd); - } - u8* const base = static_cast(mmap(nullptr, backing_size, PROT_NONE, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0)); - if (base == MAP_FAILED) { - cleanup(); - return false; - } - for (size_t i = 0; i < num_windows; ++i) { - const size_t len = (std::min)(window_size, backing_size - i * window_size); - if (mmap(base + i * window_size, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, - buffer_fds[i], 0) == MAP_FAILED) { - LOG_WARNING(HW_Memory, "Hardware buffer mmap failed: {}", strerror(errno)); - munmap(base, backing_size); - cleanup(); - return false; + if (try_window_size(candidate)) { + return true; } + LOG_WARNING(HW_Memory, "Could not back guest memory with {} MiB windows", + candidate >> 20); } - backing_base = base; - ahb_windows = std::move(buffers); - ahb_fds = std::move(buffer_fds); - ahb_window_size = window_size; - ahb_backing = true; - committed_backing_size.store(backing_size, std::memory_order_relaxed); - LOG_INFO(HW_Memory, "Guest memory backed by {} hardware buffer windows, {} MiB committed", - ahb_windows.size(), backing_size >> 20); - return true; + return false; } std::span AhbWindows() const noexcept {