diff options
| author | Jonathan Nobels <jonathan@tailscale.com> | 2026-04-10 13:00:34 -0400 |
|---|---|---|
| committer | Jonathan Nobels <jonathan@tailscale.com> | 2026-04-16 09:51:12 -0400 |
| commit | c18f8516c4d7f6339ea586c3f90d1025c9335bcd (patch) | |
| tree | 5d5ef11dc43fb828911a0dd8fa6faa28cb590ef3 | |
| parent | 399f0483321ac36d9e536cf12907c5ee42fe3ef9 (diff) | |
| download | tailscale-jonathan/deadlock-fix.tar.xz tailscale-jonathan/deadlock-fix.zip | |
ipn/ipnlocal: fix deadlock in ipn bus watcherjonathan/deadlock-fix
fixes tailscale/corp#40401
From an internal stack trace. We witnessed a slow bus error and
a complete lock up of the ipn bus watcher.
Stack showed a b.mu->t.mu and t.mu->b.mu lock ordering
issue when setting up the HealthTracker's initial state and its
timer simultaneously fires.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
| -rw-r--r-- | ipn/ipnlocal/local.go | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index 610d1d7b5..9aa7dc899 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -3233,9 +3233,6 @@ func (b *LocalBackend) WatchNotificationsAs(ctx context.Context, actor ipnauth.A if mask&ipn.NotifyInitialDriveShares != 0 && b.DriveSharingEnabled() { ini.DriveShares = b.pm.prefs.DriveShares() } - if mask&ipn.NotifyInitialHealthState != 0 { - ini.Health = b.HealthTracker().CurrentState() - } if mask&ipn.NotifyInitialSuggestedExitNode != 0 { if en, err := b.suggestExitNodeLocked(); err == nil { ini.SuggestedExitNode = &en.ID @@ -3261,6 +3258,10 @@ func (b *LocalBackend) WatchNotificationsAs(ctx context.Context, actor ipnauth.A mak.Set(&b.notifyWatchers, sessionID, session) b.mu.Unlock() + if mask&ipn.NotifyInitialHealthState != 0 && ini != nil { + ini.Health = b.HealthTracker().CurrentState() + } + metricCurrentWatchIPNBus.Add(1) defer metricCurrentWatchIPNBus.Add(-1) |
