From 28c01a50f0fb972bb261c7df339ba14690e2c04b Mon Sep 17 00:00:00 2001 From: Kevin Krakauer Date: Fri, 15 Mar 2024 15:45:37 -0700 Subject: [PATCH] netstack: don't allocate to get send buffer size In a redis-benchmark PING_INLINE test, this reduces allocations by 7.7%. PiperOrigin-RevId: 616263988 --- pkg/tcpip/stack/stack.go | 10 ++++++++++ pkg/tcpip/transport/tcp/endpoint.go | 10 ++++------ pkg/tcpip/transport/tcp/protocol.go | 7 +++++++ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 4d3f74566..ee8bca2db 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -495,6 +495,16 @@ func (s *Stack) TransportProtocolOption(transport tcpip.TransportProtocolNumber, return transProtoState.proto.Option(option) } +// SendBufSizeProto is a protocol that can return its send buffer size. +type SendBufSizeProto interface { + SendBufferSize() tcpip.TCPSendBufferSizeRangeOption +} + +// TCPSendBufferLimits returns the TCP send buffer size limit. +func (s *Stack) TCPSendBufferLimits() tcpip.TCPSendBufferSizeRangeOption { + return s.transportProtocols[header.TCPProtocolNumber].proto.(SendBufSizeProto).SendBufferSize() +} + // SetTransportProtocolHandler sets the per-stack default handler for the given // protocol. // diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index f43b2cdf5..ba277f246 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -3228,12 +3228,10 @@ func (e *endpoint) SocketOptions() *tcpip.SocketOptions { } // GetTCPSendBufferLimits is used to get send buffer size limits for TCP. -func GetTCPSendBufferLimits(s tcpip.StackHandler) tcpip.SendBufferSizeOption { - var ss tcpip.TCPSendBufferSizeRangeOption - if err := s.TransportProtocolOption(header.TCPProtocolNumber, &ss); err != nil { - panic(fmt.Sprintf("s.TransportProtocolOption(%d, %#v) = %s", header.TCPProtocolNumber, ss, err)) - } - +func GetTCPSendBufferLimits(sh tcpip.StackHandler) tcpip.SendBufferSizeOption { + // This type assertion is safe because only the TCP stack calls this + // function. + ss := sh.(*stack.Stack).TCPSendBufferLimits() return tcpip.SendBufferSizeOption{ Min: ss.Min, Default: ss.Default, diff --git a/pkg/tcpip/transport/tcp/protocol.go b/pkg/tcpip/transport/tcp/protocol.go index 73aff4d37..8d53a9e82 100644 --- a/pkg/tcpip/transport/tcp/protocol.go +++ b/pkg/tcpip/transport/tcp/protocol.go @@ -480,6 +480,13 @@ func (p *protocol) Option(option tcpip.GettableTransportProtocolOption) tcpip.Er } } +// SendBufferSize implements stack.SendBufSizeProto. +func (p *protocol) SendBufferSize() tcpip.TCPSendBufferSizeRangeOption { + p.mu.RLock() + defer p.mu.RUnlock() + return p.sendBufferSize +} + // Close implements stack.TransportProtocol.Close. func (p *protocol) Close() { p.dispatcher.close()