From 75207ddffdd7a255116fdc06062d8c23460ffe12 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 27 Mar 2019 04:01:15 +0100 Subject: [PATCH] Kernel: Load ELF executable pages lazily when possible. This currently only works for "normal" processes created by fork(). It does not work for create_user_process() processes spawned by the kernel, as those are a bit special during construction. --- Kernel/Process.cpp | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index c7b009aeb7..493cc74db1 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -322,13 +322,15 @@ int Process::do_exec(String path, Vector arguments, Vector envir #endif RetainPtr region = allocate_region_with_vmo(LinearAddress(), descriptor->metadata().size, vmo.copy_ref(), 0, "executable", true, false); - // FIXME: Should we consider doing on-demand paging here? Is it actually useful? - bool success = region->page_in(); - - ASSERT(success); + if (this != ¤t->process()) { + // FIXME: Don't force-load the entire executable at once, let the on-demand pager take care of it. + bool success = region->page_in(); + ASSERT(success); + } { // Okay, here comes the sleight of hand, pay close attention.. auto old_regions = move(m_regions); + m_regions.append(*region); ELFLoader loader(region->laddr().as_ptr()); loader.map_section_hook = [&] (LinearAddress laddr, size_t size, size_t alignment, size_t offset_in_image, bool is_readable, bool is_writable, const String& name) { ASSERT(size); @@ -347,25 +349,17 @@ int Process::do_exec(String path, Vector arguments, Vector envir return laddr.as_ptr(); }; bool success = loader.load(); - if (!success) { + if (!success || !loader.entry().get()) { m_page_directory = move(old_page_directory); // FIXME: RAII this somehow instead. ASSERT(¤t->process() == this); MM.enter_process_paging_scope(*this); m_regions = move(old_regions); - kprintf("sys$execve: Failure loading %s\n", path.characters()); + kprintf("do_exec: Failure loading %s\n", path.characters()); return -ENOEXEC; } entry_eip = loader.entry().get(); - if (!entry_eip) { - m_page_directory = move(old_page_directory); - // FIXME: RAII this somehow instead. - ASSERT(¤t->process() == this); - MM.enter_process_paging_scope(*this); - m_regions = move(old_regions); - return -ENOEXEC; - } } kfree(current->m_kernel_stack_for_signal_handler);