Skip to content

cgroup1: support stats collection for selected subsystems - #403

Open
linrl3 wants to merge 3 commits into
containerd:mainfrom
linrl3:cgroup1-stat-filter
Open

linrl3 wants to merge 3 commits into
containerd:mainfrom
linrl3:cgroup1-stat-filter

Conversation

@linrl3

@linrl3 linrl3 commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

cgroup v1 stats collection visits every loaded subsystem, even when a caller only needs CPU and memory metrics. In particular, blkio opens /proc/partitions on every collection, contributing to the contention reported in #370.

Add Cgroup.StatFiltered(subsystems, handlers...) to skip unselected subsystems before path resolution or I/O. It reuses the existing collection and error-handling logic; an empty list preserves full collection. CPU throttling and usage remain separately selectable through Cpu and Cpuacct.

Expose the method directly on the Cgroup interface. Existing Stat behavior is preserved by delegating to StatFiltered(nil, handlers...). Custom implementations of Cgroup must also provide the new method. Existing callers must opt into StatFiltered to benefit.

Tests cover selected metrics, skipped blkio I/O and path lookups, duplicate/inactive names, error handlers, loaded/child/deleted cgroups. A fixture-based benchmark compares full collection with CPU and memory subsets.

Fixes #370.

Validation of the interface revision on Linux arm64 with Go 1.22.12:

  • go test -exec sudo -race -count=1 -timeout=5m ./... passed.
  • golangci-lint v2.6.2 run -D errcheck passed with 0 issues, matching the CI linter configuration.
  • Linux amd64 cross-builds of the library and cgctl, and Linux arm64 go vet ./..., passed on the macOS host.

The Linux guest runs cgroup v2; the new v1 tests exercise real controller parsers against regular-file fixtures, without requiring a live v1 mount. All filtered-stats tests passed. Five existing environment-dependent tests were skipped (TestBlkioStat, TestSelfPath, TestPidPath, TestSystemd240, and TestCgroupv2IOController).

Previously recorded fixture benchmark: `go test ./cgroup1 -run '^

Selection ns/op B/op allocs/op
All 76,597 50,890 359
CPU 19,898 11,328 53
Memory 58,678 22,540 227
CPU + memory 59,988 33,311 271

These fixture results show reduced work when controllers are excluded; they do not measure kernel /proc/partitions contention or end-to-end CRI performance.

AI assistance: implementation, tests, and documentation were developed with OpenAI Codex.

-bench '^BenchmarkStatFiltered

Selection ns/op B/op allocs/op
All 76,597 50,890 359
CPU 19,898 11,328 53
Memory 58,678 22,540 227
CPU + memory 59,988 33,311 271

These fixture results show reduced work when controllers are excluded; they do not measure kernel /proc/partitions contention or end-to-end CRI performance.

AI assistance: implementation, tests, and documentation were developed with OpenAI Codex.

-benchmem -count=3` (median of three runs, 2 vCPUs):

Selection ns/op B/op allocs/op
All 76,597 50,890 359
CPU 19,898 11,328 53
Memory 58,678 22,540 227
CPU + memory 59,988 33,311 271

These fixture results show reduced work when controllers are excluded; they do not measure kernel /proc/partitions contention or end-to-end CRI performance.

AI assistance: implementation, tests, and documentation were developed with OpenAI Codex.

Allow callers that only need CPU and memory metrics to skip other
controllers, including blkio and its reads of /proc/partitions.

Expose a package-level StatFiltered helper backed by an optional method
on the concrete cgroup. This preserves the existing Cgroup interface and
Stat behavior while allowing third-party implementations to opt in.
Retain the existing error handlers and metrics initialization, and treat
an empty filter as full collection, consistent with Add's filtering.

Add regression tests for skipped I/O and path resolution, CPU controller
selection, error handling and cgroup lifecycle behavior, plus a benchmark
using regular-file fixtures.

Fixes containerd#370

Assisted-by: OpenAI Codex
Signed-off-by: linrunlong <linrunlong@bytedance.com>
The cgroup v1 jobs fail while installing vagrant-libvirt because
fog-json 1.5.0 requires json >= 2.19, but Vagrant has already activated
its bundled json 2.7.2. The VM never starts and no tests run.

Pin fog-json to 1.2.0 before installing vagrant-libvirt, replacing any
previously registered version restored from the Vagrant cache. This
follows the fix used in containerd/containerd commit
b84460e50769d336bf62dca976eb23f984f7d10b.

Assisted-by: Codex
Signed-off-by: linrunlong <linrunlong@bytedance.com>
@linrl3

linrl3 commented Oct 24, 2026

Copy link
Copy Markdown
Contributor Author

@fuweid Could you check the ci issue and take a look at the pr?

@fuweid fuweid self-assigned this Oct 24, 2026
@AkihiroSuda

Copy link
Copy Markdown
Member

The support for cgroup v1 has been deprecated.
Could you tell us why you still use v1?

The Linux guest runs cgroup v2; the new v1 tests exercise real controller parsers against regular-file fixtures, without requiring a live v1 mount.

Why not run the tests on your cgroup v1 environment?

@linrl3

linrl3 commented Oct 30, 2026

Copy link
Copy Markdown
Contributor Author

The support for cgroup v1 has been deprecated. Could you tell us why you still use v1?

The Linux guest runs cgroup v2; the new v1 tests exercise real controller parsers against regular-file fixtures, without requiring a live v1 mount.

Why not run the tests on your cgroup v1 environment?

Some legacy os on my side are still v1 cgroup. I have already run the test in my environment.

Comment thread cgroup1/stat.go Outdated
//
// If c does not implement that method, StatFiltered returns an error wrapping
// errors.ErrUnsupported.
func StatFiltered(c Cgroup, subsystems []Name, handlers ...ErrorHandler) (*v1.Metrics, error) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you please add this function as part of interface? it could be easier.

@linrl3 linrl3 Nov 5, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 8b365cf.

Add StatFiltered directly to Cgroup so callers can select subsystems through the public interface. Remove the package helper and optional-interface dispatch, and update the tests, benchmark, and README to use the method.

Assisted-by: Codex
Signed-off-by: linrunlong <linrunlong@bytedance.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

support filter subsystem on cgroup.Stat() function

3 participants