Skip to content

Commit

Permalink
Merge pull request #3377 from wineway/main
Browse files Browse the repository at this point in the history
libct/cg: support SCHED_IDLE for runc cgroupfs
  • Loading branch information
kolyshkin committed Feb 1, 2023
2 parents 8c5d3f0 + 81c379f commit 32d7413
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 2 deletions.
1 change: 1 addition & 0 deletions contrib/completions/bash/runc
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,7 @@ _runc_update() {
--pids-limit
--l3-cache-schema
--mem-bw-schema
--cpu-idle
"

case "$prev" in
Expand Down
8 changes: 8 additions & 0 deletions libcontainer/cgroups/fs/cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ func (s *CpuGroup) Set(path string, r *configs.Resources) error {
}
}
}

if r.CPUIdle != nil {
idle := strconv.FormatInt(*r.CPUIdle, 10)
if err := cgroups.WriteFile(path, "cpu.idle", idle); err != nil {
return err
}
}

return s.SetRtSched(path, r)
}

Expand Down
8 changes: 7 additions & 1 deletion libcontainer/cgroups/fs2/cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,20 @@ import (
)

func isCpuSet(r *configs.Resources) bool {
return r.CpuWeight != 0 || r.CpuQuota != 0 || r.CpuPeriod != 0
return r.CpuWeight != 0 || r.CpuQuota != 0 || r.CpuPeriod != 0 || r.CPUIdle != nil
}

func setCpu(dirPath string, r *configs.Resources) error {
if !isCpuSet(r) {
return nil
}

if r.CPUIdle != nil {
if err := cgroups.WriteFile(dirPath, "cpu.idle", strconv.FormatInt(*r.CPUIdle, 10)); err != nil {
return err
}
}

// NOTE: .CpuShares is not used here. Conversion is the caller's responsibility.
if r.CpuWeight != 0 {
if err := cgroups.WriteFile(dirPath, "cpu.weight", strconv.FormatUint(r.CpuWeight, 10)); err != nil {
Expand Down
3 changes: 3 additions & 0 deletions libcontainer/configs/cgroup_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ type Resources struct {
// MEM to use
CpusetMems string `json:"cpuset_mems"`

// cgroup SCHED_IDLE
CPUIdle *int64 `json:"cpu_idle,omitempty"`

// Process limit; set <= `0' to disable limit.
PidsLimit int64 `json:"pids_limit"`

Expand Down
1 change: 1 addition & 0 deletions libcontainer/specconv/spec_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,7 @@ func CreateCgroupConfig(opts *CreateOpts, defaultDevs []*devices.Device) (*confi
}
c.Resources.CpusetCpus = r.CPU.Cpus
c.Resources.CpusetMems = r.CPU.Mems
c.Resources.CPUIdle = r.CPU.Idle
}
if r.Pids != nil {
c.Resources.PidsLimit = r.Pids.Limit
Expand Down
12 changes: 12 additions & 0 deletions tests/integration/cgroups.bats
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,18 @@ function setup() {
[[ "$weights" == *"$major:$minor 444"* ]]
}

@test "runc run (cpu.idle)" {
requires cgroups_cpu_idle
[ $EUID -ne 0 ] && requires rootless_cgroup

set_cgroups_path
update_config '.linux.resources.cpu.idle = 1'

runc run -d --console-socket "$CONSOLE_SOCKET" test_cgroups_unified
[ "$status" -eq 0 ]
check_cgroup_value "cpu.idle" "1"
}

@test "runc run (cgroup v2 resources.unified only)" {
requires root cgroups_v2

Expand Down
9 changes: 9 additions & 0 deletions tests/integration/helpers.bash
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,15 @@ function requires() {
skip_me=1
fi
;;
cgroups_cpu_idle)
local p
init_cgroup_paths
[ -v CGROUP_V1 ] && p="$CGROUP_CPU_BASE_PATH"
[ -v CGROUP_V2 ] && p="$CGROUP_BASE_PATH"
if [ -z "$(find "$p" -name cpu.idle -print -quit)" ]; then
skip_me=1
fi
;;
cgroupns)
if [ ! -e "/proc/self/ns/cgroup" ]; then
skip_me=1
Expand Down
35 changes: 35 additions & 0 deletions tests/integration/update.bats
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,41 @@ EOF
check_cpu_quota 3000 10000 "300ms"
}

@test "update cgroup cpu.idle" {
requires cgroups_cpu_idle
[ $EUID -ne 0 ] && requires rootless_cgroup

runc run -d --console-socket "$CONSOLE_SOCKET" test_update
[ "$status" -eq 0 ]

check_cgroup_value "cpu.idle" "0"

local val
for val in 1 0 1; do
runc update -r - test_update <<EOF
{
"cpu": {
"idle": $val
}
}
EOF
[ "$status" -eq 0 ]
check_cgroup_value "cpu.idle" "$val"
done

for val in 1 0 1; do
runc update --cpu-idle "$val" test_update

[ "$status" -eq 0 ]
check_cgroup_value "cpu.idle" "$val"
done

# test update other option won't impact on cpu.idle
runc update --cpu-period 10000 test_update
[ "$status" -eq 0 ]
check_cgroup_value "cpu.idle" "1"
}

@test "update cgroup v2 resources via unified map" {
[ $EUID -ne 0 ] && requires rootless_cgroup
requires cgroups_v2
Expand Down
15 changes: 14 additions & 1 deletion update.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ The accepted format is as follow (unchanged values can be omitted):
"realtimeRuntime": 0,
"realtimePeriod": 0,
"cpus": "",
"mems": ""
"mems": "",
"idle": 0
},
"blockIO": {
"weight": 0
Expand Down Expand Up @@ -106,6 +107,10 @@ other options are ignored.
Name: "memory",
Usage: "Memory limit (in bytes)",
},
cli.StringFlag{
Name: "cpu-idle",
Usage: "set cgroup SCHED_IDLE or not, 0: default behavior, 1: SCHED_IDLE",
},
cli.StringFlag{
Name: "memory-reservation",
Usage: "Memory reservation or soft_limit (in bytes)",
Expand Down Expand Up @@ -192,6 +197,13 @@ other options are ignored.
if val := context.String("cpuset-mems"); val != "" {
r.CPU.Mems = val
}
if val := context.String("cpu-idle"); val != "" {
idle, err := strconv.ParseInt(val, 10, 64)
if err != nil {
return fmt.Errorf("invalid value for cpu-idle: %w", err)
}
r.CPU.Idle = i64Ptr(idle)
}

for _, pair := range []struct {
opt string
Expand Down Expand Up @@ -294,6 +306,7 @@ other options are ignored.
config.Cgroups.Resources.CpusetCpus = r.CPU.Cpus
config.Cgroups.Resources.CpusetMems = r.CPU.Mems
config.Cgroups.Resources.Memory = *r.Memory.Limit
config.Cgroups.Resources.CPUIdle = r.CPU.Idle
config.Cgroups.Resources.MemoryReservation = *r.Memory.Reservation
config.Cgroups.Resources.MemorySwap = *r.Memory.Swap
config.Cgroups.Resources.MemoryCheckBeforeUpdate = *r.Memory.CheckBeforeUpdate
Expand Down

0 comments on commit 32d7413

Please sign in to comment.