1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 22:07:36 +00:00

Kernel: Fix a few deadlocks with Thread::m_lock and g_scheduler_lock

g_scheduler_lock cannot safely be acquired after Thread::m_lock
because another processor may already hold g_scheduler_lock and wait
for the same Thread::m_lock.
This commit is contained in:
Tom 2020-10-25 20:22:59 -06:00 committed by Andreas Kling
parent 8c764319ad
commit 1e2e3eed62
6 changed files with 55 additions and 37 deletions

View file

@ -308,7 +308,10 @@ int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Ve
if (was_profiling)
Profiling::did_exec(path);
new_main_thread->set_state(Thread::State::Runnable);
{
ScopedSpinLock lock(g_scheduler_lock);
new_main_thread->set_state(Thread::State::Runnable);
}
big_lock().force_unlock_if_locked();
ASSERT_INTERRUPTS_DISABLED();
ASSERT(Processor::current().in_critical());

View file

@ -79,24 +79,25 @@ pid_t Process::sys$fork(RegisterState& regs)
dbg() << "fork: child will begin executing at " << String::format("%w", child_tss.cs) << ":" << String::format("%x", child_tss.eip) << " with stack " << String::format("%w", child_tss.ss) << ":" << String::format("%x", child_tss.esp) << ", kstack " << String::format("%w", child_tss.ss0) << ":" << String::format("%x", child_tss.esp0);
#endif
ScopedSpinLock lock(m_lock);
for (auto& region : m_regions) {
#ifdef FORK_DEBUG
dbg() << "fork: cloning Region{" << &region << "} '" << region.name() << "' @ " << region.vaddr();
#endif
auto& child_region = child->add_region(region.clone());
child_region.map(child->page_directory());
if (&region == m_master_tls_region)
child->m_master_tls_region = child_region.make_weak_ptr();
}
{
ScopedSpinLock lock(g_processes_lock);
ScopedSpinLock lock(m_lock);
for (auto& region : m_regions) {
#ifdef FORK_DEBUG
dbg() << "fork: cloning Region{" << &region << "} '" << region.name() << "' @ " << region.vaddr();
#endif
auto& child_region = child->add_region(region.clone());
child_region.map(child->page_directory());
if (&region == m_master_tls_region)
child->m_master_tls_region = child_region.make_weak_ptr();
}
ScopedSpinLock processes_lock(g_processes_lock);
g_processes->prepend(child);
child->ref(); // This reference will be dropped by Process::reap
}
ScopedSpinLock lock(g_scheduler_lock);
child_first_thread->set_affinity(Thread::current()->affinity());
child_first_thread->set_state(Thread::State::Runnable);
return child->pid().value();

View file

@ -70,7 +70,6 @@ int Process::sys$create_thread(void* (*entry)(void*), Userspace<const Syscall::S
builder.appendf("[%d]", thread->tid().value());
thread->set_name(builder.to_string());
thread->set_priority(requested_thread_priority);
if (!is_thread_joinable)
thread->detach();
@ -83,6 +82,9 @@ int Process::sys$create_thread(void* (*entry)(void*), Userspace<const Syscall::S
auto tsr_result = thread->make_thread_specific_region({});
if (tsr_result.is_error())
return tsr_result.error();
ScopedSpinLock lock(g_scheduler_lock);
thread->set_priority(requested_thread_priority);
thread->set_state(Thread::State::Runnable);
return thread->tid().value();
}