mirror of
https://github.com/RGBCube/serenity
synced 2025-05-28 09:45:09 +00:00
Kernel: Make allocate_supervisor_physical_page OOM-fallible
This commit is contained in:
parent
4d2f1a05ec
commit
bd5b56cab0
4 changed files with 11 additions and 21 deletions
|
@ -741,12 +741,9 @@ 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)
|
ErrorOr<NonnullOwnPtr<Memory::Region>> MemoryManager::allocate_dma_buffer_page(StringView name, Memory::Region::Access access, RefPtr<Memory::PhysicalPage>& dma_buffer_page)
|
||||||
{
|
{
|
||||||
dma_buffer_page = allocate_supervisor_physical_page();
|
dma_buffer_page = TRY(allocate_supervisor_physical_page());
|
||||||
if (dma_buffer_page.is_null())
|
|
||||||
return ENOMEM;
|
|
||||||
// Do not enable Cache for this region as physical memory transfers are performed (Most architectures have this behaviour by default)
|
// Do not enable Cache for this region as physical memory transfers are performed (Most architectures have this behaviour by default)
|
||||||
auto region_or_error = allocate_kernel_region(dma_buffer_page->paddr(), PAGE_SIZE, name, access, Region::Cacheable::No);
|
return allocate_kernel_region(dma_buffer_page->paddr(), PAGE_SIZE, name, access, Region::Cacheable::No);
|
||||||
return region_or_error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<NonnullOwnPtr<Memory::Region>> MemoryManager::allocate_dma_buffer_page(StringView name, Memory::Region::Access access)
|
ErrorOr<NonnullOwnPtr<Memory::Region>> MemoryManager::allocate_dma_buffer_page(StringView name, Memory::Region::Access access)
|
||||||
|
@ -956,22 +953,21 @@ ErrorOr<NonnullRefPtrVector<PhysicalPage>> MemoryManager::allocate_contiguous_su
|
||||||
return physical_pages;
|
return physical_pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<PhysicalPage> MemoryManager::allocate_supervisor_physical_page()
|
ErrorOr<NonnullRefPtr<PhysicalPage>> MemoryManager::allocate_supervisor_physical_page()
|
||||||
{
|
{
|
||||||
SpinlockLocker lock(s_mm_lock);
|
SpinlockLocker lock(s_mm_lock);
|
||||||
auto page = m_super_physical_region->take_free_page();
|
auto page = m_super_physical_region->take_free_page();
|
||||||
|
|
||||||
if (!page) {
|
if (!page) {
|
||||||
dmesgln("MM: no super physical pages available");
|
dmesgln("MM: no super physical pages available");
|
||||||
VERIFY_NOT_REACHED();
|
return ENOMEM;
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* ptr = quickmap_page(*page);
|
auto* ptr = quickmap_page(*page);
|
||||||
memset(ptr, 0, PAGE_SIZE);
|
memset(ptr, 0, PAGE_SIZE);
|
||||||
unquickmap_page();
|
unquickmap_page();
|
||||||
++m_system_memory_info.super_physical_pages_used;
|
++m_system_memory_info.super_physical_pages_used;
|
||||||
return page;
|
return page.release_nonnull();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryManager::enter_process_address_space(Process& process)
|
void MemoryManager::enter_process_address_space(Process& process)
|
||||||
|
|
|
@ -172,7 +172,7 @@ public:
|
||||||
|
|
||||||
NonnullRefPtr<PhysicalPage> allocate_committed_user_physical_page(Badge<CommittedPhysicalPageSet>, ShouldZeroFill = ShouldZeroFill::Yes);
|
NonnullRefPtr<PhysicalPage> allocate_committed_user_physical_page(Badge<CommittedPhysicalPageSet>, ShouldZeroFill = ShouldZeroFill::Yes);
|
||||||
RefPtr<PhysicalPage> allocate_user_physical_page(ShouldZeroFill = ShouldZeroFill::Yes, bool* did_purge = nullptr);
|
RefPtr<PhysicalPage> allocate_user_physical_page(ShouldZeroFill = ShouldZeroFill::Yes, bool* did_purge = nullptr);
|
||||||
RefPtr<PhysicalPage> allocate_supervisor_physical_page();
|
ErrorOr<NonnullRefPtr<PhysicalPage>> allocate_supervisor_physical_page();
|
||||||
ErrorOr<NonnullRefPtrVector<PhysicalPage>> allocate_contiguous_supervisor_physical_pages(size_t size);
|
ErrorOr<NonnullRefPtrVector<PhysicalPage>> allocate_contiguous_supervisor_physical_pages(size_t size);
|
||||||
void deallocate_physical_page(PhysicalAddress);
|
void deallocate_physical_page(PhysicalAddress);
|
||||||
|
|
||||||
|
|
|
@ -37,25 +37,19 @@ AHCIPort::AHCIPort(const AHCIPortHandler& handler, volatile AHCI::PortRegisters&
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_fis_receive_page = MM.allocate_supervisor_physical_page();
|
m_fis_receive_page = MM.allocate_supervisor_physical_page().release_value_but_fixme_should_propagate_errors();
|
||||||
if (m_fis_receive_page.is_null())
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (size_t index = 0; index < 1; index++) {
|
for (size_t index = 0; index < 1; index++) {
|
||||||
m_dma_buffers.append(MM.allocate_supervisor_physical_page().release_nonnull());
|
m_dma_buffers.append(MM.allocate_supervisor_physical_page().release_value_but_fixme_should_propagate_errors());
|
||||||
}
|
}
|
||||||
for (size_t index = 0; index < 1; index++) {
|
for (size_t index = 0; index < 1; index++) {
|
||||||
m_command_table_pages.append(MM.allocate_supervisor_physical_page().release_nonnull());
|
m_command_table_pages.append(MM.allocate_supervisor_physical_page().release_value_but_fixme_should_propagate_errors());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto region_or_error = MM.allocate_dma_buffer_page("AHCI Port Command List", Memory::Region::Access::ReadWrite, m_command_list_page);
|
m_command_list_region = MM.allocate_dma_buffer_page("AHCI Port Command List", Memory::Region::Access::ReadWrite, m_command_list_page).release_value_but_fixme_should_propagate_errors();
|
||||||
|
|
||||||
dbgln_if(AHCI_DEBUG, "AHCI Port {}: Command list page at {}", representative_port_index(), m_command_list_page->paddr());
|
dbgln_if(AHCI_DEBUG, "AHCI Port {}: Command list page at {}", representative_port_index(), m_command_list_page->paddr());
|
||||||
dbgln_if(AHCI_DEBUG, "AHCI Port {}: FIS receive page at {}", representative_port_index(), m_fis_receive_page->paddr());
|
dbgln_if(AHCI_DEBUG, "AHCI Port {}: FIS receive page at {}", representative_port_index(), m_fis_receive_page->paddr());
|
||||||
|
|
||||||
if (region_or_error.is_error())
|
|
||||||
TODO();
|
|
||||||
m_command_list_region = region_or_error.release_value();
|
|
||||||
dbgln_if(AHCI_DEBUG, "AHCI Port {}: Command list region at {}", representative_port_index(), m_command_list_region->vaddr());
|
dbgln_if(AHCI_DEBUG, "AHCI Port {}: Command list region at {}", representative_port_index(), m_command_list_region->vaddr());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ AHCIPortHandler::AHCIPortHandler(AHCIController& controller, u8 irq, AHCI::Maske
|
||||||
{
|
{
|
||||||
// FIXME: Use the number of taken ports to determine how many pages we should allocate.
|
// FIXME: Use the number of taken ports to determine how many pages we should allocate.
|
||||||
for (size_t index = 0; index < (((size_t)AHCI::Limits::MaxPorts * 512) / PAGE_SIZE); index++) {
|
for (size_t index = 0; index < (((size_t)AHCI::Limits::MaxPorts * 512) / PAGE_SIZE); index++) {
|
||||||
m_identify_metadata_pages.append(MM.allocate_supervisor_physical_page().release_nonnull());
|
m_identify_metadata_pages.append(MM.allocate_supervisor_physical_page().release_value_but_fixme_should_propagate_errors());
|
||||||
}
|
}
|
||||||
|
|
||||||
dbgln_if(AHCI_DEBUG, "AHCI Port Handler: IRQ {}", irq);
|
dbgln_if(AHCI_DEBUG, "AHCI Port Handler: IRQ {}", irq);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue