diff --git a/src/core/hle/service/nvdrv/core/nvmap.cpp b/src/core/hle/service/nvdrv/core/nvmap.cpp index 344fcbf51..9f83f3627 100644 --- a/src/core/hle/service/nvdrv/core/nvmap.cpp +++ b/src/core/hle/service/nvdrv/core/nvmap.cpp @@ -210,32 +210,17 @@ DAddr NvMap::PinHandle(NvMap::Handle::Id handle, bool low_area_pin) { handle_description->in_heap = true; } else { size_t aligned_up = Common::AlignUp(map_size, BIG_PAGE_SIZE); - constexpr size_t MAX_FREE_ATTEMPTS = 100; // Prevent infinite loop - size_t free_attempts = 0; while ((address = smmu.Allocate(aligned_up)) == 0) { // Free handles until the allocation succeeds std::scoped_lock queueLock(unmap_queue_lock); - bool freed_any = false; - // Try to free multiple handles from the queue - while (!unmap_queue.empty() && free_attempts < MAX_FREE_ATTEMPTS) { - if (auto freeHandleDesc{unmap_queue.front()}) { - // Handles in the unmap queue are guaranteed not to be pinned so don't bother - // checking if they are before unmapping - std::scoped_lock freeLock(freeHandleDesc->mutex); - if (freeHandleDesc->d_address) { - UnmapHandle(*freeHandleDesc); - freed_any = true; - } - // Remove from queue even if d_address was 0 (already unmapped) - unmap_queue.pop_front(); - } else { - unmap_queue.pop_front(); - } - free_attempts++; - } - - if (!freed_any || unmap_queue.empty()) { - LOG_CRITICAL(Service_NVDRV, "Ran out of SMMU address space! No more handles to free."); + if (auto freeHandleDesc{unmap_queue.front()}) { + // Handles in the unmap queue are guaranteed not to be pinned so don't bother + // checking if they are before unmapping + std::scoped_lock freeLock(freeHandleDesc->mutex); + if (freeHandleDesc->d_address) + UnmapHandle(*freeHandleDesc); + } else { + LOG_CRITICAL(Service_NVDRV, "Ran out of SMMU address space!"); // Break out of the loop to prevent infinite spinning when no handles can be freed return 0; } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 8dccaf841..18de13eff 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -1,6 +1,5 @@ // SPDX-FileCopyrightText: 2021 yuzu Emulator Project // SPDX-FileCopyrightText: 2021 Skyline Team and Contributors -// SPDX-FileCopyrightText: 2025 citron Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #include @@ -299,10 +298,6 @@ NvResult nvhost_as_gpu::Remap(std::span entries) { } DAddr base = nvmap.PinHandle(entry.handle, false); - if (!base) { - LOG_ERROR(Service_NVDRV, "Failed to pin handle {}: SMMU address space exhausted", entry.handle); - return NvResult::InsufficientMemory; - } DAddr device_address{static_cast( base + (static_cast(entry.handle_offset_big_pages) << vm.big_page_size_bits))}; @@ -358,12 +353,8 @@ NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) { return NvResult::BadValue; } - DAddr base = nvmap.PinHandle(params.handle, false); - if (!base) { - LOG_ERROR(Service_NVDRV, "Failed to pin handle {}: SMMU address space exhausted", params.handle); - return NvResult::InsufficientMemory; - } - DAddr device_address{static_cast(base + params.buffer_offset)}; + DAddr device_address{ + static_cast(nvmap.PinHandle(params.handle, false) + params.buffer_offset)}; u64 size{params.mapping_size ? params.mapping_size : handle->orig_size}; bool big_page{[&]() { diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp index 5486b6711..a0a7bfa40 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp @@ -1,5 +1,4 @@ // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project -// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include @@ -142,10 +141,6 @@ NvResult nvhost_nvdec_common::MapBuffer(IoctlMapBuffer& params, std::span(entries.size())); for (size_t i = 0; i < num_entries; i++) { DAddr pin_address = nvmap.PinHandle(entries[i].map_handle, true); - if (!pin_address) { - LOG_ERROR(Service_NVDRV, "Failed to pin handle {}: SMMU address space exhausted", entries[i].map_handle); - return NvResult::InsufficientMemory; - } entries[i].map_address = static_cast(pin_address); }