mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 14:32:46 +00:00 
			
		
		
		
	Kernel: Handle OOM when adding memory regions to Spaces :^)
This commit is contained in:
		
							parent
							
								
									e94dfb7355
								
							
						
					
					
						commit
						be475cd6a8
					
				
					 3 changed files with 30 additions and 18 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Idan Horowitz
						Idan Horowitz