mirror of
https://github.com/opencontainers/runc.git
synced 2025-09-26 19:41:35 +08:00
Merge pull request #3377 from wineway/main
libct/cg: support SCHED_IDLE for runc cgroupfs
This commit is contained in:
@@ -743,6 +743,7 @@ _runc_update() {
|
|||||||
--pids-limit
|
--pids-limit
|
||||||
--l3-cache-schema
|
--l3-cache-schema
|
||||||
--mem-bw-schema
|
--mem-bw-schema
|
||||||
|
--cpu-idle
|
||||||
"
|
"
|
||||||
|
|
||||||
case "$prev" in
|
case "$prev" in
|
||||||
|
@@ -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)
|
return s.SetRtSched(path, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func isCpuSet(r *configs.Resources) bool {
|
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 {
|
func setCpu(dirPath string, r *configs.Resources) error {
|
||||||
@@ -19,6 +19,12 @@ func setCpu(dirPath string, r *configs.Resources) error {
|
|||||||
return nil
|
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.
|
// NOTE: .CpuShares is not used here. Conversion is the caller's responsibility.
|
||||||
if r.CpuWeight != 0 {
|
if r.CpuWeight != 0 {
|
||||||
if err := cgroups.WriteFile(dirPath, "cpu.weight", strconv.FormatUint(r.CpuWeight, 10)); err != nil {
|
if err := cgroups.WriteFile(dirPath, "cpu.weight", strconv.FormatUint(r.CpuWeight, 10)); err != nil {
|
||||||
|
@@ -84,6 +84,9 @@ type Resources struct {
|
|||||||
// MEM to use
|
// MEM to use
|
||||||
CpusetMems string `json:"cpuset_mems"`
|
CpusetMems string `json:"cpuset_mems"`
|
||||||
|
|
||||||
|
// cgroup SCHED_IDLE
|
||||||
|
CPUIdle *int64 `json:"cpu_idle,omitempty"`
|
||||||
|
|
||||||
// Process limit; set <= `0' to disable limit.
|
// Process limit; set <= `0' to disable limit.
|
||||||
PidsLimit int64 `json:"pids_limit"`
|
PidsLimit int64 `json:"pids_limit"`
|
||||||
|
|
||||||
|
@@ -748,6 +748,7 @@ func CreateCgroupConfig(opts *CreateOpts, defaultDevs []*devices.Device) (*confi
|
|||||||
}
|
}
|
||||||
c.Resources.CpusetCpus = r.CPU.Cpus
|
c.Resources.CpusetCpus = r.CPU.Cpus
|
||||||
c.Resources.CpusetMems = r.CPU.Mems
|
c.Resources.CpusetMems = r.CPU.Mems
|
||||||
|
c.Resources.CPUIdle = r.CPU.Idle
|
||||||
}
|
}
|
||||||
if r.Pids != nil {
|
if r.Pids != nil {
|
||||||
c.Resources.PidsLimit = r.Pids.Limit
|
c.Resources.PidsLimit = r.Pids.Limit
|
||||||
|
@@ -187,6 +187,18 @@ function setup() {
|
|||||||
[[ "$weights" == *"$major:$minor 444"* ]]
|
[[ "$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)" {
|
@test "runc run (cgroup v2 resources.unified only)" {
|
||||||
requires root cgroups_v2
|
requires root cgroups_v2
|
||||||
|
|
||||||
|
@@ -413,6 +413,15 @@ function requires() {
|
|||||||
skip_me=1
|
skip_me=1
|
||||||
fi
|
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)
|
cgroupns)
|
||||||
if [ ! -e "/proc/self/ns/cgroup" ]; then
|
if [ ! -e "/proc/self/ns/cgroup" ]; then
|
||||||
skip_me=1
|
skip_me=1
|
||||||
|
@@ -425,6 +425,41 @@ EOF
|
|||||||
check_cpu_quota 3000 10000 "300ms"
|
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" {
|
@test "update cgroup v2 resources via unified map" {
|
||||||
[ $EUID -ne 0 ] && requires rootless_cgroup
|
[ $EUID -ne 0 ] && requires rootless_cgroup
|
||||||
requires cgroups_v2
|
requires cgroups_v2
|
||||||
|
15
update.go
15
update.go
@@ -48,7 +48,8 @@ The accepted format is as follow (unchanged values can be omitted):
|
|||||||
"realtimeRuntime": 0,
|
"realtimeRuntime": 0,
|
||||||
"realtimePeriod": 0,
|
"realtimePeriod": 0,
|
||||||
"cpus": "",
|
"cpus": "",
|
||||||
"mems": ""
|
"mems": "",
|
||||||
|
"idle": 0
|
||||||
},
|
},
|
||||||
"blockIO": {
|
"blockIO": {
|
||||||
"weight": 0
|
"weight": 0
|
||||||
@@ -106,6 +107,10 @@ other options are ignored.
|
|||||||
Name: "memory",
|
Name: "memory",
|
||||||
Usage: "Memory limit (in bytes)",
|
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{
|
cli.StringFlag{
|
||||||
Name: "memory-reservation",
|
Name: "memory-reservation",
|
||||||
Usage: "Memory reservation or soft_limit (in bytes)",
|
Usage: "Memory reservation or soft_limit (in bytes)",
|
||||||
@@ -192,6 +197,13 @@ other options are ignored.
|
|||||||
if val := context.String("cpuset-mems"); val != "" {
|
if val := context.String("cpuset-mems"); val != "" {
|
||||||
r.CPU.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 {
|
for _, pair := range []struct {
|
||||||
opt string
|
opt string
|
||||||
@@ -294,6 +306,7 @@ other options are ignored.
|
|||||||
config.Cgroups.Resources.CpusetCpus = r.CPU.Cpus
|
config.Cgroups.Resources.CpusetCpus = r.CPU.Cpus
|
||||||
config.Cgroups.Resources.CpusetMems = r.CPU.Mems
|
config.Cgroups.Resources.CpusetMems = r.CPU.Mems
|
||||||
config.Cgroups.Resources.Memory = *r.Memory.Limit
|
config.Cgroups.Resources.Memory = *r.Memory.Limit
|
||||||
|
config.Cgroups.Resources.CPUIdle = r.CPU.Idle
|
||||||
config.Cgroups.Resources.MemoryReservation = *r.Memory.Reservation
|
config.Cgroups.Resources.MemoryReservation = *r.Memory.Reservation
|
||||||
config.Cgroups.Resources.MemorySwap = *r.Memory.Swap
|
config.Cgroups.Resources.MemorySwap = *r.Memory.Swap
|
||||||
config.Cgroups.Resources.MemoryCheckBeforeUpdate = *r.Memory.CheckBeforeUpdate
|
config.Cgroups.Resources.MemoryCheckBeforeUpdate = *r.Memory.CheckBeforeUpdate
|
||||||
|
Reference in New Issue
Block a user