1
0
Fork 0
forked from suyu/suyu

hle: kernel: Migrate MemoryManager to KMemoryManager.

This commit is contained in:
bunnei 2021-02-12 17:38:40 -08:00
parent 93109c870e
commit b1e27890e8
8 changed files with 48 additions and 47 deletions

View file

@ -170,6 +170,8 @@ add_library(core STATIC
hle/kernel/k_memory_block_manager.cpp hle/kernel/k_memory_block_manager.cpp
hle/kernel/k_memory_block_manager.h hle/kernel/k_memory_block_manager.h
hle/kernel/k_memory_layout.h hle/kernel/k_memory_layout.h
hle/kernel/k_memory_manager.cpp
hle/kernel/k_memory_manager.h
hle/kernel/k_page_bitmap.h hle/kernel/k_page_bitmap.h
hle/kernel/k_page_linked_list.h hle/kernel/k_page_linked_list.h
hle/kernel/k_priority_queue.h hle/kernel/k_priority_queue.h
@ -200,8 +202,6 @@ add_library(core STATIC
hle/kernel/kernel.cpp hle/kernel/kernel.cpp
hle/kernel/kernel.h hle/kernel/kernel.h
hle/kernel/memory_types.h hle/kernel/memory_types.h
hle/kernel/memory/memory_manager.cpp
hle/kernel/memory/memory_manager.h
hle/kernel/memory/page_heap.cpp hle/kernel/memory/page_heap.cpp
hle/kernel/memory/page_heap.h hle/kernel/memory/page_heap.h
hle/kernel/memory/page_table.cpp hle/kernel/memory/page_table.cpp

View file

@ -8,20 +8,20 @@
#include "common/assert.h" #include "common/assert.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "common/scope_exit.h" #include "common/scope_exit.h"
#include "core/hle/kernel/k_memory_manager.h"
#include "core/hle/kernel/k_page_linked_list.h" #include "core/hle/kernel/k_page_linked_list.h"
#include "core/hle/kernel/memory/memory_manager.h"
#include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/svc_results.h"
namespace Kernel::Memory { namespace Kernel {
std::size_t MemoryManager::Impl::Initialize(Pool new_pool, u64 start_address, u64 end_address) { std::size_t KMemoryManager::Impl::Initialize(Pool new_pool, u64 start_address, u64 end_address) {
const auto size{end_address - start_address}; const auto size{end_address - start_address};
// Calculate metadata sizes // Calculate metadata sizes
const auto ref_count_size{(size / PageSize) * sizeof(u16)}; const auto ref_count_size{(size / PageSize) * sizeof(u16)};
const auto optimize_map_size{(Common::AlignUp((size / PageSize), 64) / 64) * sizeof(u64)}; const auto optimize_map_size{(Common::AlignUp((size / PageSize), 64) / 64) * sizeof(u64)};
const auto manager_size{Common::AlignUp(optimize_map_size + ref_count_size, PageSize)}; const auto manager_size{Common::AlignUp(optimize_map_size + ref_count_size, PageSize)};
const auto page_heap_size{PageHeap::CalculateManagementOverheadSize(size)}; const auto page_heap_size{Memory::PageHeap::CalculateManagementOverheadSize(size)};
const auto total_metadata_size{manager_size + page_heap_size}; const auto total_metadata_size{manager_size + page_heap_size};
ASSERT(manager_size <= total_metadata_size); ASSERT(manager_size <= total_metadata_size);
ASSERT(Common::IsAligned(total_metadata_size, PageSize)); ASSERT(Common::IsAligned(total_metadata_size, PageSize));
@ -41,13 +41,13 @@ std::size_t MemoryManager::Impl::Initialize(Pool new_pool, u64 start_address, u6
return total_metadata_size; return total_metadata_size;
} }
void MemoryManager::InitializeManager(Pool pool, u64 start_address, u64 end_address) { void KMemoryManager::InitializeManager(Pool pool, u64 start_address, u64 end_address) {
ASSERT(pool < Pool::Count); ASSERT(pool < Pool::Count);
managers[static_cast<std::size_t>(pool)].Initialize(pool, start_address, end_address); managers[static_cast<std::size_t>(pool)].Initialize(pool, start_address, end_address);
} }
VAddr MemoryManager::AllocateAndOpenContinuous(std::size_t num_pages, std::size_t align_pages, VAddr KMemoryManager::AllocateAndOpenContinuous(std::size_t num_pages, std::size_t align_pages,
u32 option) { u32 option) {
// Early return if we're allocating no pages // Early return if we're allocating no pages
if (num_pages == 0) { if (num_pages == 0) {
return {}; return {};
@ -59,7 +59,7 @@ VAddr MemoryManager::AllocateAndOpenContinuous(std::size_t num_pages, std::size_
std::lock_guard lock{pool_locks[pool_index]}; std::lock_guard lock{pool_locks[pool_index]};
// Choose a heap based on our page size request // Choose a heap based on our page size request
const s32 heap_index{PageHeap::GetAlignedBlockIndex(num_pages, align_pages)}; const s32 heap_index{Memory::PageHeap::GetAlignedBlockIndex(num_pages, align_pages)};
// Loop, trying to iterate from each block // Loop, trying to iterate from each block
// TODO (bunnei): Support multiple managers // TODO (bunnei): Support multiple managers
@ -72,7 +72,7 @@ VAddr MemoryManager::AllocateAndOpenContinuous(std::size_t num_pages, std::size_
} }
// If we allocated more than we need, free some // If we allocated more than we need, free some
const auto allocated_pages{PageHeap::GetBlockNumPages(heap_index)}; const auto allocated_pages{Memory::PageHeap::GetBlockNumPages(heap_index)};
if (allocated_pages > num_pages) { if (allocated_pages > num_pages) {
chosen_manager.Free(allocated_block + num_pages * PageSize, allocated_pages - num_pages); chosen_manager.Free(allocated_block + num_pages * PageSize, allocated_pages - num_pages);
} }
@ -80,8 +80,8 @@ VAddr MemoryManager::AllocateAndOpenContinuous(std::size_t num_pages, std::size_
return allocated_block; return allocated_block;
} }
ResultCode MemoryManager::Allocate(KPageLinkedList& page_list, std::size_t num_pages, Pool pool, ResultCode KMemoryManager::Allocate(KPageLinkedList& page_list, std::size_t num_pages, Pool pool,
Direction dir) { Direction dir) {
ASSERT(page_list.GetNumPages() == 0); ASSERT(page_list.GetNumPages() == 0);
// Early return if we're allocating no pages // Early return if we're allocating no pages
@ -94,7 +94,7 @@ ResultCode MemoryManager::Allocate(KPageLinkedList& page_list, std::size_t num_p
std::lock_guard lock{pool_locks[pool_index]}; std::lock_guard lock{pool_locks[pool_index]};
// Choose a heap based on our page size request // Choose a heap based on our page size request
const s32 heap_index{PageHeap::GetBlockIndex(num_pages)}; const s32 heap_index{Memory::PageHeap::GetBlockIndex(num_pages)};
if (heap_index < 0) { if (heap_index < 0) {
return ResultOutOfMemory; return ResultOutOfMemory;
} }
@ -113,7 +113,7 @@ ResultCode MemoryManager::Allocate(KPageLinkedList& page_list, std::size_t num_p
// Keep allocating until we've allocated all our pages // Keep allocating until we've allocated all our pages
for (s32 index{heap_index}; index >= 0 && num_pages > 0; index--) { for (s32 index{heap_index}; index >= 0 && num_pages > 0; index--) {
const auto pages_per_alloc{PageHeap::GetBlockNumPages(index)}; const auto pages_per_alloc{Memory::PageHeap::GetBlockNumPages(index)};
while (num_pages >= pages_per_alloc) { while (num_pages >= pages_per_alloc) {
// Allocate a block // Allocate a block
@ -149,8 +149,8 @@ ResultCode MemoryManager::Allocate(KPageLinkedList& page_list, std::size_t num_p
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
ResultCode MemoryManager::Free(KPageLinkedList& page_list, std::size_t num_pages, Pool pool, ResultCode KMemoryManager::Free(KPageLinkedList& page_list, std::size_t num_pages, Pool pool,
Direction dir) { Direction dir) {
// Early return if we're freeing no pages // Early return if we're freeing no pages
if (!num_pages) { if (!num_pages) {
return RESULT_SUCCESS; return RESULT_SUCCESS;
@ -173,4 +173,4 @@ ResultCode MemoryManager::Free(KPageLinkedList& page_list, std::size_t num_pages
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
} // namespace Kernel::Memory } // namespace Kernel

View file

@ -17,9 +17,9 @@ namespace Kernel {
class KPageLinkedList; class KPageLinkedList;
} }
namespace Kernel::Memory { namespace Kernel {
class MemoryManager final : NonCopyable { class KMemoryManager final : NonCopyable {
public: public:
enum class Pool : u32 { enum class Pool : u32 {
Application = 0, Application = 0,
@ -41,7 +41,7 @@ public:
Mask = (0xF << Shift), Mask = (0xF << Shift),
}; };
MemoryManager() = default; KMemoryManager() = default;
constexpr std::size_t GetSize(Pool pool) const { constexpr std::size_t GetSize(Pool pool) const {
return managers[static_cast<std::size_t>(pool)].GetSize(); return managers[static_cast<std::size_t>(pool)].GetSize();
@ -84,7 +84,7 @@ private:
using RefCount = u16; using RefCount = u16;
private: private:
PageHeap heap; Memory::PageHeap heap;
Pool pool{}; Pool pool{};
public: public:
@ -118,4 +118,4 @@ private:
std::array<Impl, MaxManagerCount> managers; std::array<Impl, MaxManagerCount> managers;
}; };
} // namespace Kernel::Memory } // namespace Kernel

View file

@ -28,13 +28,13 @@
#include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/k_memory_layout.h" #include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_memory_manager.h"
#include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_resource_limit.h"
#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/k_shared_memory.h" #include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/kernel/k_slab_heap.h" #include "core/hle/kernel/k_slab_heap.h"
#include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/memory/memory_manager.h"
#include "core/hle/kernel/physical_core.h" #include "core/hle/kernel/physical_core.h"
#include "core/hle/kernel/process.h" #include "core/hle/kernel/process.h"
#include "core/hle/kernel/service_thread.h" #include "core/hle/kernel/service_thread.h"
@ -277,14 +277,14 @@ struct KernelCore::Impl {
constexpr PAddr time_addr{layout.System().StartAddress() + hid_size + font_size + irs_size}; constexpr PAddr time_addr{layout.System().StartAddress() + hid_size + font_size + irs_size};
// Initialize memory manager // Initialize memory manager
memory_manager = std::make_unique<Memory::MemoryManager>(); memory_manager = std::make_unique<KMemoryManager>();
memory_manager->InitializeManager(Memory::MemoryManager::Pool::Application, memory_manager->InitializeManager(KMemoryManager::Pool::Application,
layout.Application().StartAddress(), layout.Application().StartAddress(),
layout.Application().EndAddress()); layout.Application().EndAddress());
memory_manager->InitializeManager(Memory::MemoryManager::Pool::Applet, memory_manager->InitializeManager(KMemoryManager::Pool::Applet,
layout.Applet().StartAddress(), layout.Applet().StartAddress(),
layout.Applet().EndAddress()); layout.Applet().EndAddress());
memory_manager->InitializeManager(Memory::MemoryManager::Pool::System, memory_manager->InitializeManager(KMemoryManager::Pool::System,
layout.System().StartAddress(), layout.System().StartAddress(),
layout.System().EndAddress()); layout.System().EndAddress());
@ -348,7 +348,7 @@ struct KernelCore::Impl {
std::atomic<u32> next_host_thread_id{Core::Hardware::NUM_CPU_CORES}; std::atomic<u32> next_host_thread_id{Core::Hardware::NUM_CPU_CORES};
// Kernel memory management // Kernel memory management
std::unique_ptr<Memory::MemoryManager> memory_manager; std::unique_ptr<KMemoryManager> memory_manager;
std::unique_ptr<KSlabHeap<Page>> user_slab_heap_pages; std::unique_ptr<KSlabHeap<Page>> user_slab_heap_pages;
// Shared memory for services // Shared memory for services
@ -573,11 +573,11 @@ KThread* KernelCore::GetCurrentEmuThread() const {
return impl->GetCurrentEmuThread(); return impl->GetCurrentEmuThread();
} }
Memory::MemoryManager& KernelCore::MemoryManager() { KMemoryManager& KernelCore::MemoryManager() {
return *impl->memory_manager; return *impl->memory_manager;
} }
const Memory::MemoryManager& KernelCore::MemoryManager() const { const KMemoryManager& KernelCore::MemoryManager() const {
return *impl->memory_manager; return *impl->memory_manager;
} }

View file

@ -27,22 +27,18 @@ struct EventType;
namespace Kernel { namespace Kernel {
namespace Memory {
class MemoryManager;
} // namespace Memory
class ClientPort; class ClientPort;
class GlobalSchedulerContext; class GlobalSchedulerContext;
class HandleTable; class HandleTable;
class PhysicalCore; class KMemoryManager;
class Process;
class KResourceLimit; class KResourceLimit;
class KScheduler; class KScheduler;
class KSharedMemory; class KSharedMemory;
class KThread;
class PhysicalCore;
class Process;
class ServiceThread; class ServiceThread;
class Synchronization; class Synchronization;
class KThread;
class TimeManager; class TimeManager;
template <typename T> template <typename T>
@ -180,10 +176,10 @@ public:
void RegisterHostThread(); void RegisterHostThread();
/// Gets the virtual memory manager for the kernel. /// Gets the virtual memory manager for the kernel.
Memory::MemoryManager& MemoryManager(); KMemoryManager& MemoryManager();
/// Gets the virtual memory manager for the kernel. /// Gets the virtual memory manager for the kernel.
const Memory::MemoryManager& MemoryManager() const; const KMemoryManager& MemoryManager() const;
/// Gets the slab heap allocated for user space pages. /// Gets the slab heap allocated for user space pages.
KSlabHeap<Page>& GetUserSlabHeapPages(); KSlabHeap<Page>& GetUserSlabHeapPages();

View file

@ -62,7 +62,7 @@ PageTable::PageTable(Core::System& system) : system{system} {}
ResultCode PageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, ResultCode PageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type,
bool enable_aslr, VAddr code_addr, std::size_t code_size, bool enable_aslr, VAddr code_addr, std::size_t code_size,
Memory::MemoryManager::Pool pool) { KMemoryManager::Pool pool) {
const auto GetSpaceStart = [this](KAddressSpaceInfo::Type type) { const auto GetSpaceStart = [this](KAddressSpaceInfo::Type type) {
return KAddressSpaceInfo::GetAddressSpaceStart(address_space_width, type); return KAddressSpaceInfo::GetAddressSpaceStart(address_space_width, type);

View file

@ -11,7 +11,7 @@
#include "common/page_table.h" #include "common/page_table.h"
#include "core/file_sys/program_metadata.h" #include "core/file_sys/program_metadata.h"
#include "core/hle/kernel/k_memory_block.h" #include "core/hle/kernel/k_memory_block.h"
#include "core/hle/kernel/memory/memory_manager.h" #include "core/hle/kernel/k_memory_manager.h"
#include "core/hle/result.h" #include "core/hle/result.h"
namespace Core { namespace Core {
@ -30,7 +30,7 @@ public:
ResultCode InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr, ResultCode InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr,
VAddr code_addr, std::size_t code_size, VAddr code_addr, std::size_t code_size,
Memory::MemoryManager::Pool pool); KMemoryManager::Pool pool);
ResultCode MapProcessCode(VAddr addr, std::size_t pages_count, KMemoryState state, ResultCode MapProcessCode(VAddr addr, std::size_t pages_count, KMemoryState state,
KMemoryPermission perm); KMemoryPermission perm);
ResultCode MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size); ResultCode MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size);
@ -271,7 +271,7 @@ private:
bool is_kernel{}; bool is_kernel{};
bool is_aslr_enabled{}; bool is_aslr_enabled{};
MemoryManager::Pool memory_pool{MemoryManager::Pool::Application}; KMemoryManager::Pool memory_pool{KMemoryManager::Pool::Application};
Common::PageTable page_table_impl; Common::PageTable page_table_impl;

View file

@ -274,7 +274,7 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
// Set initial resource limits // Set initial resource limits
resource_limit->SetLimitValue( resource_limit->SetLimitValue(
LimitableResource::PhysicalMemory, LimitableResource::PhysicalMemory,
kernel.MemoryManager().GetSize(Memory::MemoryManager::Pool::Application)); kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application));
KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory, KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory,
code_size + system_resource_size); code_size + system_resource_size);
if (!memory_reservation.Succeeded()) { if (!memory_reservation.Succeeded()) {
@ -285,7 +285,7 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
// Initialize proces address space // Initialize proces address space
if (const ResultCode result{ if (const ResultCode result{
page_table->InitializeForProcess(metadata.GetAddressSpaceType(), false, 0x8000000, page_table->InitializeForProcess(metadata.GetAddressSpaceType(), false, 0x8000000,
code_size, Memory::MemoryManager::Pool::Application)}; code_size, KMemoryManager::Pool::Application)};
result.IsError()) { result.IsError()) {
return result; return result;
} }
@ -323,6 +323,11 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
UNREACHABLE(); UNREACHABLE();
} }
// Set initial resource limits
resource_limit->SetLimitValue(
LimitableResource::PhysicalMemory,
kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application));
resource_limit->SetLimitValue(LimitableResource::Threads, 608); resource_limit->SetLimitValue(LimitableResource::Threads, 608);
resource_limit->SetLimitValue(LimitableResource::Events, 700); resource_limit->SetLimitValue(LimitableResource::Events, 700);
resource_limit->SetLimitValue(LimitableResource::TransferMemory, 128); resource_limit->SetLimitValue(LimitableResource::TransferMemory, 128);