SystemProfiler: prevent nested wake-up of profiler thread

* When SystemProfiler::_MaybeNotifyProfilerThreadLocked() is called
  and the conditions are right, it will lock the thread's scheduler
  spinlock and unblock it. Internally, the unblock will enqueue the
  thread into the run queue, which causes a ThreadEnqueuedInRunQueue
  event for SystemProfiler. Since the conditions haven't changed, it
  now went into _MaybeNotifyProfilerThreadLocked again (this time
  from the profiler thread context). In there, it will try to lock
  the profiler thread's scheduling spinlock, which is already locked
  by the other thread (which is firmly sleeping). Deadlock, KDL.

* Before unblocking the profiler thread, unset fWaitingProfilerThread
  so that further events will not try to unblock it again.
This commit is contained in:
Julian Harnath
2017-11-24 18:22:14 +01:00
parent d45104b1eb
commit 5c821d1200
+5 -3
View File
@@ -220,10 +220,12 @@ SystemProfiler::_MaybeNotifyProfilerThreadLocked()
int cpu = smp_get_current_cpu();
fReentered[cpu] = true;
SpinLocker _(fWaitingProfilerThread->scheduler_lock);
thread_unblock_locked(fWaitingProfilerThread, B_OK);
Thread* profilerThread = fWaitingProfilerThread;
fWaitingProfilerThread = NULL;
SpinLocker _(profilerThread->scheduler_lock);
thread_unblock_locked(profilerThread, B_OK);
fReentered[cpu] = false;
}
}