]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: add a sync.Pool for a NetlinkRIB scratch buffer
authorBrad Fitzpatrick <bradfitz@golang.org>
Mon, 17 Apr 2023 20:32:03 +0000 (13:32 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 18 Apr 2023 14:42:52 +0000 (14:42 +0000)
The syscall.NetlinkRIB signature means it necessarily allocates but
this changes makes it allocate a bit less. For example, in the net
package:

    name                           old time/op    new time/op    delta
    Interfaces-8                     59.1µs ± 3%    57.3µs ± 2%   -3.02%  (p=0.000 n=10+10)
    InterfaceByIndex-8               53.1µs ± 5%    50.6µs ± 2%   -4.81%  (p=0.000 n=10+10)
    InterfaceByName-8                59.3µs ± 2%    57.4µs ± 1%   -3.29%  (p=0.000 n=10+10)
    InterfaceAddrs-8                  105µs ± 1%     101µs ± 1%   -4.22%  (p=0.000 n=10+9)
    InterfacesAndAddrs-8             38.2µs ± 3%    36.3µs ± 2%   -4.98%  (p=0.000 n=10+10)
    InterfacesAndMulticastAddrs-8     152µs ± 2%     154µs ± 6%     ~     (p=0.105 n=10+10)

    name                           old alloc/op   new alloc/op   delta
    Interfaces-8                     22.8kB ± 0%    18.7kB ± 0%  -17.90%  (p=0.000 n=10+9)
    InterfaceByIndex-8               16.2kB ± 0%    12.1kB ± 0%  -25.22%  (p=0.000 n=10+10)
    InterfaceByName-8                22.8kB ± 0%    18.8kB ± 0%  -17.85%  (p=0.000 n=10+10)
    InterfaceAddrs-8                 36.6kB ± 0%    28.5kB ± 0%  -22.28%  (p=0.000 n=10+10)
    InterfacesAndAddrs-8             9.60kB ± 0%    5.51kB ± 0%  -42.59%  (p=0.000 n=10+7)
    InterfacesAndMulticastAddrs-8     141kB ± 0%     141kB ± 0%     ~     (all equal)

    name                           old allocs/op  new allocs/op  delta
    Interfaces-8                       53.0 ± 0%      52.0 ± 0%   -1.89%  (p=0.000 n=10+10)
    InterfaceByIndex-8                 28.0 ± 0%      27.0 ± 0%   -3.57%  (p=0.000 n=10+10)
    InterfaceByName-8                  54.0 ± 0%      53.0 ± 0%   -1.85%  (p=0.000 n=10+10)
    InterfaceAddrs-8                    155 ± 0%       153 ± 0%   -1.29%  (p=0.000 n=10+10)
    InterfacesAndAddrs-8               38.0 ± 0%      37.0 ± 0%   -2.63%  (p=0.000 n=10+10)
    InterfacesAndMulticastAddrs-8      77.0 ± 0%      77.0 ± 0%     ~     (all equal)

Signed-off-by: Brad Fitzpatrick <bradfitz@golang.org>
Change-Id: Ic3278b2c000af78d7ed816645463c3b7ff0c90ca
Reviewed-on: https://go-review.googlesource.com/c/go/+/485455
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
src/net/interface_test.go
src/syscall/netlink_linux.go

index da54a660e5ca3be537afbdebaf303067a4dcdc0e..5590b062627fdbdfda05edb78b3ddf162d54cf6a 100644 (file)
@@ -300,6 +300,7 @@ func checkMulticastStats(ifStats *ifStats, uniStats, multiStats *routeStats) err
 }
 
 func BenchmarkInterfaces(b *testing.B) {
+       b.ReportAllocs()
        testHookUninstaller.Do(uninstallTestHooks)
 
        for i := 0; i < b.N; i++ {
@@ -310,6 +311,7 @@ func BenchmarkInterfaces(b *testing.B) {
 }
 
 func BenchmarkInterfaceByIndex(b *testing.B) {
+       b.ReportAllocs()
        testHookUninstaller.Do(uninstallTestHooks)
 
        ifi := loopbackInterface()
@@ -324,6 +326,7 @@ func BenchmarkInterfaceByIndex(b *testing.B) {
 }
 
 func BenchmarkInterfaceByName(b *testing.B) {
+       b.ReportAllocs()
        testHookUninstaller.Do(uninstallTestHooks)
 
        ifi := loopbackInterface()
@@ -338,6 +341,7 @@ func BenchmarkInterfaceByName(b *testing.B) {
 }
 
 func BenchmarkInterfaceAddrs(b *testing.B) {
+       b.ReportAllocs()
        testHookUninstaller.Do(uninstallTestHooks)
 
        for i := 0; i < b.N; i++ {
@@ -348,6 +352,7 @@ func BenchmarkInterfaceAddrs(b *testing.B) {
 }
 
 func BenchmarkInterfacesAndAddrs(b *testing.B) {
+       b.ReportAllocs()
        testHookUninstaller.Do(uninstallTestHooks)
 
        ifi := loopbackInterface()
@@ -362,6 +367,7 @@ func BenchmarkInterfacesAndAddrs(b *testing.B) {
 }
 
 func BenchmarkInterfacesAndMulticastAddrs(b *testing.B) {
+       b.ReportAllocs()
        testHookUninstaller.Do(uninstallTestHooks)
 
        ifi := loopbackInterface()
index e976c70ef1670ae97987a20733d4e9fefeb0c67e..a503a0744005bbf7b951604504b4335a80aa71de 100644 (file)
@@ -6,7 +6,10 @@
 
 package syscall
 
-import "unsafe"
+import (
+       "sync"
+       "unsafe"
+)
 
 // Round the length of a netlink message up to align it properly.
 func nlmAlignOf(msglen int) int {
@@ -47,6 +50,11 @@ func newNetlinkRouteRequest(proto, seq, family int) []byte {
        return rr.toWireFormat()
 }
 
+var pageBufPool = &sync.Pool{New: func() any {
+       b := make([]byte, Getpagesize())
+       return &b
+}}
+
 // NetlinkRIB returns routing information base, as known as RIB, which
 // consists of network facility information, states and parameters.
 func NetlinkRIB(proto, family int) ([]byte, error) {
@@ -72,10 +80,12 @@ func NetlinkRIB(proto, family int) ([]byte, error) {
                return nil, EINVAL
        }
        var tab []byte
-       rbNew := make([]byte, Getpagesize())
+
+       rbNew := pageBufPool.Get().(*[]byte)
+       defer pageBufPool.Put(rbNew)
 done:
        for {
-               rb := rbNew
+               rb := *rbNew
                nr, _, err := Recvfrom(s, rb, 0)
                if err != nil {
                        return nil, err