From 643f4cf86499e904c85d21cf6f3a4676bd1cddd3 Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Mon, 28 Nov 2022 23:27:58 +0530 Subject: [PATCH] Ensure thread doesn't migrate during `InsertThread` As we didn't hold `coreMigrationMutex`, the thread could simply migrate during `InsertThread` which would lead to the thread potentially never waking up as it's been inserted on a non-resident core. Co-authored-by: PixelyIon --- app/src/main/cpp/skyline/kernel/scheduler.cpp | 3 ++- app/src/main/cpp/skyline/kernel/scheduler.h | 2 +- app/src/main/cpp/skyline/kernel/types/KThread.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/cpp/skyline/kernel/scheduler.cpp b/app/src/main/cpp/skyline/kernel/scheduler.cpp index ed9dc5b1..588599d6 100644 --- a/app/src/main/cpp/skyline/kernel/scheduler.cpp +++ b/app/src/main/cpp/skyline/kernel/scheduler.cpp @@ -86,8 +86,9 @@ namespace skyline::kernel { } void Scheduler::InsertThread(const std::shared_ptr &thread) { + std::scoped_lock migrationLock{thread->coreMigrationMutex}; auto &core{cores.at(thread->coreId)}; - std::unique_lock lock(core.mutex); + std::unique_lock lock{core.mutex}; if (thread->isPaused) { // We cannot insert a thread that is paused, so we need to wait until it has been resumed diff --git a/app/src/main/cpp/skyline/kernel/scheduler.h b/app/src/main/cpp/skyline/kernel/scheduler.h index f45066d5..51e9752b 100644 --- a/app/src/main/cpp/skyline/kernel/scheduler.h +++ b/app/src/main/cpp/skyline/kernel/scheduler.h @@ -58,7 +58,7 @@ namespace skyline { std::list> parkedQueue; //!< A queue of threads which are parked and waiting on core migration /** - * @brief Migrate a thread from its resident core to its ideal core + * @brief Migrate a thread from its resident core to the target core * @note 'KThread::coreMigrationMutex' **must** be locked by the calling thread prior to calling this * @note This is used to handle non-cooperative core affinity mask changes where the resident core is not in its new affinity mask */ diff --git a/app/src/main/cpp/skyline/kernel/types/KThread.h b/app/src/main/cpp/skyline/kernel/types/KThread.h index c6c9908a..a39b6c00 100644 --- a/app/src/main/cpp/skyline/kernel/types/KThread.h +++ b/app/src/main/cpp/skyline/kernel/types/KThread.h @@ -50,7 +50,7 @@ namespace skyline { std::atomic basePriority; //!< The priority of the thread for the scheduler without any priority-inheritance std::atomic priority; //!< The priority of the thread for the scheduler including priority-inheritance - std::mutex coreMigrationMutex; //!< Synchronizes operations which depend on which core the thread is running on + std::recursive_mutex coreMigrationMutex; //!< Synchronizes operations which depend on which core the thread is running on u8 idealCore; //!< The ideal CPU core for this thread to run on u8 coreId; //!< The CPU core on which this thread is running CoreMask affinityMask{}; //!< A mask of CPU cores this thread is allowed to run on