opencontainers / opencontainers/runc

Joining cgroups blindly causes performance problems

Open
#861 22 comments 0 reactions 0 assignees View on GitHub

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.