Browse Source

debug uma impl

temporary-branch
CamilleLaVey 1 day ago
parent
commit
4b3608b58d
  1. 135
      src/common/host_memory.cpp

135
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<AHardwareBuffer*> buffers;
std::vector<int> 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<AHardwareBuffer*> buffers;
std::vector<int> 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<off_t>(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<u8*>(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<off_t>(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<u8*>(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<AHardwareBuffer* const> AhbWindows() const noexcept {

Loading…
Cancel
Save