Merge pull request #6185 from ameerj/process-reslimit
kernel/process: Replace process resource limit instance with the kernel's resource limit
This commit is contained in:
		| @@ -67,8 +67,13 @@ struct KernelCore::Impl { | |||||||
|         is_phantom_mode_for_singlecore = false; |         is_phantom_mode_for_singlecore = false; | ||||||
|  |  | ||||||
|         InitializePhysicalCores(); |         InitializePhysicalCores(); | ||||||
|         InitializeSystemResourceLimit(kernel, system); |  | ||||||
|         InitializeMemoryLayout(); |         // Derive the initial memory layout from the emulated board | ||||||
|  |         KMemoryLayout memory_layout; | ||||||
|  |         DeriveInitialMemoryLayout(memory_layout); | ||||||
|  |         InitializeMemoryLayout(memory_layout); | ||||||
|  |         InitializeSystemResourceLimit(kernel, system, memory_layout); | ||||||
|  |         InitializeSlabHeaps(); | ||||||
|         InitializeSchedulers(); |         InitializeSchedulers(); | ||||||
|         InitializeSuspendThreads(); |         InitializeSuspendThreads(); | ||||||
|         InitializePreemption(kernel); |         InitializePreemption(kernel); | ||||||
| @@ -137,27 +142,32 @@ struct KernelCore::Impl { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Creates the default system resource limit |     // Creates the default system resource limit | ||||||
|     void InitializeSystemResourceLimit(KernelCore& kernel, Core::System& system) { |     void InitializeSystemResourceLimit(KernelCore& kernel, Core::System& system, | ||||||
|  |                                        const KMemoryLayout& memory_layout) { | ||||||
|         system_resource_limit = std::make_shared<KResourceLimit>(kernel, system); |         system_resource_limit = std::make_shared<KResourceLimit>(kernel, system); | ||||||
|  |         const auto [total_size, kernel_size] = memory_layout.GetTotalAndKernelMemorySizes(); | ||||||
|  |  | ||||||
|         // If setting the default system values fails, then something seriously wrong has occurred. |         // If setting the default system values fails, then something seriously wrong has occurred. | ||||||
|         ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, 0x100000000) |         ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, total_size) | ||||||
|                    .IsSuccess()); |                    .IsSuccess()); | ||||||
|         ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess()); |         ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess()); | ||||||
|         ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 900).IsSuccess()); |         ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 900).IsSuccess()); | ||||||
|         ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200) |         ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200) | ||||||
|                    .IsSuccess()); |                    .IsSuccess()); | ||||||
|         ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Sessions, 1133).IsSuccess()); |         ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Sessions, 1133).IsSuccess()); | ||||||
|  |         system_resource_limit->Reserve(LimitableResource::PhysicalMemory, kernel_size); | ||||||
|  |  | ||||||
|         // Derived from recent software updates. The kernel reserves 27MB |  | ||||||
|         constexpr u64 kernel_size{0x1b00000}; |  | ||||||
|         if (!system_resource_limit->Reserve(LimitableResource::PhysicalMemory, kernel_size)) { |  | ||||||
|             UNREACHABLE(); |  | ||||||
|         } |  | ||||||
|         // Reserve secure applet memory, introduced in firmware 5.0.0 |         // Reserve secure applet memory, introduced in firmware 5.0.0 | ||||||
|         constexpr u64 secure_applet_memory_size{0x400000}; |         constexpr u64 secure_applet_memory_size{Common::Size_4_MB}; | ||||||
|         ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory, |         ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory, | ||||||
|                                               secure_applet_memory_size)); |                                               secure_applet_memory_size)); | ||||||
|  |  | ||||||
|  |         // This memory seems to be reserved on hardware, but is not reserved/used by yuzu. | ||||||
|  |         // Likely Horizon OS reserved memory | ||||||
|  |         // TODO(ameerj): Derive the memory rather than hardcode it. | ||||||
|  |         constexpr u64 unknown_reserved_memory{0x2f896000}; | ||||||
|  |         ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory, | ||||||
|  |                                               unknown_reserved_memory)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void InitializePreemption(KernelCore& kernel) { |     void InitializePreemption(KernelCore& kernel) { | ||||||
| @@ -531,11 +541,7 @@ struct KernelCore::Impl { | |||||||
|                                                         linear_region_start); |                                                         linear_region_start); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void InitializeMemoryLayout() { |     void InitializeMemoryLayout(const KMemoryLayout& memory_layout) { | ||||||
|         // Derive the initial memory layout from the emulated board |  | ||||||
|         KMemoryLayout memory_layout; |  | ||||||
|         DeriveInitialMemoryLayout(memory_layout); |  | ||||||
|  |  | ||||||
|         const auto system_pool = memory_layout.GetKernelSystemPoolRegionPhysicalExtents(); |         const auto system_pool = memory_layout.GetKernelSystemPoolRegionPhysicalExtents(); | ||||||
|         const auto applet_pool = memory_layout.GetKernelAppletPoolRegionPhysicalExtents(); |         const auto applet_pool = memory_layout.GetKernelAppletPoolRegionPhysicalExtents(); | ||||||
|         const auto application_pool = memory_layout.GetKernelApplicationPoolRegionPhysicalExtents(); |         const auto application_pool = memory_layout.GetKernelApplicationPoolRegionPhysicalExtents(); | ||||||
| @@ -578,11 +584,14 @@ struct KernelCore::Impl { | |||||||
|             system.Kernel(), system.DeviceMemory(), nullptr, {time_phys_addr, time_size / PageSize}, |             system.Kernel(), system.DeviceMemory(), nullptr, {time_phys_addr, time_size / PageSize}, | ||||||
|             KMemoryPermission::None, KMemoryPermission::Read, time_phys_addr, time_size, |             KMemoryPermission::None, KMemoryPermission::Read, time_phys_addr, time_size, | ||||||
|             "Time:SharedMemory"); |             "Time:SharedMemory"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void InitializeSlabHeaps() { | ||||||
|         // Allocate slab heaps |         // Allocate slab heaps | ||||||
|         user_slab_heap_pages = std::make_unique<KSlabHeap<Page>>(); |         user_slab_heap_pages = std::make_unique<KSlabHeap<Page>>(); | ||||||
|  |  | ||||||
|         constexpr u64 user_slab_heap_size{0x1ef000}; |         // TODO(ameerj): This should be derived, not hardcoded within the kernel | ||||||
|  |         constexpr u64 user_slab_heap_size{0x3de000}; | ||||||
|         // Reserve slab heaps |         // Reserve slab heaps | ||||||
|         ASSERT( |         ASSERT( | ||||||
|             system_resource_limit->Reserve(LimitableResource::PhysicalMemory, user_slab_heap_size)); |             system_resource_limit->Reserve(LimitableResource::PhysicalMemory, user_slab_heap_size)); | ||||||
|   | |||||||
| @@ -120,9 +120,7 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name, | |||||||
|     std::shared_ptr<Process> process = std::make_shared<Process>(system); |     std::shared_ptr<Process> process = std::make_shared<Process>(system); | ||||||
|     process->name = std::move(name); |     process->name = std::move(name); | ||||||
|  |  | ||||||
|     // TODO: This is inaccurate |     process->resource_limit = kernel.GetSystemResourceLimit(); | ||||||
|     // The process should hold a reference to the kernel-wide resource limit. |  | ||||||
|     process->resource_limit = std::make_shared<KResourceLimit>(kernel, system); |  | ||||||
|     process->status = ProcessStatus::Created; |     process->status = ProcessStatus::Created; | ||||||
|     process->program_id = 0; |     process->program_id = 0; | ||||||
|     process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID() |     process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID() | ||||||
| @@ -160,17 +158,13 @@ void Process::DecrementThreadCount() { | |||||||
| } | } | ||||||
|  |  | ||||||
| u64 Process::GetTotalPhysicalMemoryAvailable() const { | u64 Process::GetTotalPhysicalMemoryAvailable() const { | ||||||
|     // TODO: This is expected to always return the application memory pool size after accurately |  | ||||||
|     // reserving kernel resources. The current workaround uses a process-local resource limit of |  | ||||||
|     // application memory pool size, which is inaccurate. |  | ||||||
|     const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) + |     const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) + | ||||||
|                        page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + |                        page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + | ||||||
|                        main_thread_stack_size}; |                        main_thread_stack_size}; | ||||||
|  |     ASSERT(capacity == kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application)); | ||||||
|     if (capacity < memory_usage_capacity) { |     if (capacity < memory_usage_capacity) { | ||||||
|         return capacity; |         return capacity; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return memory_usage_capacity; |     return memory_usage_capacity; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -272,10 +266,6 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, | |||||||
|     system_resource_size = metadata.GetSystemResourceSize(); |     system_resource_size = metadata.GetSystemResourceSize(); | ||||||
|     image_size = code_size; |     image_size = code_size; | ||||||
|  |  | ||||||
|     // Set initial resource limits |  | ||||||
|     resource_limit->SetLimitValue( |  | ||||||
|         LimitableResource::PhysicalMemory, |  | ||||||
|         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()) { | ||||||
| @@ -324,16 +314,6 @@ 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::Events, 700); |  | ||||||
|     resource_limit->SetLimitValue(LimitableResource::TransferMemory, 128); |  | ||||||
|     resource_limit->SetLimitValue(LimitableResource::Sessions, 894); |  | ||||||
|  |  | ||||||
|     // Create TLS region |     // Create TLS region | ||||||
|     tls_region_address = CreateTLSRegion(); |     tls_region_address = CreateTLSRegion(); | ||||||
|     memory_reservation.Commit(); |     memory_reservation.Commit(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user