[roll] Roll fuchsia [x86][idle] Fix a race in the idle thread. Fix a race in the x86 implementation of the idle thread which could lead to a thread being stuck in the READY state for a period of time instead of being scheduled to run immediately. This was a pretty tough one to find, and is a bit complicated. For full details, please refer to the analysis posted here https://bugs.fuchsia.dev/p/fuchsia/issues/detail?id=102058#c58 Here is the short version. When configured to use MONTOR/MWAIT for putting the CPU into a lower power state when idle, the idle loop basically looks like the following. ``` while (true) { AutoPreemptDisable apd; while (!signaled and !has_pending_preempts) { monitor(signaled); if (!signaled and !has_pending_preempts) { mwait(); } } } ``` So, preemption is disabled and we sit in mwait until we have a pending preempt, or until someone writes to our per-cpu signal variable. The second check (in the if predicate) exists to handle a case where another CPU signals us through our global variable after the while check and just before the monitor check. There is a window of time, however, after arming the monitor and performing our second check, but before dropping into the mwait, where an interrupt can fire. If this unblocks a thread and assigns it to the local CPU, it will cause a preempt to become locally. It cannot reschedule immediately, however, because the idle thread has disabled preemption. When the interrupt unwinds, the idle thread will be past the second check but not in the mwait yet. When it drops into the mwait, it will not immediately wake up as the interrupt fired before it made it into the wait state. The fix is to handle this the same way that we handle the HLT version of this thread. Disable interrupts before we make our final check, then re-enable them one instruction before the MWAIT. This puts the MWAIT into the interrupt shadow of the STI instruction, and guarantees that we will have made it into MWAIT before the interrupt fires and kicks us out again. Original-Bug: 102058 Original-Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/717178 Original-Revision: bd41e2902a2aaf71c0e16e4a603850c1a7c064b8 GitOrigin-RevId: 0da87dd7a3ab9f27f6e5e00b69fe5ff03d8a911f Change-Id: I9d33938b5b89822cf3e1f6f07fd99bed35ab437f
This repository contains Fuchsia's Global Integration manifest files.
All changes should be made to the internal version of this repository. Our infrastructure automatically updates this version when the internal one changes.
Currently all changes must be made by a Google employee. Non-Google employees wishing to make a change can ask for assistance via the IRC channel #fuchsia on Freenode.
First install Jiri.
Next run:
$ jiri init $ jiri import minimal https://fuchsia.googlesource.com/integration $ jiri update
Third party projects should have their own subdirectory in ./third_party.