From ec8f6854bf580e2d17e4503bd460cd90aafa993d Mon Sep 17 00:00:00 2001 From: Florian Lehner Date: Thu, 26 Oct 2023 10:42:28 +0200 Subject: [PATCH] metric/system/cgroup: add cache for v2 entries As multiple PIDs can use the same v2 cgroup, cache the result to reduce CPU usage and number of syscalls. --- metric/system/cgroup/reader.go | 6 +++++- metric/system/cgroup/util.go | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/metric/system/cgroup/reader.go b/metric/system/cgroup/reader.go index f9aae99fef..7f5a497001 100644 --- a/metric/system/cgroup/reader.go +++ b/metric/system/cgroup/reader.go @@ -23,6 +23,7 @@ import ( "path/filepath" "strconv" "strings" + "sync" "github.com/elastic/elastic-agent-libs/logp" "github.com/elastic/elastic-agent-system-metrics/metric/system/cgroup/cgv1" @@ -68,7 +69,7 @@ const ( memoryStat = "memory" ) -//nolint: deadcode,structcheck,unused // needed by other platforms +// nolint: deadcode,structcheck,unused // needed by other platforms type mount struct { subsystem string // Subsystem name (e.g. cpuacct). mountpoint string // Mountpoint of the subsystem (e.g. /cgroup/cpuacct). @@ -85,6 +86,9 @@ type Reader struct { ignoreRootCgroups bool // Ignore a cgroup when its path is "/". cgroupsHierarchyOverride string cgroupMountpoints Mountpoints // Mountpoints for each subsystem (e.g. cpu, cpuacct, memory, blkio). + + // Cache to map known v2 cgroup controllerPaths to PathList. + v2ControllerPathCache sync.Map } // ReaderOptions holds options for NewReaderOptions. diff --git a/metric/system/cgroup/util.go b/metric/system/cgroup/util.go index e84cafbbfa..601b6910cf 100644 --- a/metric/system/cgroup/util.go +++ b/metric/system/cgroup/util.go @@ -256,6 +256,7 @@ func (r Reader) ProcessCgroupPaths(pid int) (PathList, error) { if r.cgroupsHierarchyOverride != "" { path = r.cgroupsHierarchyOverride } + // cgroup V2 // cgroup v2 controllers will always start with this string if strings.Contains(line, "0::/") { @@ -276,6 +277,14 @@ the container as /sys/fs/cgroup/unified and start the system module with the hos controllerPath = r.rootfsMountpoint.ResolveHostFS(filepath.Join("/sys/fs/cgroup/unified", path)) } + if tmp, ok := r.v2ControllerPathCache.Load(controllerPath); ok { + pathList, ok := tmp.(PathList) + if ok { + cPaths.V2 = pathList.V2 + continue + } + } + cgpaths, err := ioutil.ReadDir(controllerPath) if err != nil { return cPaths, fmt.Errorf("error fetching cgroupV2 controllers for cgroup location '%s' and path line '%s': %w", r.cgroupMountpoints.V2Loc, line, err) @@ -288,6 +297,7 @@ the container as /sys/fs/cgroup/unified and start the system module with the hos cPaths.V2[controllerName] = ControllerPath{ControllerPath: path, FullPath: controllerPath, IsV2: true} } } + r.v2ControllerPathCache.Store(controllerPath, cPaths) // cgroup v1 } else { subsystems := strings.Split(fields[1], ",")