Skip to content

Commit c1ab7c5

Browse files
committed
fs2: Fix statHugeTlb error when rsvd usage is present
Signed-off-by: Gavin Lam <[email protected]>
1 parent b970779 commit c1ab7c5

File tree

3 files changed

+204
-2
lines changed

3 files changed

+204
-2
lines changed

fs2/hugetlb.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,11 @@ func setHugeTlb(dirPath string, r *cgroups.Resources) error {
4343
func statHugeTlb(dirPath string, stats *cgroups.Stats) error {
4444
hugetlbStats := cgroups.HugetlbStats{}
4545
rsvd := ".rsvd"
46+
4647
for _, pagesize := range cgroups.HugePageSizes() {
48+
prefix := "hugetlb." + pagesize
4749
again:
48-
prefix := "hugetlb." + pagesize + rsvd
49-
value, err := fscommon.GetCgroupParamUint(dirPath, prefix+".current")
50+
value, err := fscommon.GetCgroupParamUint(dirPath, prefix+rsvd+".current")
5051
if err != nil {
5152
if rsvd != "" && errors.Is(err, os.ErrNotExist) {
5253
rsvd = ""

fs2/hugetlb_test.go

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
package fs2
2+
3+
import (
4+
"fmt"
5+
"strconv"
6+
"testing"
7+
8+
"github.com/opencontainers/cgroups"
9+
"github.com/opencontainers/cgroups/fscommon"
10+
)
11+
12+
const (
13+
hugetlbUsageContents = "128"
14+
hugetlbFailcnt = "max 100"
15+
)
16+
17+
const (
18+
usage = "hugetlb.%s.current"
19+
limit = "hugetlb.%s.max"
20+
failcnt = "hugetlb.%s.events"
21+
22+
rsvdUsage = "hugetlb.%s.rsvd.current"
23+
rsvdLimit = "hugetlb.%s.rsvd.max"
24+
)
25+
26+
func TestSetHugetlb(t *testing.T) {
27+
path := t.TempDir()
28+
29+
const (
30+
hugetlbBefore = 256
31+
hugetlbAfter = 512
32+
)
33+
34+
for _, pageSize := range cgroups.HugePageSizes() {
35+
writeFileContents(t, path, map[string]string{
36+
fmt.Sprintf(limit, pageSize): strconv.Itoa(hugetlbBefore),
37+
fmt.Sprintf(rsvdLimit, pageSize): strconv.Itoa(hugetlbBefore),
38+
})
39+
}
40+
41+
r := &cgroups.Resources{}
42+
for _, pageSize := range cgroups.HugePageSizes() {
43+
r.HugetlbLimit = []*cgroups.HugepageLimit{
44+
{
45+
Pagesize: pageSize,
46+
Limit: hugetlbAfter,
47+
},
48+
}
49+
if err := setHugeTlb(path, r); err != nil {
50+
t.Fatal(err)
51+
}
52+
}
53+
54+
for _, pageSize := range cgroups.HugePageSizes() {
55+
for _, template := range []string{limit, rsvdLimit} {
56+
fname := fmt.Sprintf(template, pageSize)
57+
value, err := fscommon.GetCgroupParamUint(path, fname)
58+
if err != nil {
59+
t.Fatal(err)
60+
}
61+
if value != hugetlbAfter {
62+
t.Fatalf("Set %s failed. Expected: %v, Got: %v", fname, hugetlbAfter, value)
63+
}
64+
}
65+
}
66+
}
67+
68+
func TestSetHugetlbWithNoRsvdLimit(t *testing.T) {
69+
path := t.TempDir()
70+
71+
const (
72+
hugetlbBefore = 256
73+
hugetlbAfter = 512
74+
)
75+
76+
for _, pageSize := range cgroups.HugePageSizes() {
77+
writeFileContents(t, path, map[string]string{
78+
fmt.Sprintf(limit, pageSize): strconv.Itoa(hugetlbBefore),
79+
})
80+
}
81+
82+
r := &cgroups.Resources{}
83+
for _, pageSize := range cgroups.HugePageSizes() {
84+
r.HugetlbLimit = []*cgroups.HugepageLimit{
85+
{
86+
Pagesize: pageSize,
87+
Limit: hugetlbAfter,
88+
},
89+
}
90+
if err := setHugeTlb(path, r); err != nil {
91+
t.Fatal(err)
92+
}
93+
}
94+
95+
for _, pageSize := range cgroups.HugePageSizes() {
96+
fname := fmt.Sprintf(limit, pageSize)
97+
value, err := fscommon.GetCgroupParamUint(path, fname)
98+
if err != nil {
99+
t.Fatal(err)
100+
}
101+
if value != hugetlbAfter {
102+
t.Fatalf("Set %s failed. Expected: %v, Got: %v", fname, hugetlbAfter, value)
103+
}
104+
}
105+
}
106+
107+
func TestStatHugetlb(t *testing.T) {
108+
path := t.TempDir()
109+
for _, pageSize := range cgroups.HugePageSizes() {
110+
writeFileContents(t, path, map[string]string{
111+
fmt.Sprintf(rsvdUsage, pageSize): hugetlbUsageContents,
112+
fmt.Sprintf(failcnt, pageSize): hugetlbFailcnt,
113+
})
114+
}
115+
116+
actualStats := *cgroups.NewStats()
117+
err := statHugeTlb(path, &actualStats)
118+
if err != nil {
119+
t.Fatal(err)
120+
}
121+
expectedStats := cgroups.HugetlbStats{Usage: 128, Failcnt: 100}
122+
for _, pageSize := range cgroups.HugePageSizes() {
123+
if expectedStats != actualStats.HugetlbStats[pageSize] {
124+
t.Errorf("Expected hugetlb stats: %v, actual: %v", expectedStats, actualStats.HugetlbStats[pageSize])
125+
}
126+
}
127+
}
128+
129+
func TestStatHugetlbWithNoRsvdUsage(t *testing.T) {
130+
path := t.TempDir()
131+
for _, pageSize := range cgroups.HugePageSizes() {
132+
writeFileContents(t, path, map[string]string{
133+
fmt.Sprintf(usage, pageSize): hugetlbUsageContents,
134+
fmt.Sprintf(failcnt, pageSize): hugetlbFailcnt,
135+
})
136+
}
137+
138+
actualStats := *cgroups.NewStats()
139+
err := statHugeTlb(path, &actualStats)
140+
if err != nil {
141+
t.Fatal(err)
142+
}
143+
expectedStats := cgroups.HugetlbStats{Usage: 128, Failcnt: 100}
144+
for _, pageSize := range cgroups.HugePageSizes() {
145+
if expectedStats != actualStats.HugetlbStats[pageSize] {
146+
t.Errorf("Expected hugetlb stats: %v, actual: %v", expectedStats, actualStats.HugetlbStats[pageSize])
147+
}
148+
}
149+
}
150+
151+
func TestStatHugetlbNoUsageFile(t *testing.T) {
152+
path := t.TempDir()
153+
for _, pageSize := range cgroups.HugePageSizes() {
154+
writeFileContents(t, path, map[string]string{
155+
fmt.Sprintf(failcnt, pageSize): hugetlbFailcnt,
156+
})
157+
}
158+
159+
actualStats := *cgroups.NewStats()
160+
err := statHugeTlb(path, &actualStats)
161+
if err == nil {
162+
t.Fatal("Expected failure")
163+
}
164+
}
165+
166+
func TestStatHugetlbBadUsageFile(t *testing.T) {
167+
path := t.TempDir()
168+
for _, pageSize := range cgroups.HugePageSizes() {
169+
writeFileContents(t, path, map[string]string{
170+
fmt.Sprintf(usage, pageSize): "bad",
171+
})
172+
}
173+
174+
actualStats := *cgroups.NewStats()
175+
err := statHugeTlb(path, &actualStats)
176+
if err == nil {
177+
t.Fatal("Expected failure")
178+
}
179+
}

fs2/utils_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package fs2
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"testing"
7+
8+
"github.com/opencontainers/cgroups"
9+
)
10+
11+
func init() {
12+
cgroups.TestMode = true
13+
}
14+
15+
func writeFileContents(t testing.TB, path string, fileContents map[string]string) {
16+
for file, contents := range fileContents {
17+
statPath := filepath.Join(path, file)
18+
if err := os.WriteFile(statPath, []byte(contents), 0o644); err != nil {
19+
t.Fatal(err)
20+
}
21+
}
22+
}

0 commit comments

Comments
 (0)