mirror of
https://github.com/slackhq/nebula.git
synced 2025-11-22 08:24:25 +01:00
reuse GRO slices
This commit is contained in:
@@ -52,10 +52,9 @@ type StdConn struct {
|
||||
gsoMaxBytes int
|
||||
gsoFlushTimeout time.Duration
|
||||
|
||||
groSegmentPool sync.Pool
|
||||
groBufSize atomic.Int64
|
||||
rxBufferPool chan []byte
|
||||
gsoBufferPool sync.Pool
|
||||
groBufSize atomic.Int64
|
||||
rxBufferPool chan []byte
|
||||
gsoBufferPool sync.Pool
|
||||
|
||||
gsoBatches metrics.Counter
|
||||
gsoSegments metrics.Counter
|
||||
@@ -276,9 +275,6 @@ func (u *StdConn) setGroBufferSize(size int) {
|
||||
size = defaultGROReadBufferSize
|
||||
}
|
||||
u.groBufSize.Store(int64(size))
|
||||
u.groSegmentPool = sync.Pool{New: func() any {
|
||||
return make([]byte, size)
|
||||
}}
|
||||
if u.rxBufferPool == nil {
|
||||
poolSize := u.batch * 4
|
||||
if poolSize < u.batch {
|
||||
@@ -2272,6 +2268,13 @@ func (u *StdConn) logIoUringResult(addr netip.AddrPort, expected, written int, e
|
||||
}
|
||||
|
||||
func (u *StdConn) emitSegments(r EncReader, addr netip.AddrPort, payload []byte, segSize, segCount int, release func()) bool {
|
||||
var releaseFlag atomic.Bool
|
||||
releaseOnce := func() {
|
||||
if release != nil && releaseFlag.CompareAndSwap(false, true) {
|
||||
release()
|
||||
}
|
||||
}
|
||||
|
||||
if segSize <= 0 || segSize >= len(payload) {
|
||||
u.l.WithFields(logrus.Fields{
|
||||
"tag": "gro-debug",
|
||||
@@ -2281,6 +2284,7 @@ func (u *StdConn) emitSegments(r EncReader, addr netip.AddrPort, payload []byte,
|
||||
"seg_size": segSize,
|
||||
"seg_count": segCount,
|
||||
}).Debug("gro-debug skip emit")
|
||||
releaseOnce()
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -2297,42 +2301,27 @@ func (u *StdConn) emitSegments(r EncReader, addr netip.AddrPort, payload []byte,
|
||||
"seg_size": segSize,
|
||||
"seg_count": segCount,
|
||||
}).Debug("gro-debug skip emit")
|
||||
releaseOnce()
|
||||
return false
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if release != nil {
|
||||
release()
|
||||
}
|
||||
}()
|
||||
|
||||
actualSegments := 0
|
||||
start := 0
|
||||
starts := make([]int, 0, segCount)
|
||||
lens := make([]int, 0, segCount)
|
||||
debugEnabled := u.l.IsLevelEnabled(logrus.DebugLevel)
|
||||
var firstHeader header.H
|
||||
var firstParsed bool
|
||||
var firstCounter uint64
|
||||
var firstRemote uint32
|
||||
actualSegments := 0
|
||||
start := 0
|
||||
|
||||
for start < totalLen && actualSegments < segCount {
|
||||
end := start + segSize
|
||||
if end > totalLen {
|
||||
end = totalLen
|
||||
}
|
||||
|
||||
segLen := end - start
|
||||
bufAny := u.groSegmentPool.Get()
|
||||
var segBuf []byte
|
||||
if bufAny == nil {
|
||||
segBuf = make([]byte, segLen)
|
||||
} else {
|
||||
segBuf = bufAny.([]byte)
|
||||
if cap(segBuf) < segLen {
|
||||
segBuf = make([]byte, segLen)
|
||||
}
|
||||
}
|
||||
segment := segBuf[:segLen]
|
||||
copy(segment, payload[start:end])
|
||||
segment := payload[start:end]
|
||||
|
||||
if debugEnabled && !firstParsed {
|
||||
if err := firstHeader.Parse(segment); err == nil {
|
||||
@@ -2353,11 +2342,10 @@ func (u *StdConn) emitSegments(r EncReader, addr netip.AddrPort, payload []byte,
|
||||
}
|
||||
}
|
||||
|
||||
starts = append(starts, start)
|
||||
lens = append(lens, segLen)
|
||||
start = end
|
||||
actualSegments++
|
||||
r(addr, segment, func() {
|
||||
u.groSegmentPool.Put(segBuf[:cap(segBuf)])
|
||||
})
|
||||
|
||||
if debugEnabled && actualSegments == segCount && segLen < segSize {
|
||||
var tail header.H
|
||||
@@ -2372,7 +2360,22 @@ func (u *StdConn) emitSegments(r EncReader, addr netip.AddrPort, payload []byte,
|
||||
}).Debug("gro-debug tail segment metadata")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if actualSegments == 0 {
|
||||
releaseOnce()
|
||||
return false
|
||||
}
|
||||
|
||||
var remaining int32 = int32(actualSegments)
|
||||
for i := range starts {
|
||||
segment := payload[starts[i] : starts[i]+lens[i]]
|
||||
segmentRelease := func() {
|
||||
if atomic.AddInt32(&remaining, -1) == 0 {
|
||||
releaseOnce()
|
||||
}
|
||||
}
|
||||
r(addr, segment, segmentRelease)
|
||||
}
|
||||
|
||||
if u.groBatches != nil {
|
||||
@@ -2384,7 +2387,7 @@ func (u *StdConn) emitSegments(r EncReader, addr netip.AddrPort, payload []byte,
|
||||
u.groBatchTick.Add(1)
|
||||
u.groSegmentsTick.Add(int64(actualSegments))
|
||||
|
||||
if debugEnabled && actualSegments > 0 {
|
||||
if debugEnabled {
|
||||
lastLen := segSize
|
||||
if tail := totalLen % segSize; tail != 0 {
|
||||
lastLen = tail
|
||||
|
||||
Reference in New Issue
Block a user