Repository navigation
Conversation
0f0efc1 to
ce807f1
Compare
InterfaceByIndex and InterfaceByName dumped every link with an
AF_UNSPEC RTM_GETLINK dump and picked one out of the result, since
interfaceTable ignored the index it was given on Linux, so a single
lookup cost as much as Interfaces and grew with the number of links on
the host. A daemon that resolves interface names and indexes on every
event spent most of its idle CPU there.
Ask the kernel for the one link instead, with an RTM_GETLINK request
that carries the index, or the name in IFLA_IFNAME, which Linux has
answered since 2.6.33. The kernel refuses to filter link dumps by
index, so the filtered dumps that Interface.Addrs uses since CL 848185
are not an option here. A missing interface is reported as absent, as
before, and any other failure of the request falls back to the dump.
InterfaceByName no longer refreshes the IPv6 zone cache on Linux as a
side effect; the cache refreshes itself.
Other platforms keep scanning the table, through a new interfaceByName
hook whose generic implementation is the table scan. BSD already
fetches one interface by index.
On a laptop with 37 links:
goos: linux
goarch: amd64
pkg: net
cpu: AMD Ryzen 7 PRO 6850U with Radeon Graphics
| before | after |
| sec/op | sec/op vs base |
Interfaces-16 415.9µ ± 4% 417.4µ ± 5% ~ (p=0.699 n=6)
InterfaceByIndex-16 353.84µ ± 2% 17.32µ ± 18% -95.11% (p=0.002 n=6)
InterfaceByName-16 434.01µ ± 6% 18.98µ ± 4% -95.63% (p=0.002 n=6)
| before | after |
| B/op | B/op vs base |
InterfaceByIndex-16 307.461Ki ± 0% 8.656Ki ± 0% -97.18% (p=0.002 n=6)
InterfaceByName-16 474.738Ki ± 0% 8.595Ki ± 0% -98.19% (p=0.002 n=6)
In a network namespace with 501 links:
| before | after |
| sec/op | sec/op vs base |
Interfaces-16 6.217m ± 67% 5.941m ± 8% ~ (p=0.065 n=6)
InterfaceByIndex-16 7809.33µ ± 2% 15.62µ ± 4% -99.80% (p=0.002 n=6)
InterfaceByName-16 5950.19µ ± 73% 16.45µ ± 6% -99.72% (p=0.002 n=6)
Fixes golang#82381
ce807f1 to
a7df664
Compare
|
This PR (HEAD: a7df664) has been imported to Gerrit for code review. Please visit Gerrit at https://go-review.googlesource.com/c/go/+/851865. Important tips:
|
|
Message from Gopher Robot: Patch Set 1: Congratulations on opening your first change. Thank you for your contribution! Next steps: Most changes in the Go project go through a few rounds of revision. This can be During May-July and Nov-Jan the Go project is in a code freeze, during which Please don’t reply on this GitHub thread. Visit golang.org/cl/851865. |
InterfaceByIndex and InterfaceByName dumped every link with an
AF_UNSPEC RTM_GETLINK dump and picked one out of the result, since
interfaceTable ignored the index it was given on Linux, so a single
lookup cost as much as Interfaces and grew with the number of links on
the host. A daemon that resolves interface names and indexes on every
event spent most of its idle CPU there.
Ask the kernel for the one link instead, with an RTM_GETLINK request
that carries the index, or the name in IFLA_IFNAME, which Linux has
answered since 2.6.33. The kernel refuses to filter link dumps by
index, so the filtered dumps that Interface.Addrs uses since CL 848185
are not an option here. A missing interface is reported as absent, as
before, and any other failure of the request falls back to the dump.
InterfaceByName no longer refreshes the IPv6 zone cache on Linux as a
side effect; the cache refreshes itself.
Other platforms keep scanning the table, through a new interfaceByName
hook whose generic implementation is the table scan. BSD already
fetches one interface by index.
On a laptop with 37 links:
In a network namespace with 501 links:
Fixes #82381