WIP: [video_core] Fix memory leak when GPU accuracy level is set to Normal #26

Closed
MaranBr wants to merge 1 commit from memory-leak-fix into master
3 changed files with 8 additions and 23 deletions

View file

@ -384,13 +384,13 @@ static void* ChooseVirtualBase(size_t virtual_size) {
// Try up to 64 times to allocate memory at random addresses in the range.
for (int i = 0; i < 64; i++) {
// Calculate a possible location.
uintptr_t hint_address = ((rng() % range) + lower) * HugePageSize;
uintptr_t hint_address = ((((i == 0) ? 0 : rng()) % range) + lower) * HugePageSize;
// Try to map.
// Note: we may be able to take advantage of MAP_FIXED_NOREPLACE here.
// Added MAP_FIXED_NOREPLACE here to stop mprotect eventually (20+ mins) failing with out of memory.
void* map_pointer =
mmap(reinterpret_cast<void*>(hint_address), virtual_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_FIXED_NOREPLACE, -1, 0);
// If we successfully mapped, we're done.
if (reinterpret_cast<uintptr_t>(map_pointer) == hint_address) {
@ -463,7 +463,7 @@ public:
}
backing_base = static_cast<u8*>(
mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
mmap(nullptr, backing_size, PROT_READ | PROT_WRITE | MAP_FIXED_NOREPLACE, MAP_SHARED, fd, 0));
if (backing_base == MAP_FAILED) {
LOG_CRITICAL(HW_Memory, "mmap failed: {}", strerror(errno));
throw std::bad_alloc{};

View file

@ -72,7 +72,6 @@ public:
}
void SignalFence(std::function<void()>&& func) {
bool delay_fence = Settings::IsGPULevelHigh();
if constexpr (!can_async_check) {
TryReleasePendingFences<false>();
}
@ -82,14 +81,9 @@ public:
if constexpr (can_async_check) {
guard.lock();
}
if (delay_fence) {
uncommitted_operations.emplace_back(std::move(func));
}
uncommitted_operations.emplace_back(std::move(func));
pending_operations.emplace_back(std::move(uncommitted_operations));
QueueFence(new_fence);
if (!delay_fence) {
func();
}
fences.push(std::move(new_fence));
if (should_flush) {
rasterizer.FlushCommands();

View file

@ -257,13 +257,10 @@ void QueryCacheBase<Traits>::CounterReport(GPUVAddr addr, QueryType counter_type
};
u8* pointer = impl->device_memory.template GetPointer<u8>(cpu_addr);
u8* pointer_timestamp = impl->device_memory.template GetPointer<u8>(cpu_addr + 8);
bool is_synced = !Settings::IsGPULevelHigh() && is_fence;
std::function<void()> operation([this, is_synced, streamer, query_base = query, query_location,
std::function<void()> operation([this, streamer, query_base = query, query_location,
pointer, pointer_timestamp] {
if (True(query_base->flags & QueryFlagBits::IsInvalidated)) {
if (!is_synced) [[likely]] {
impl->pending_unregister.push_back(query_location);
}
impl->pending_unregister.push_back(query_location);
return;
}
if (False(query_base->flags & QueryFlagBits::IsFinalValueSynced)) [[unlikely]] {
@ -280,9 +277,7 @@ void QueryCacheBase<Traits>::CounterReport(GPUVAddr addr, QueryType counter_type
u32 value = static_cast<u32>(query_base->value);
std::memcpy(pointer, &value, sizeof(value));
}
if (!is_synced) [[likely]] {
impl->pending_unregister.push_back(query_location);
}
impl->pending_unregister.push_back(query_location);
});
if (is_fence) {
impl->rasterizer.SignalFence(std::move(operation));
@ -301,10 +296,6 @@ void QueryCacheBase<Traits>::CounterReport(GPUVAddr addr, QueryType counter_type
}
impl->rasterizer.SyncOperation(std::move(operation));
}
if (is_synced) {
streamer->Free(new_query_id);
return;
}
auto [cont_addr, base] = gen_caching_indexing(cpu_addr);
{
std::scoped_lock lock(cache_mutex);