opencontainers / opencontainers/runc
Joining cgroups blindly causes performance problems
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 13.5k
- Forks
- 2.3k
- Avg merge
- 2d 8h
- Merged PRs (30d)
- 30
Description
It turns out that joining cgroups that we don't use has a non-zero performance degredation. The most obvious case is with blkio which can cause operations to become 10 times slower. The following test assumes you have some block device /dev/sdX that is formatted as ext4 (this used a spinning hard drive, but you could also use a flash usb):
# mount /dev/sdX /workspace
# echo $$ > /sys/fs/cgroup/blkio/cgroup.procs
# time dd if=/dev/zero of=/workspace/test.bin bs=512 count=1000 oflag=dsync
1000+0 records in
1000+0 records out
512000 bytes (512 kB) copied, 2.09553 s, 244 kB/s
real 0m2.097s
user 0m0.000s
sys 0m0.144s
# mkdir /sys/fs/cgroup/blkio/test
# echo $$ >/sys/fs/cgroup/blkio/test/cgroup.procs
# time dd if=/dev/zero of=/workspace/test.bin bs=512 count=1000 oflag=dsync
1000+0 records in
1000+0 records out
512000 bytes (512 kB) copied, 19.5512 s, 26.2 kB/s
real 0m19.553s
user 0m0.000s
sys 0m0.132s
This is already a known issue upstream (in the kernel), but it is a general problem (most cgroup controllers have special cases for their root cgroup to maximise performance -- but few have optimisations to reduce the hierarchy based on which cgroups have limits set).
Unfortunately, the naive solution (not joining cgroups if we don't intend to use them in config.json) causes obvious issues with runc update (and commands that make assumptions about which cgroups we've joined). So we'd have to write quite a bit of code to create new cgroups and join container processes to them if the user requests a limit that wasn't required before. We could do it with the freezer cgroup and some enumeration.
This is (somewhat) related to the lazy cgroup work that we should do as a part of #774.
The performance issue described in docker/docker#21485 occurs because of this.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Review the existing cgroup-joining behavior and the assumptions made by runc update, then compare the proposed lazy cgroup work in #774 with the controller behavior described here. Done would require avoiding unnecessary controller hierarchies without breaking runc update or later limit requests, but the issue does not identify specific files or tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, linux
- Domain
- cli, operating-systems
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 28/100