Skip to content

Commit

Permalink
maps: Consider actual passed time for GC interval calculation
Browse files Browse the repository at this point in the history
When GetInterval calculates the new GC interval, it uses the result of
the previous calculation as a pivot point. However, if GC was triggered
by a signal, smaller time interval has passed, therefore, expectations
on the delete ratio should be lower. Adjust the delete ratio
proportionally to avoid increasing the interval uncontrollably when
multiple signals arrive over a short period of time.

Ref: #27405
Signed-off-by: Maxim Mikityanskiy <maxim@isovalent.com>
  • Loading branch information
gentoo-root committed Feb 17, 2024
1 parent d1834ba commit 590a1cf
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 14 deletions.
22 changes: 14 additions & 8 deletions pkg/maps/ctmap/ctmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -864,25 +864,31 @@ var cachedGCInterval time.Duration

// GetInterval returns the interval adjusted based on the deletion ratio of the
// last run
func GetInterval(maxDeleteRatio float64) time.Duration {
func GetInterval(actualPrevInterval time.Duration, maxDeleteRatio float64) time.Duration {
if val := option.Config.ConntrackGCInterval; val != time.Duration(0) {
return val
}

prevInterval := cachedGCInterval
if prevInterval == time.Duration(0) {
prevInterval = defaults.ConntrackGCStartingInterval
expectedPrevInterval := cachedGCInterval
adjustedDeleteRatio := maxDeleteRatio
if expectedPrevInterval == time.Duration(0) {
expectedPrevInterval = defaults.ConntrackGCStartingInterval
} else if actualPrevInterval < expectedPrevInterval && actualPrevInterval > 0 {
adjustedDeleteRatio *= float64(expectedPrevInterval) / float64(actualPrevInterval)
}

newInterval := calculateInterval(prevInterval, maxDeleteRatio)
newInterval := calculateInterval(expectedPrevInterval, adjustedDeleteRatio)
if val := option.Config.ConntrackGCMaxInterval; val != time.Duration(0) && newInterval > val {
newInterval = val
}

if newInterval != prevInterval {
if newInterval != expectedPrevInterval {
log.WithFields(logrus.Fields{
"newInterval": newInterval,
"deleteRatio": maxDeleteRatio,
"expectedPrevInterval": expectedPrevInterval,
"actualPrevInterval": actualPrevInterval,
"newInterval": newInterval,
"deleteRatio": maxDeleteRatio,
"adjustedDeleteRatio": adjustedDeleteRatio,
}).Info("Conntrack garbage collector interval recalculated")
}

Expand Down
10 changes: 5 additions & 5 deletions pkg/maps/ctmap/ctmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,21 @@ func (t *CTMapTestSuite) TestCalculateInterval(c *C) {

func (t *CTMapTestSuite) TestGetInterval(c *C) {
cachedGCInterval = time.Minute
c.Assert(GetInterval(0.1), Equals, time.Minute)
c.Assert(GetInterval(cachedGCInterval, 0.1), Equals, time.Minute)

// Setting ConntrackGCInterval overrides the calculation
oldInterval := option.Config.ConntrackGCInterval
option.Config.ConntrackGCInterval = 10 * time.Second
c.Assert(GetInterval(0.1), Equals, 10*time.Second)
c.Assert(GetInterval(cachedGCInterval, 0.1), Equals, 10*time.Second)
option.Config.ConntrackGCInterval = oldInterval
c.Assert(GetInterval(0.1), Equals, time.Minute)
c.Assert(GetInterval(cachedGCInterval, 0.1), Equals, time.Minute)

// Setting ConntrackGCMaxInterval limits the maximum interval
oldMaxInterval := option.Config.ConntrackGCMaxInterval
option.Config.ConntrackGCMaxInterval = 20 * time.Second
c.Assert(GetInterval(0.1), Equals, 20*time.Second)
c.Assert(GetInterval(cachedGCInterval, 0.1), Equals, 20*time.Second)
option.Config.ConntrackGCMaxInterval = oldMaxInterval
c.Assert(GetInterval(0.1), Equals, time.Minute)
c.Assert(GetInterval(cachedGCInterval, 0.1), Equals, time.Minute)

cachedGCInterval = time.Duration(0)
}
Expand Down
9 changes: 8 additions & 1 deletion pkg/maps/ctmap/gc/gc.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ func (gc *GC) Enable(restoredEndpoints []*endpoint.Endpoint) {
ipv6 := gc.ipv6
triggeredBySignal := false
ctTimer, ctTimerDone := inctimer.New()
var gcPrev time.Time
defer ctTimerDone()
for {
var (
Expand Down Expand Up @@ -138,6 +139,12 @@ func (gc *GC) Enable(restoredEndpoints []*endpoint.Endpoint) {
}
)

gcInterval := gcStart.Sub(gcPrev)
if gcPrev.IsZero() {
gcInterval = time.Duration(0)
}
gcPrev = gcStart

eps := gc.endpointsManager.GetEndpoints()
for _, e := range eps {
epsMap[e.IPv4Address()] = e
Expand Down Expand Up @@ -190,7 +197,7 @@ func (gc *GC) Enable(restoredEndpoints []*endpoint.Endpoint) {
ipv6 = true
}
}
case <-ctTimer.After(ctmap.GetInterval(maxDeleteRatio)):
case <-ctTimer.After(ctmap.GetInterval(gcInterval, maxDeleteRatio)):
gc.signalHandler.MuteSignals()
ipv4 = gc.ipv4
ipv6 = gc.ipv6
Expand Down

0 comments on commit 590a1cf

Please sign in to comment.