diff --git a/probe/endpoint/procspy/background_reader_linux.go b/probe/endpoint/procspy/background_reader_linux.go index f51bf9f84..96668c65f 100644 --- a/probe/endpoint/procspy/background_reader_linux.go +++ b/probe/endpoint/procspy/background_reader_linux.go @@ -13,10 +13,11 @@ import ( ) const ( - initialRateLimit = 50 * time.Millisecond // Read 20 * fdBlockSize file descriptors (/proc/PID/fd/*) per namespace per second - maxRateLimit = 250 * time.Millisecond // Read at least 4 * fdBlockSize file descriptors per namespace per second - fdBlockSize = uint64(300) - targetWalkTime = 10 * time.Second // Aim at walking all files in 10 seconds + initialRateLimitPeriod = 50 * time.Millisecond // Read 20 * fdBlockSize file descriptors (/proc/PID/fd/*) per namespace per second + maxRateLimitPeriod = 250 * time.Millisecond // Read at least 4 * fdBlockSize file descriptors per namespace per second + fdBlockSize = uint64(300) // Maximum number of /proc/PID/fd/* files to stat per rate-limit period + // (as a rule of thumb going through each block should be more expensive than reading /proc/PID/tcp{,6}) + targetWalkTime = 10 * time.Second // Aim at walking all files in 10 seconds ) type backgroundReader struct { @@ -63,12 +64,12 @@ func (br *backgroundReader) stop() error { func (br *backgroundReader) loop() { const ( - maxRateLimitF = float64(maxRateLimit) - targetWalkTimeF = float64(targetWalkTime) + maxRateLimitPeriodF = float64(maxRateLimitPeriod) + targetWalkTimeF = float64(targetWalkTime) ) - rateLimit := initialRateLimit - ticker := time.NewTicker(rateLimit) + rateLimitPeriod := initialRateLimitPeriod + ticker := time.NewTicker(rateLimitPeriod) for { start := time.Now() sockets, err := walkProcPid(br.walkingBuf, br.walker, ticker.C, fdBlockSize) @@ -107,12 +108,12 @@ func (br *backgroundReader) loop() { } // Adjust rate limit to more-accurately meet the target walk time in next iteration - scaledRateLimit := targetWalkTimeF / walkTimeF * float64(rateLimit) - rateLimit = time.Duration(math.Min(scaledRateLimit, maxRateLimitF)) - log.Debugf("background /proc reader: new rate limit %s", rateLimit) + scaledRateLimitPeriod := targetWalkTimeF / walkTimeF * float64(rateLimitPeriod) + rateLimitPeriod = time.Duration(math.Min(scaledRateLimitPeriod, maxRateLimitPeriodF)) + log.Debugf("background /proc reader: new rate limit %s", rateLimitPeriod) ticker.Stop() - ticker = time.NewTicker(rateLimit) + ticker = time.NewTicker(rateLimitPeriod) br.walkingBuf.Reset() diff --git a/probe/endpoint/procspy/proc_internal_test.go b/probe/endpoint/procspy/proc_internal_test.go index 1e3bc7466..362068c41 100644 --- a/probe/endpoint/procspy/proc_internal_test.go +++ b/probe/endpoint/procspy/proc_internal_test.go @@ -61,7 +61,7 @@ func TestWalkProcPid(t *testing.T) { walker := process.NewWalker(procRoot) ticker := time.NewTicker(time.Millisecond) defer ticker.Stop() - fdBlockSize := 1 + fdBlockSize := uint64(1) have, err := walkProcPid(&buf, walker, ticker.C, fdBlockSize) if err != nil { t.Fatal(err)