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 <pixelyion@protonmail.com>
This commit is contained in:
Billy Laws 2022-11-28 23:27:58 +05:30 committed by Mark Collins
parent 7f7352ed59
commit 643f4cf864
3 changed files with 4 additions and 3 deletions

View File

@ -86,8 +86,9 @@ namespace skyline::kernel {
} }
void Scheduler::InsertThread(const std::shared_ptr<type::KThread> &thread) { void Scheduler::InsertThread(const std::shared_ptr<type::KThread> &thread) {
std::scoped_lock migrationLock{thread->coreMigrationMutex};
auto &core{cores.at(thread->coreId)}; auto &core{cores.at(thread->coreId)};
std::unique_lock lock(core.mutex); std::unique_lock lock{core.mutex};
if (thread->isPaused) { if (thread->isPaused) {
// We cannot insert a thread that is paused, so we need to wait until it has been resumed // We cannot insert a thread that is paused, so we need to wait until it has been resumed

View File

@ -58,7 +58,7 @@ namespace skyline {
std::list<std::shared_ptr<type::KThread>> parkedQueue; //!< A queue of threads which are parked and waiting on core migration std::list<std::shared_ptr<type::KThread>> 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 '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 * @note This is used to handle non-cooperative core affinity mask changes where the resident core is not in its new affinity mask
*/ */

View File

@ -50,7 +50,7 @@ namespace skyline {
std::atomic<i8> basePriority; //!< The priority of the thread for the scheduler without any priority-inheritance std::atomic<i8> basePriority; //!< The priority of the thread for the scheduler without any priority-inheritance
std::atomic<i8> priority; //!< The priority of the thread for the scheduler including priority-inheritance std::atomic<i8> 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 idealCore; //!< The ideal CPU core for this thread to run on
u8 coreId; //!< The CPU core on which this thread is running 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 CoreMask affinityMask{}; //!< A mask of CPU cores this thread is allowed to run on