Kernel+Userland: Remove supervisor pages concept

There's no real value in separating physical pages to supervisor and
user types, so let's remove the concept and just let everyone to use
"user" physical pages which can be allocated from any PhysicalRegion
we want to use. Later on, we will remove the "user" prefix as this
prefix is not needed anymore.
This commit is contained in:
Liav A 2022-07-14 15:14:08 +03:00 committed by Andreas Kling
parent ed9b2a85ed
commit 1c499e75bd
Notes: sideshowbarker 2024-07-17 08:56:59 +09:00
8 changed files with 8 additions and 96 deletions

View File

@ -7,7 +7,6 @@ PHDRS
data PT_LOAD ;
ksyms PT_LOAD ;
bss PT_LOAD ;
super_pages PT_LOAD ;
}
SECTIONS
@ -55,11 +54,6 @@ SECTIONS
*(.heap)
} :bss
.super_pages ALIGN(4K) (NOLOAD) : AT (ADDR(.super_pages))
{
*(.super_pages)
} :super_pages
/*
FIXME: 8MB is enough space for all of the tables required to identity map
physical memory. 8M is wasteful, so this should be properly calculated.

View File

@ -9,7 +9,6 @@ ENTRY(init)
PHDRS
{
elf_headers PT_LOAD FILEHDR PHDRS FLAGS(PF_R) ;
super_pages PT_LOAD FLAGS(PF_R | PF_W) ;
text PT_LOAD FLAGS(PF_R | PF_X) ;
data PT_LOAD FLAGS(PF_R | PF_W) ;
bss PT_LOAD FLAGS(PF_R | PF_W) ;
@ -27,11 +26,6 @@ SECTIONS
start_of_elf_headers = .;
} :elf_headers
.super_pages ALIGN(4K) (NOLOAD) : AT (ADDR(.super_pages))
{
*(.super_pages)
} :super_pages
.text ALIGN(4K) : AT (ADDR(.text))
{
start_of_kernel_text = .;

View File

@ -450,8 +450,6 @@ private:
TRY(json.add("user_physical_available"sv, system_memory.user_physical_pages - system_memory.user_physical_pages_used));
TRY(json.add("user_physical_committed"sv, system_memory.user_physical_pages_committed));
TRY(json.add("user_physical_uncommitted"sv, system_memory.user_physical_pages_uncommitted));
TRY(json.add("super_physical_allocated"sv, system_memory.super_physical_pages_used));
TRY(json.add("super_physical_available"sv, system_memory.super_physical_pages - system_memory.super_physical_pages_used));
TRY(json.add("kmalloc_call_count"sv, stats.kmalloc_call_count));
TRY(json.add("kfree_call_count"sv, stats.kfree_call_count));
TRY(json.finish());

View File

@ -43,11 +43,6 @@ extern u8 end_of_kernel_ksyms[];
extern multiboot_module_entry_t multiboot_copy_boot_modules_array[16];
extern size_t multiboot_copy_boot_modules_count;
// Treat the super pages as logically separate from .bss
// FIXME: Find a solution so we don't need to expand this range each time
// we are in a situation too many drivers try to allocate super pages.
__attribute__((section(".super_pages"))) static u8 super_pages[4 * MiB];
namespace Kernel::Memory {
ErrorOr<FlatPtr> page_round_up(FlatPtr x)
@ -347,17 +342,6 @@ UNMAP_AFTER_INIT void MemoryManager::parse_memory_map()
m_user_physical_regions.append(PhysicalRegion::try_create(range.lower, range.upper).release_nonnull());
}
// Super pages are guaranteed to be in the first 16MB of physical memory
VERIFY(virtual_to_low_physical((FlatPtr)super_pages) + sizeof(super_pages) < 0x1000000);
// Append statically-allocated super physical physical_region.
m_super_physical_region = PhysicalRegion::try_create(
PhysicalAddress(virtual_to_low_physical(FlatPtr(super_pages))),
PhysicalAddress(virtual_to_low_physical(FlatPtr(super_pages + sizeof(super_pages)))));
VERIFY(m_super_physical_region);
m_system_memory_info.super_physical_pages += m_super_physical_region->size();
for (auto& region : m_user_physical_regions)
m_system_memory_info.user_physical_pages += region.size();
@ -368,7 +352,6 @@ UNMAP_AFTER_INIT void MemoryManager::parse_memory_map()
initialize_physical_pages();
VERIFY(m_system_memory_info.super_physical_pages > 0);
VERIFY(m_system_memory_info.user_physical_pages > 0);
// We start out with no committed pages
@ -378,9 +361,6 @@ UNMAP_AFTER_INIT void MemoryManager::parse_memory_map()
dmesgln("MM: {} range @ {} - {} (size {:#x})", UserMemoryRangeTypeNames[to_underlying(used_range.type)], used_range.start, used_range.end.offset(-1), used_range.end.as_ptr() - used_range.start.as_ptr());
}
dmesgln("MM: Super physical region: {} - {} (size {:#x})", m_super_physical_region->lower(), m_super_physical_region->upper().offset(-1), PAGE_SIZE * m_super_physical_region->size());
m_super_physical_region->initialize_zones();
for (auto& region : m_user_physical_regions) {
dmesgln("MM: User physical region: {} - {} (size {:#x})", region.lower(), region.upper().offset(-1), PAGE_SIZE * region.size());
region.initialize_zones();
@ -776,7 +756,7 @@ ErrorOr<NonnullOwnPtr<Region>> MemoryManager::allocate_contiguous_kernel_region(
ErrorOr<NonnullOwnPtr<Memory::Region>> MemoryManager::allocate_dma_buffer_page(StringView name, Memory::Region::Access access, RefPtr<Memory::PhysicalPage>& dma_buffer_page)
{
dma_buffer_page = TRY(allocate_supervisor_physical_page());
dma_buffer_page = TRY(allocate_user_physical_page());
// Do not enable Cache for this region as physical memory transfers are performed (Most architectures have this behaviour by default)
return allocate_kernel_region(dma_buffer_page->paddr(), PAGE_SIZE, name, access, Region::Cacheable::No);
}
@ -885,13 +865,7 @@ void MemoryManager::deallocate_physical_page(PhysicalAddress paddr)
++m_system_memory_info.user_physical_pages_uncommitted;
return;
}
// If it's not a user page, it should be a supervisor page.
if (!m_super_physical_region->contains(paddr))
PANIC("MM: deallocate_user_physical_page couldn't figure out region for page @ {}", paddr);
m_super_physical_region->return_page(paddr);
--m_system_memory_info.super_physical_pages_used;
}
RefPtr<PhysicalPage> MemoryManager::find_free_user_physical_page(bool committed)
@ -999,43 +973,6 @@ ErrorOr<NonnullRefPtrVector<PhysicalPage>> MemoryManager::allocate_contiguous_us
return ENOMEM;
}
ErrorOr<NonnullRefPtrVector<PhysicalPage>> MemoryManager::allocate_contiguous_supervisor_physical_pages(size_t size)
{
VERIFY(!(size % PAGE_SIZE));
SpinlockLocker lock(s_mm_lock);
size_t count = ceil_div(size, static_cast<size_t>(PAGE_SIZE));
auto physical_pages = m_super_physical_region->take_contiguous_free_pages(count);
if (physical_pages.is_empty()) {
dmesgln("MM: no super physical pages available");
return ENOMEM;
}
{
auto cleanup_region = TRY(MM.allocate_kernel_region(physical_pages[0].paddr(), PAGE_SIZE * count, "MemoryManager Allocation Sanitization"sv, Region::Access::Read | Region::Access::Write));
memset(cleanup_region->vaddr().as_ptr(), 0, PAGE_SIZE * count);
}
m_system_memory_info.super_physical_pages_used += count;
return physical_pages;
}
ErrorOr<NonnullRefPtr<PhysicalPage>> MemoryManager::allocate_supervisor_physical_page()
{
SpinlockLocker lock(s_mm_lock);
auto page = m_super_physical_region->take_free_page();
if (!page) {
dmesgln("MM: no super physical pages available");
return ENOMEM;
}
auto* ptr = quickmap_page(*page);
memset(ptr, 0, PAGE_SIZE);
unquickmap_page();
++m_system_memory_info.super_physical_pages_used;
return page.release_nonnull();
}
void MemoryManager::enter_process_address_space(Process& process)
{
enter_address_space(process.address_space());

View File

@ -175,8 +175,6 @@ public:
NonnullRefPtr<PhysicalPage> allocate_committed_user_physical_page(Badge<CommittedPhysicalPageSet>, ShouldZeroFill = ShouldZeroFill::Yes);
ErrorOr<NonnullRefPtr<PhysicalPage>> allocate_user_physical_page(ShouldZeroFill = ShouldZeroFill::Yes, bool* did_purge = nullptr);
ErrorOr<NonnullRefPtr<PhysicalPage>> allocate_supervisor_physical_page();
ErrorOr<NonnullRefPtrVector<PhysicalPage>> allocate_contiguous_supervisor_physical_pages(size_t size);
ErrorOr<NonnullRefPtrVector<PhysicalPage>> allocate_contiguous_user_physical_pages(size_t size);
void deallocate_physical_page(PhysicalAddress);
@ -196,8 +194,6 @@ public:
PhysicalSize user_physical_pages_used { 0 };
PhysicalSize user_physical_pages_committed { 0 };
PhysicalSize user_physical_pages_uncommitted { 0 };
PhysicalSize super_physical_pages { 0 };
PhysicalSize super_physical_pages_used { 0 };
};
SystemMemoryInfo get_system_memory_info()
@ -301,7 +297,6 @@ private:
SystemMemoryInfo m_system_memory_info;
NonnullOwnPtrVector<PhysicalRegion> m_user_physical_regions;
OwnPtr<PhysicalRegion> m_super_physical_region;
OwnPtr<PhysicalRegion> m_physical_pages_region;
PhysicalPageEntry* m_physical_page_entries { nullptr };
size_t m_physical_page_entries_count { 0 };

View File

@ -22,7 +22,7 @@ namespace Kernel {
UNMAP_AFTER_INIT ErrorOr<NonnullRefPtr<AHCIPort>> AHCIPort::create(AHCIController const& controller, AHCI::HBADefinedCapabilities hba_capabilities, volatile AHCI::PortRegisters& registers, u32 port_index)
{
auto identify_buffer_page = MUST(MM.allocate_supervisor_physical_page());
auto identify_buffer_page = MUST(MM.allocate_user_physical_page());
auto port = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) AHCIPort(controller, move(identify_buffer_page), hba_capabilities, registers, port_index)));
TRY(port->allocate_resources_and_initialize_ports());
return port;
@ -35,14 +35,14 @@ ErrorOr<void> AHCIPort::allocate_resources_and_initialize_ports()
return {};
}
m_fis_receive_page = TRY(MM.allocate_supervisor_physical_page());
m_fis_receive_page = TRY(MM.allocate_user_physical_page());
for (size_t index = 0; index < 1; index++) {
auto dma_page = TRY(MM.allocate_supervisor_physical_page());
auto dma_page = TRY(MM.allocate_user_physical_page());
m_dma_buffers.append(move(dma_page));
}
for (size_t index = 0; index < 1; index++) {
auto command_table_page = TRY(MM.allocate_supervisor_physical_page());
auto command_table_page = TRY(MM.allocate_user_physical_page());
m_command_table_pages.append(move(command_table_page));
}

View File

@ -62,7 +62,6 @@ MemoryStatsWidget::MemoryStatsWidget(GraphWidget* graph)
m_user_physical_pages_label = build_widgets_for_label("Physical memory:");
m_user_physical_pages_committed_label = build_widgets_for_label("Committed memory:");
m_supervisor_physical_pages_label = build_widgets_for_label("Supervisor physical:");
m_kmalloc_space_label = build_widgets_for_label("Kernel heap:");
m_kmalloc_count_label = build_widgets_for_label("Calls kmalloc:");
m_kfree_count_label = build_widgets_for_label("Calls kfree:");
@ -120,23 +119,19 @@ void MemoryStatsWidget::refresh()
u64 user_physical_available = json.get("user_physical_available"sv).to_u64();
u64 user_physical_committed = json.get("user_physical_committed"sv).to_u64();
u64 user_physical_uncommitted = json.get("user_physical_uncommitted"sv).to_u64();
u64 super_physical_alloc = json.get("super_physical_allocated"sv).to_u64();
u64 super_physical_free = json.get("super_physical_available"sv).to_u64();
u32 kmalloc_call_count = json.get("kmalloc_call_count"sv).to_u32();
u32 kfree_call_count = json.get("kfree_call_count"sv).to_u32();
u64 kmalloc_bytes_total = kmalloc_allocated + kmalloc_available;
u64 user_physical_pages_total = user_physical_allocated + user_physical_available;
u64 supervisor_pages_total = super_physical_alloc + super_physical_free;
u64 physical_pages_total = user_physical_pages_total + supervisor_pages_total;
u64 physical_pages_in_use = user_physical_allocated + super_physical_alloc;
u64 physical_pages_total = user_physical_pages_total;
u64 physical_pages_in_use = user_physical_allocated;
u64 total_userphysical_and_swappable_pages = user_physical_allocated + user_physical_committed + user_physical_uncommitted;
m_kmalloc_space_label->set_text(String::formatted("{}/{}", human_readable_size(kmalloc_allocated), human_readable_size(kmalloc_bytes_total)));
m_user_physical_pages_label->set_text(String::formatted("{}/{}", human_readable_size(page_count_to_bytes(physical_pages_in_use)), human_readable_size(page_count_to_bytes(physical_pages_total))));
m_user_physical_pages_committed_label->set_text(String::formatted("{}", human_readable_size(page_count_to_bytes(user_physical_committed))));
m_supervisor_physical_pages_label->set_text(String::formatted("{}/{}", human_readable_size(page_count_to_bytes(super_physical_alloc)), human_readable_size(page_count_to_bytes(supervisor_pages_total))));
m_kmalloc_count_label->set_text(String::formatted("{}", kmalloc_call_count));
m_kfree_count_label->set_text(String::formatted("{}", kfree_call_count));
m_kmalloc_difference_label->set_text(String::formatted("{:+}", kmalloc_call_count - kfree_call_count));

View File

@ -36,7 +36,6 @@ private:
String m_graph_widget_name {};
RefPtr<GUI::Label> m_user_physical_pages_label;
RefPtr<GUI::Label> m_user_physical_pages_committed_label;
RefPtr<GUI::Label> m_supervisor_physical_pages_label;
RefPtr<GUI::Label> m_kmalloc_space_label;
RefPtr<GUI::Label> m_kmalloc_count_label;
RefPtr<GUI::Label> m_kfree_count_label;