util/deephash: avoid variadic argument for Update (#5372)

Hashing []any is slow since hashing of interfaces is slow.
Hashing of interfaces is slow since we pessimistically assume
that cycles can occur through them and start cycle tracking.

Drop the variadic signature of Update and fix callers to pass in
an anonymous struct so that we are hashing concrete types
near the root of the value tree.

Signed-off-by: Joe Tsai <joetsai@digital-static.net>

Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This commit is contained in:
Joe Tsai 2022-08-15 11:22:28 -07:00 committed by GitHub
parent 1c0286e98a
commit 32a1a3d1c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 10 deletions

View File

@ -1180,7 +1180,15 @@ func (b *LocalBackend) updateFilterLocked(netMap *netmap.NetworkMap, prefs *ipn.
sshPol = *netMap.SSHPolicy sshPol = *netMap.SSHPolicy
} }
changed := deephash.Update(&b.filterHash, haveNetmap, addrs, packetFilter, localNets.Ranges(), logNets.Ranges(), shieldsUp, sshPol) changed := deephash.Update(&b.filterHash, &struct {
HaveNetmap bool
Addrs []netip.Prefix
FilterMatch []filter.Match
LocalNets []netipx.IPRange
LogNets []netipx.IPRange
ShieldsUp bool
SSHPolicy tailcfg.SSHPolicy
}{haveNetmap, addrs, packetFilter, localNets.Ranges(), logNets.Ranges(), shieldsUp, sshPol})
if !changed { if !changed {
return return
} }

View File

@ -188,14 +188,13 @@ func HasherForType[T any]() func(T) Sum {
} }
// Update sets last to the hash of v and reports whether its value changed. // Update sets last to the hash of v and reports whether its value changed.
func Update(last *Sum, v ...any) (changed bool) { func Update(last *Sum, v any) (changed bool) {
sum := Hash(v) sum := Hash(v)
if sum == *last { changed = sum != *last
// unchanged. if changed {
return false *last = sum
} }
*last = sum return changed
return true
} }
var appenderToType = reflect.TypeOf((*appenderTo)(nil)).Elem() var appenderToType = reflect.TypeOf((*appenderTo)(nil)).Elem()

View File

@ -704,8 +704,12 @@ func (e *userspaceEngine) maybeReconfigWireguardLocked(discoChanged map[key.Node
} }
e.lastNMinPeers = len(min.Peers) e.lastNMinPeers = len(min.Peers)
if !deephash.Update(&e.lastEngineSigTrim, &min, trimmedNodes, trackNodes, trackIPs) { if changed := deephash.Update(&e.lastEngineSigTrim, &struct {
// No changes WGConfig *wgcfg.Config
TrimmedNodes map[key.NodePublic]bool
TrackNodes []key.NodePublic
TrackIPs []netip.Addr
}{&min, trimmedNodes, trackNodes, trackIPs}); !changed {
return nil return nil
} }
@ -856,7 +860,10 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config,
isSubnetRouterChanged := isSubnetRouter != e.lastIsSubnetRouter isSubnetRouterChanged := isSubnetRouter != e.lastIsSubnetRouter
engineChanged := deephash.Update(&e.lastEngineSigFull, cfg) engineChanged := deephash.Update(&e.lastEngineSigFull, cfg)
routerChanged := deephash.Update(&e.lastRouterSig, routerCfg, dnsCfg) routerChanged := deephash.Update(&e.lastRouterSig, &struct {
RouterConfig *router.Config
DNSConfig *dns.Config
}{routerCfg, dnsCfg})
if !engineChanged && !routerChanged && listenPort == e.magicConn.LocalPort() && !isSubnetRouterChanged { if !engineChanged && !routerChanged && listenPort == e.magicConn.LocalPort() && !isSubnetRouterChanged {
return ErrNoChanges return ErrNoChanges
} }