Fix reservation in GPU VMM

Rather than reserving a region so it *can* be used by MapAllocate
reserved actually prevents a region from being used by MapAllocate.
This commit is contained in:
Billy Laws 2020-08-09 16:01:38 +01:00 committed by ◱ PixelyIon
parent ade8a711fb
commit ae131502c6
3 changed files with 16 additions and 16 deletions

View File

@ -83,7 +83,7 @@ namespace skyline::gpu::vmm {
throw exception("Failed to insert chunk into GPU address space!"); throw exception("Failed to insert chunk into GPU address space!");
} }
u64 MemoryManager::AllocateSpace(u64 size) { u64 MemoryManager::ReserveSpace(u64 size) {
size = util::AlignUp(size, constant::GpuPageSize); size = util::AlignUp(size, constant::GpuPageSize);
auto newChunk = FindChunk(size, ChunkState::Unmapped); auto newChunk = FindChunk(size, ChunkState::Unmapped);
if (!newChunk) if (!newChunk)
@ -91,23 +91,23 @@ namespace skyline::gpu::vmm {
auto chunk = *newChunk; auto chunk = *newChunk;
chunk.size = size; chunk.size = size;
chunk.state = ChunkState::Allocated; chunk.state = ChunkState::Reserved;
return InsertChunk(chunk); return InsertChunk(chunk);
} }
u64 MemoryManager::AllocateFixed(u64 address, u64 size) { u64 MemoryManager::ReserveFixed(u64 address, u64 size) {
if ((address & (constant::GpuPageSize - 1)) != 0) if ((address & (constant::GpuPageSize - 1)) != 0)
return 0; return 0;
size = util::AlignUp(size, constant::GpuPageSize); size = util::AlignUp(size, constant::GpuPageSize);
return InsertChunk(ChunkDescriptor(address, size, 0, ChunkState::Allocated)); return InsertChunk(ChunkDescriptor(address, size, 0, ChunkState::Reserved));
} }
u64 MemoryManager::MapAllocated(u64 address, u64 size) { u64 MemoryManager::MapAllocate(u64 address, u64 size) {
size = util::AlignUp(size, constant::GpuPageSize); size = util::AlignUp(size, constant::GpuPageSize);
auto mappedChunk = FindChunk(size, ChunkState::Allocated); auto mappedChunk = FindChunk(size, ChunkState::Unmapped);
if (!mappedChunk) if (!mappedChunk)
return 0; return 0;
@ -139,7 +139,7 @@ namespace skyline::gpu::vmm {
if (chunk == chunkList.end()) if (chunk == chunkList.end())
return false; return false;
chunk->state = ChunkState::Allocated; chunk->state = ChunkState::Reserved;
chunk->cpuAddress = 0; chunk->cpuAddress = 0;
return true; return true;

View File

@ -17,7 +17,7 @@ namespace skyline {
*/ */
enum ChunkState { enum ChunkState {
Unmapped, //!< The chunk is unmapped Unmapped, //!< The chunk is unmapped
Allocated, //!< The chunk is allocated but unmapped Reserved, //!< The chunk is reserved
Mapped //!< The chunk is mapped and a CPU side address is present Mapped //!< The chunk is mapped and a CPU side address is present
}; };
@ -68,19 +68,19 @@ namespace skyline {
MemoryManager(const DeviceState &state); MemoryManager(const DeviceState &state);
/** /**
* @brief This reserves a region of the GPU address space so it can be automatically used when mapping * @brief This reserves a region of the GPU address space so it will not be chosen automatically when mapping
* @param size The size of the region to reserve * @param size The size of the region to reserve
* @return The virtual GPU base address of the region base * @return The virtual GPU base address of the region base
*/ */
u64 AllocateSpace(u64 size); u64 ReserveSpace(u64 size);
/** /**
* @brief This reserves a fixed region of the GPU address space so it can be automatically used when mapping * @brief This reserves a fixed region of the GPU address space so it will not be chosen automatically when mapping
* @param address The virtual base address of the region to allocate * @param address The virtual base address of the region to allocate
* @param size The size of the region to allocate * @param size The size of the region to allocate
* @return The virtual address of the region base * @return The virtual address of the region base
*/ */
u64 AllocateFixed(u64 address, u64 size); u64 ReserveFixed(u64 address, u64 size);
/** /**
* @brief This maps a physical CPU memory region to an automatically chosen virtual memory region * @brief This maps a physical CPU memory region to an automatically chosen virtual memory region
@ -88,7 +88,7 @@ namespace skyline {
* @param size The size of the region to map * @param size The size of the region to map
* @return The virtual address of the region base * @return The virtual address of the region base
*/ */
u64 MapAllocated(u64 address, u64 size); u64 MapAllocate(u64 address, u64 size);
/** /**
* @brief This maps a physical CPU memory region to a fixed virtual memory region * @brief This maps a physical CPU memory region to a fixed virtual memory region

View File

@ -37,9 +37,9 @@ namespace skyline::service::nvdrv::device {
u64 size = static_cast<u64>(region.pages) * static_cast<u64>(region.pageSize); u64 size = static_cast<u64>(region.pages) * static_cast<u64>(region.pageSize);
if (region.flags & 1) if (region.flags & 1)
region.offset = state.gpu->memoryManager.AllocateFixed(region.offset, size); region.offset = state.gpu->memoryManager.ReserveFixed(region.offset, size);
else else
region.offset = state.gpu->memoryManager.AllocateSpace(size); region.offset = state.gpu->memoryManager.ReserveSpace(size);
if (region.offset == 0) { if (region.offset == 0) {
state.logger->Warn("Failed to allocate GPU address space region!"); state.logger->Warn("Failed to allocate GPU address space region!");
@ -78,7 +78,7 @@ namespace skyline::service::nvdrv::device {
if (region.flags & 1) if (region.flags & 1)
region.offset = state.gpu->memoryManager.MapFixed(region.offset, mapPhysicalAddress, mapSize); region.offset = state.gpu->memoryManager.MapFixed(region.offset, mapPhysicalAddress, mapSize);
else else
region.offset = state.gpu->memoryManager.MapAllocated(mapPhysicalAddress, mapSize); region.offset = state.gpu->memoryManager.MapAllocate(mapPhysicalAddress, mapSize);
if (region.offset == 0) { if (region.offset == 0) {
state.logger->Warn("Failed to map GPU address space region!"); state.logger->Warn("Failed to map GPU address space region!");