diff --git a/README.md b/README.md index 7eacd0b..bd874fd 100644 --- a/README.md +++ b/README.md @@ -183,8 +183,9 @@ type Environment interface { ## Kernel Versions +- 6.1: `pids.peak` in cgroup v2 - 5.19: `memory.peak` in cgroup v2 -- 4.15: cgroup v2 +- 4.15: cgroup v2 (also need support in the Linux distribution) - 4.14: SECCOMP_RET_KILL_PROCESS - 4.6: CLONE_NEWCGROUP - 3.19: execveat() diff --git a/cmd/runprog/main_linux.go b/cmd/runprog/main_linux.go index 3bbc8c0..e5b5978 100644 --- a/cmd/runprog/main_linux.go +++ b/cmd/runprog/main_linux.go @@ -417,7 +417,11 @@ func start() (*runner.Result, error) { if err != nil && !errors.Is(err, os.ErrNotExist) { return nil, fmt.Errorf("cgroup memory: %v", err) } - debug("cgroup: cpu: ", cpu, " memory: ", memory) + procPeak, err := cg.ProcessPeak() + if err != nil && !errors.Is(err, os.ErrNotExist) { + return nil, fmt.Errorf("cgroup pid: %v", err) + } + debug("cgroup: cpu: ", cpu, " memory: ", memory, " procPeak: ", procPeak) rt.Time = time.Duration(cpu) if memory > 0 { rt.Memory = runner.Size(memory) diff --git a/pkg/cgroup/cgroup_linux.go b/pkg/cgroup/cgroup_linux.go index 864e3c6..11c5df1 100644 --- a/pkg/cgroup/cgroup_linux.go +++ b/pkg/cgroup/cgroup_linux.go @@ -33,6 +33,9 @@ type Cgroup interface { // MemoryMaxUsageInBytes reads max total memory usage. Not exist in cgroup v2 with kernel version < 5.19 MemoryMaxUsage() (uint64, error) + // ProcessPeak reads maximum number of process ever existed in cgroup. Not exist in cgroup v1 or kernel < 6.1 + ProcessPeak() (uint64, error) + // SetCPUBandwidth sets the cpu bandwidth. Times in ns SetCPUBandwidth(quota, period uint64) error diff --git a/pkg/cgroup/v1_linux.go b/pkg/cgroup/v1_linux.go index 80c7393..8364f98 100644 --- a/pkg/cgroup/v1_linux.go +++ b/pkg/cgroup/v1_linux.go @@ -181,6 +181,11 @@ func (c *V1) MemoryMaxUsage() (uint64, error) { return c.memory.ReadUint("memory.max_usage_in_bytes") } +// ProcessPeak implements Cgroup. +func (c *V1) ProcessPeak() (uint64, error) { + return 0, ErrNotInitialized +} + // SetMemoryLimit write memory.limit_in_bytes func (c *V1) SetMemoryLimit(i uint64) error { return c.memory.WriteUint("memory.limit_in_bytes", i) diff --git a/pkg/cgroup/v2_linux.go b/pkg/cgroup/v2_linux.go index 4eb37e2..d4a07c8 100644 --- a/pkg/cgroup/v2_linux.go +++ b/pkg/cgroup/v2_linux.go @@ -155,6 +155,14 @@ func (c *V2) MemoryMaxUsage() (uint64, error) { return c.ReadUint("memory.peak") } +// ProcessPeak reads pids.peak +func (c *V2) ProcessPeak() (uint64, error) { + if !c.control.Pids { + return 0, ErrNotInitialized + } + return c.ReadUint("pids.peak") +} + // SetCPUBandwidth set cpu.max quota period func (c *V2) SetCPUBandwidth(quota, period uint64) error { if !c.control.CPU {