• Austin Clements's avatar
    runtime: fix goroutine priority elevation · 44497eba
    Austin Clements authored
    Currently it's possible for user code to exploit the high scheduler
    priority of the GC worker in conjunction with the runnext optimization
    to elevate a user goroutine to high priority so it will always run
    even if there are other runnable goroutines.
    
    For example, if a goroutine is in a tight allocation loop, the
    following can happen:
    
    1. Goroutine 1 allocates, triggering a GC.
    2. G 1 attempts an assist, but fails and blocks.
    3. The scheduler runs the GC worker, since it is high priority.
       Note that this also starts a new scheduler quantum.
    4. The GC worker does enough work to satisfy the assist.
    5. The GC worker readies G 1, putting it in runnext.
    6. GC finishes and the scheduler runs G 1 from runnext, giving it
       the rest of the GC worker's quantum.
    7. Go to 1.
    
    Even if there are other goroutines on the run queue, they never get a
    chance to run in the above sequence. This requires a confluence of
    circumstances that make it unlikely, though not impossible, that it
    would happen in "real" code. In the test added by this commit, we
    force this confluence by setting GOMAXPROCS to 1 and GOGC to 1 so it's
    easy for the test to repeated trigger GC and wake from a blocked
    assist.
    
    We fix this by making GC always put user goroutines at the end of the
    run queue, instead of in runnext. This makes it so user code can't
    piggy-back on the GC's high priority to make a user goroutine act like
    it has high priority. The only other situation where GC wakes user
    goroutines is waking all blocked assists at the end, but this uses the
    global run queue and hence doesn't have this problem.
    
    Fixes #15706.
    
    Change-Id: I1589dee4b7b7d0c9c8575ed3472226084dfce8bc
    Reviewed-on: https://go-review.googlesource.com/23172Reviewed-by: 's avatarRick Hudson <rlh@golang.org>
    44497eba
Name
Last commit
Last update
..
archive Loading commit data...
bufio Loading commit data...
builtin Loading commit data...
bytes Loading commit data...
cmd Loading commit data...
compress Loading commit data...
container Loading commit data...
context Loading commit data...
crypto Loading commit data...
database/sql Loading commit data...
debug Loading commit data...
encoding Loading commit data...
errors Loading commit data...
expvar Loading commit data...
flag Loading commit data...
fmt Loading commit data...
go Loading commit data...
hash Loading commit data...
html Loading commit data...
image Loading commit data...
index/suffixarray Loading commit data...
internal Loading commit data...
io Loading commit data...
log Loading commit data...
math Loading commit data...
mime Loading commit data...
net Loading commit data...
os Loading commit data...
path Loading commit data...
reflect Loading commit data...
regexp Loading commit data...
runtime Loading commit data...
sort Loading commit data...
strconv Loading commit data...
strings Loading commit data...
sync Loading commit data...
syscall Loading commit data...
testing Loading commit data...
text Loading commit data...
time Loading commit data...
unicode Loading commit data...
unsafe Loading commit data...
vendor/golang.org/x/net Loading commit data...
Make.dist Loading commit data...
all.bash Loading commit data...
all.bat Loading commit data...
all.rc Loading commit data...
androidtest.bash Loading commit data...
bootstrap.bash Loading commit data...
buildall.bash Loading commit data...
clean.bash Loading commit data...
clean.bat Loading commit data...
clean.rc Loading commit data...
cmp.bash Loading commit data...
iostest.bash Loading commit data...
make.bash Loading commit data...
make.bat Loading commit data...
make.rc Loading commit data...
naclmake.bash Loading commit data...
nacltest.bash Loading commit data...
race.bash Loading commit data...
race.bat Loading commit data...
run.bash Loading commit data...
run.bat Loading commit data...
run.rc Loading commit data...