Skip to content

Commit

Permalink
Merge pull request #291 from manugupt1/improve-perf
Browse files Browse the repository at this point in the history
Improve performance by for pid stats (cgroups1) re-using readuint
  • Loading branch information
kzys authored Jun 2, 2023
2 parents 0f00bce + 0895e99 commit f4638b4
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 11 deletions.
9 changes: 1 addition & 8 deletions cgroup1/pids.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"os"
"path/filepath"
"strconv"
"strings"

v1 "github.com/containerd/cgroups/v3/cgroup1/stats"
specs "github.com/opencontainers/runtime-spec/specs-go"
Expand Down Expand Up @@ -67,16 +66,10 @@ func (p *pidsController) Stat(path string, stats *v1.Metrics) error {
if err != nil {
return err
}
var max uint64
maxData, err := os.ReadFile(filepath.Join(p.Path(path), "pids.max"))
max, err := readUint(filepath.Join(p.Path(path), "pids.max"))
if err != nil {
return err
}
if maxS := strings.TrimSpace(string(maxData)); maxS != "max" {
if max, err = parseUint(maxS, 10, 64); err != nil {
return err
}
}
stats.Pids = &v1.PidsStat{
Current: current,
Limit: max,
Expand Down
47 changes: 47 additions & 0 deletions cgroup1/pids_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,50 @@ func TestPidsOverflowMax(t *testing.T) {
t.Fatal("expected not nil err")
}
}

func BenchmarkTestPids(b *testing.B) {

mock, err := newMock(b)
if err != nil {
b.Fatal(err)
}
defer func() {
if err := mock.delete(); err != nil {
b.Errorf("failed delete: %v", err)
}
}()

pids := NewPids(mock.root)
if pids == nil {
b.Fatal("pids is nil")
}
resources := specs.LinuxResources{
Pids: &specs.LinuxPids{
Limit: 10,
},
}

err = pids.Create("test", &resources)
if err != nil {
b.Fatal(err)
}

current := filepath.Join(mock.root, "pids", "test", "pids.current")
if err = os.WriteFile(
current,
[]byte(strconv.Itoa(5)),
defaultFilePerm,
); err != nil {
b.Fatal(err)
}

b.ReportAllocs()

for i := 0; i < b.N; i++ {
metrics := v1.Metrics{}
err = pids.Stat("test", &metrics)
if err != nil {
b.Fatal(err)
}
}
}
13 changes: 10 additions & 3 deletions cgroup1/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package cgroup1

import (
"bufio"
"bytes"
"fmt"
"os"
"path/filepath"
Expand Down Expand Up @@ -137,13 +138,19 @@ func readUint(path string) (uint64, error) {
}
defer f.Close()

b := make([]byte, 128) // Chose 128 as some files have leading/trailing whitespaces and alignment
// We should only need 20 bytes for the max uint64, but for a nice power of 2
// lets use 32.
b := make([]byte, 32)
n, err := f.Read(b)
if err != nil {
return 0, err
}

return parseUint(strings.TrimSpace(string(b[:n])), 10, 64)
s := string(bytes.TrimSpace(b[:n]))
if s == "max" {
// Return 0 for the max value to maintain backward compatibility.
return 0, nil
}
return parseUint(s, 10, 64)
}

func parseUint(s string, base, bitSize int) (uint64, error) {
Expand Down
19 changes: 19 additions & 0 deletions cgroup1/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package cgroup1

import (
"os"
"path/filepath"
"testing"
)

Expand All @@ -30,3 +32,20 @@ func BenchmarkReaduint64(b *testing.B) {
}
}
}

func TestReadUint(t *testing.T) {
tDir := t.TempDir()
pidsmax := filepath.Join(tDir, "pids.max")
err := os.WriteFile(pidsmax, []byte("max"), 0644)
if err != nil {
t.Fatal(err)
}
max, err := readUint(pidsmax)
if err != nil {
t.Fatal(err)
}
// test for backwards compatibility
if max != 0 {
t.Fail()
}
}

0 comments on commit f4638b4

Please sign in to comment.