wgengine: use a singleflight.Group to reduce status contention (#5450)

Updates tailscale/coral#72

Signed-off-by: Andrew Dunham <andrew@tailscale.com>

Signed-off-by: Andrew Dunham <andrew@tailscale.com>
This commit is contained in:
Andrew Dunham 2022-08-27 12:36:07 -04:00 committed by GitHub
parent 70f9fc8c7a
commit e8f09d24c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 1 deletions

View File

@ -157,12 +157,21 @@ func (e *userspaceEngine) onOpenTimeout(flow flowtrack.Tuple) {
return
}
// We don't care if this information is perfectly up-to-date, since
// we're just using it to print debug information.
//
// In tailscale/coral#72, we see a goroutine profile with thousands of
// goroutines blocked on the mutex in getStatus here, so we wrap it in
// a singleflight and accept stale information to reduce contention.
st, err, _ := e.getStatusSf.Do(struct{}{}, e.getStatus)
var ps *ipnstate.PeerStatusLite
if st, err := e.getStatus(); err == nil {
if err == nil {
for _, v := range st.Peers {
if v.NodeKey == n.Key {
v := v // copy
ps = &v
break
}
}
} else {

View File

@ -46,6 +46,7 @@
"tailscale.com/util/clientmetric"
"tailscale.com/util/deephash"
"tailscale.com/util/mak"
"tailscale.com/util/singleflight"
"tailscale.com/version"
"tailscale.com/wgengine/filter"
"tailscale.com/wgengine/magicsock"
@ -146,6 +147,10 @@ type userspaceEngine struct {
// value of the ICMP identifer and sequence number concatenated.
icmpEchoResponseCallback map[uint32]func()
// this singleflight is used to deduplicate calls to getStatus when we
// don't care if the data is perfectly fresh
getStatusSf singleflight.Group[struct{}, *Status]
// Lock ordering: magicsock.Conn.mu, wgLock, then mu.
}