mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-13 11:42:38 +03:00
Kernel: Handle OOM when adding memory regions to Spaces :^)
This commit is contained in:
parent
e94dfb7355
commit
be475cd6a8
Notes:
sideshowbarker
2024-07-18 09:00:44 +09:00
Author: https://github.com/IdanHo Commit: https://github.com/SerenityOS/serenity/commit/be475cd6a83 Pull-request: https://github.com/SerenityOS/serenity/pull/8758
@ -102,8 +102,13 @@ KResultOr<FlatPtr> Process::sys$fork(RegisterState& regs)
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
auto& child_region = child->space().add_region(region_clone.release_nonnull());
|
||||
child_region.map(child->space().page_directory(), ShouldFlushTLB::No);
|
||||
auto* child_region = child->space().add_region(region_clone.release_nonnull());
|
||||
if (!child_region) {
|
||||
dbgln("fork: Cannot add region, insufficient memory");
|
||||
// TODO: tear down new process?
|
||||
return ENOMEM;
|
||||
}
|
||||
child_region->map(child->space().page_directory(), ShouldFlushTLB::No);
|
||||
|
||||
if (region == m_master_tls_region.unsafe_ptr())
|
||||
child->m_master_tls_region = child_region;
|
||||
|
@ -156,16 +156,18 @@ KResultOr<Region*> Space::try_allocate_split_region(Region const& source_region,
|
||||
m_process, range, source_region.vmobject(), offset_in_vmobject, KString::try_create(source_region.name()), source_region.access(), source_region.is_cacheable() ? Region::Cacheable::Yes : Region::Cacheable::No, source_region.is_shared());
|
||||
if (!new_region)
|
||||
return ENOMEM;
|
||||
auto& region = add_region(new_region.release_nonnull());
|
||||
region.set_syscall_region(source_region.is_syscall_region());
|
||||
region.set_mmap(source_region.is_mmap());
|
||||
region.set_stack(source_region.is_stack());
|
||||
auto* region = add_region(new_region.release_nonnull());
|
||||
if (!region)
|
||||
return ENOMEM;
|
||||
region->set_syscall_region(source_region.is_syscall_region());
|
||||
region->set_mmap(source_region.is_mmap());
|
||||
region->set_stack(source_region.is_stack());
|
||||
size_t page_offset_in_source_region = (offset_in_vmobject - source_region.offset_in_vmobject()) / PAGE_SIZE;
|
||||
for (size_t i = 0; i < region.page_count(); ++i) {
|
||||
for (size_t i = 0; i < region->page_count(); ++i) {
|
||||
if (source_region.should_cow(page_offset_in_source_region + i))
|
||||
region.set_should_cow(i, true);
|
||||
region->set_should_cow(i, true);
|
||||
}
|
||||
return ®ion;
|
||||
return region;
|
||||
}
|
||||
|
||||
KResultOr<Region*> Space::allocate_region(Range const& range, StringView name, int prot, AllocationStrategy strategy)
|
||||
@ -179,7 +181,10 @@ KResultOr<Region*> Space::allocate_region(Range const& range, StringView name, i
|
||||
return ENOMEM;
|
||||
if (!region->map(page_directory()))
|
||||
return ENOMEM;
|
||||
return &add_region(region.release_nonnull());
|
||||
auto* added_region = add_region(region.release_nonnull());
|
||||
if (!added_region)
|
||||
return ENOMEM;
|
||||
return added_region;
|
||||
}
|
||||
|
||||
KResultOr<Region*> Space::allocate_region_with_vmobject(Range const& range, NonnullRefPtr<VMObject> vmobject, size_t offset_in_vmobject, StringView name, int prot, bool shared)
|
||||
@ -202,14 +207,16 @@ KResultOr<Region*> Space::allocate_region_with_vmobject(Range const& range, Nonn
|
||||
auto region = Region::try_create_user_accessible(m_process, range, move(vmobject), offset_in_vmobject, KString::try_create(name), prot_to_region_access_flags(prot), Region::Cacheable::Yes, shared);
|
||||
if (!region) {
|
||||
dbgln("allocate_region_with_vmobject: Unable to allocate Region");
|
||||
return nullptr;
|
||||
return ENOMEM;
|
||||
}
|
||||
auto& region_ref = add_region(region.release_nonnull());
|
||||
if (!region_ref.map(page_directory())) {
|
||||
auto* added_region = add_region(region.release_nonnull());
|
||||
if (!added_region)
|
||||
return ENOMEM;
|
||||
if (!added_region->map(page_directory())) {
|
||||
// FIXME: What is an appropriate error code here, really?
|
||||
return ENOMEM;
|
||||
}
|
||||
return ®ion_ref;
|
||||
return added_region;
|
||||
}
|
||||
|
||||
bool Space::deallocate_region(Region& region)
|
||||
@ -284,12 +291,12 @@ Vector<Region*> Space::find_regions_intersecting(const Range& range)
|
||||
return regions;
|
||||
}
|
||||
|
||||
Region& Space::add_region(NonnullOwnPtr<Region> region)
|
||||
Region* Space::add_region(NonnullOwnPtr<Region> region)
|
||||
{
|
||||
auto* ptr = region.ptr();
|
||||
ScopedSpinLock lock(m_lock);
|
||||
m_regions.insert(region->vaddr().get(), move(region));
|
||||
return *ptr;
|
||||
auto success = m_regions.try_insert(region->vaddr().get(), move(region));
|
||||
return success ? ptr : nullptr;
|
||||
}
|
||||
|
||||
// Carve out a virtual address range from a region and return the two regions on either side
|
||||
|
@ -24,7 +24,7 @@ public:
|
||||
PageDirectory& page_directory() { return *m_page_directory; }
|
||||
const PageDirectory& page_directory() const { return *m_page_directory; }
|
||||
|
||||
Region& add_region(NonnullOwnPtr<Region>);
|
||||
Region* add_region(NonnullOwnPtr<Region>);
|
||||
|
||||
size_t region_count() const { return m_regions.size(); }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user