mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-11-04 12:45:03 +01:00 
			
		
		
		
	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:
		
						commit
						bb922d6ff6
					
				@ -67,8 +67,13 @@ struct KernelCore::Impl {
 | 
			
		||||
        is_phantom_mode_for_singlecore = false;
 | 
			
		||||
 | 
			
		||||
        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();
 | 
			
		||||
        InitializeSuspendThreads();
 | 
			
		||||
        InitializePreemption(kernel);
 | 
			
		||||
@ -137,27 +142,32 @@ struct KernelCore::Impl {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 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);
 | 
			
		||||
        const auto [total_size, kernel_size] = memory_layout.GetTotalAndKernelMemorySizes();
 | 
			
		||||
 | 
			
		||||
        // 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());
 | 
			
		||||
        ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess());
 | 
			
		||||
        ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 900).IsSuccess());
 | 
			
		||||
        ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200)
 | 
			
		||||
                   .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
 | 
			
		||||
        constexpr u64 secure_applet_memory_size{0x400000};
 | 
			
		||||
        constexpr u64 secure_applet_memory_size{Common::Size_4_MB};
 | 
			
		||||
        ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory,
 | 
			
		||||
                                              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) {
 | 
			
		||||
@ -531,11 +541,7 @@ struct KernelCore::Impl {
 | 
			
		||||
                                                        linear_region_start);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void InitializeMemoryLayout() {
 | 
			
		||||
        // Derive the initial memory layout from the emulated board
 | 
			
		||||
        KMemoryLayout memory_layout;
 | 
			
		||||
        DeriveInitialMemoryLayout(memory_layout);
 | 
			
		||||
 | 
			
		||||
    void InitializeMemoryLayout(const KMemoryLayout& memory_layout) {
 | 
			
		||||
        const auto system_pool = memory_layout.GetKernelSystemPoolRegionPhysicalExtents();
 | 
			
		||||
        const auto applet_pool = memory_layout.GetKernelAppletPoolRegionPhysicalExtents();
 | 
			
		||||
        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},
 | 
			
		||||
            KMemoryPermission::None, KMemoryPermission::Read, time_phys_addr, time_size,
 | 
			
		||||
            "Time:SharedMemory");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void InitializeSlabHeaps() {
 | 
			
		||||
        // Allocate slab heaps
 | 
			
		||||
        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
 | 
			
		||||
        ASSERT(
 | 
			
		||||
            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);
 | 
			
		||||
    process->name = std::move(name);
 | 
			
		||||
 | 
			
		||||
    // TODO: This is inaccurate
 | 
			
		||||
    // The process should hold a reference to the kernel-wide resource limit.
 | 
			
		||||
    process->resource_limit = std::make_shared<KResourceLimit>(kernel, system);
 | 
			
		||||
    process->resource_limit = kernel.GetSystemResourceLimit();
 | 
			
		||||
    process->status = ProcessStatus::Created;
 | 
			
		||||
    process->program_id = 0;
 | 
			
		||||
    process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID()
 | 
			
		||||
@ -160,17 +158,13 @@ void Process::DecrementThreadCount() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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) +
 | 
			
		||||
                       page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size +
 | 
			
		||||
                       main_thread_stack_size};
 | 
			
		||||
 | 
			
		||||
    ASSERT(capacity == kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application));
 | 
			
		||||
    if (capacity < memory_usage_capacity) {
 | 
			
		||||
        return capacity;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return memory_usage_capacity;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -272,10 +266,6 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
 | 
			
		||||
    system_resource_size = metadata.GetSystemResourceSize();
 | 
			
		||||
    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,
 | 
			
		||||
                                                  code_size + system_resource_size);
 | 
			
		||||
    if (!memory_reservation.Succeeded()) {
 | 
			
		||||
@ -324,16 +314,6 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
 | 
			
		||||
        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
 | 
			
		||||
    tls_region_address = CreateTLSRegion();
 | 
			
		||||
    memory_reservation.Commit();
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user