From 9a3019796bc8f0714d27fdd52ea503b292035da3 Mon Sep 17 00:00:00 2001 From: Filippo Giunchedi Date: Tue, 10 Oct 2023 09:55:59 +0200 Subject: [PATCH] container: skip checking for files in non-existent directories. Inspired by profile data from @brancz at https://pprof.me/5dfadaf/ and confirmed via `strace`. On cgroup v1 systems about half of Stat calls turn out to be for files within paths that don't exist. I have also added very basic benchmarks for getSpecInternal. --- container/common/helpers.go | 4 ++++ container/common/helpers_test.go | 37 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/container/common/helpers.go b/container/common/helpers.go index 572c414ce7..dbffc922e9 100644 --- a/container/common/helpers.go +++ b/container/common/helpers.go @@ -75,7 +75,11 @@ func getSpecInternal(cgroupPaths map[string]string, machineInfoFactory info.Mach dir, err := os.Stat(cgroupPathDir) if err == nil && dir.ModTime().Before(lowestTime) { lowestTime = dir.ModTime() + } else if os.IsNotExist(err) { + // Directory does not exist, skip checking for files within. + continue } + // The modified time of the cgroup directory sometimes changes whenever a subcontainer is created. // eg. /docker will have creation time matching the creation of latest docker container. // Use clone_children/events as a workaround as it isn't usually modified. It is only likely changed diff --git a/container/common/helpers_test.go b/container/common/helpers_test.go index b926d53c79..5688b89f17 100644 --- a/container/common/helpers_test.go +++ b/container/common/helpers_test.go @@ -247,3 +247,40 @@ func TestRemoveNetMetrics(t *testing.T) { } } } + +func BenchmarkGetSpecCgroupV2(b *testing.B) { + root, err := os.Getwd() + if err != nil { + b.Fatalf("getwd: %s", err) + } + + cgroupPaths := map[string]string{ + "": filepath.Join(root, "test_resources/cgroup_v2/test1"), + } + + for i := 0; i < b.N; i++ { + _, err := getSpecInternal(cgroupPaths, &mockInfoProvider{}, false, false, true) + assert.Nil(b, err) + } + +} + +func BenchmarkGetSpecCgroupV1(b *testing.B) { + root, err := os.Getwd() + if err != nil { + b.Fatalf("getwd: %s", err) + } + + cgroupPaths := map[string]string{ + "memory": filepath.Join(root, "test_resources/cgroup_v1/test1/memory"), + "cpu": filepath.Join(root, "test_resources/cgroup_v1/test1/cpu"), + "cpuset": filepath.Join(root, "test_resources/cgroup_v1/test1/cpuset"), + "pids": filepath.Join(root, "test_resources/cgroup_v1/test1/pids"), + } + + for i := 0; i < b.N; i++ { + _, err := getSpecInternal(cgroupPaths, &mockInfoProvider{}, false, false, false) + assert.Nil(b, err) + } + +}