Skip to content

Commit 62133e3

Browse files
authored
Merge pull request #3306 from kolyshkin/rdt-faster
Faster Intel RDT init if the feature is unavailable
2 parents 17543ed + edeb3b3 commit 62133e3

File tree

3 files changed

+33
-172
lines changed

3 files changed

+33
-172
lines changed

libcontainer/intelrdt/intelrdt.go

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ import (
55
"bytes"
66
"errors"
77
"fmt"
8-
"io"
98
"os"
109
"path/filepath"
1110
"strconv"
1211
"strings"
1312
"sync"
1413

1514
"github.com/moby/sys/mountinfo"
15+
"golang.org/x/sys/unix"
16+
1617
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
1718
"github.com/opencontainers/runc/libcontainer/configs"
1819
)
@@ -194,21 +195,21 @@ var (
194195
// For Intel RDT initialization
195196
initOnce sync.Once
196197

197-
errNotFound = errors.New("Intel RDT resctrl mount point not found")
198+
errNotFound = errors.New("Intel RDT not available")
198199
)
199200

200201
// Check if Intel RDT sub-features are enabled in featuresInit()
201202
func featuresInit() {
202203
initOnce.Do(func() {
203-
// 1. Check if hardware and kernel support Intel RDT sub-features
204-
flagsSet, err := parseCpuInfoFile("/proc/cpuinfo")
204+
// 1. Check if Intel RDT "resource control" filesystem is available.
205+
// The user guarantees to mount the filesystem.
206+
root, err := Root()
205207
if err != nil {
206208
return
207209
}
208210

209-
// 2. Check if Intel RDT "resource control" filesystem is available.
210-
// The user guarantees to mount the filesystem.
211-
root, err := Root()
211+
// 2. Check if hardware and kernel support Intel RDT sub-features.
212+
flagsSet, err := parseCpuInfoFile("/proc/cpuinfo")
212213
if err != nil {
213214
return
214215
}
@@ -250,9 +251,9 @@ func featuresInit() {
250251
})
251252
}
252253

253-
// Return the mount point path of Intel RDT "resource control" filesysem
254-
func findIntelRdtMountpointDir(f io.Reader) (string, error) {
255-
mi, err := mountinfo.GetMountsFromReader(f, func(m *mountinfo.Info) (bool, bool) {
254+
// Return the mount point path of Intel RDT "resource control" filesystem.
255+
func findIntelRdtMountpointDir() (string, error) {
256+
mi, err := mountinfo.GetMounts(func(m *mountinfo.Info) (bool, bool) {
256257
// similar to mountinfo.FSTypeFilter but stops after the first match
257258
if m.FSType == "resctrl" {
258259
return false, true // don't skip, stop
@@ -276,35 +277,30 @@ func findIntelRdtMountpointDir(f io.Reader) (string, error) {
276277

277278
// For Root() use only.
278279
var (
279-
intelRdtRoot string
280-
rootMu sync.Mutex
280+
intelRdtRoot string
281+
intelRdtRootErr error
282+
rootOnce sync.Once
281283
)
282284

283285
// Root returns the Intel RDT "resource control" filesystem mount point.
284286
func Root() (string, error) {
285-
rootMu.Lock()
286-
defer rootMu.Unlock()
287-
288-
if intelRdtRoot != "" {
289-
return intelRdtRoot, nil
290-
}
287+
rootOnce.Do(func() {
288+
// If resctrl is available, kernel creates this directory.
289+
if unix.Access("/sys/fs/resctrl", unix.F_OK) != nil {
290+
intelRdtRootErr = errNotFound
291+
return
292+
}
291293

292-
f, err := os.Open("/proc/self/mountinfo")
293-
if err != nil {
294-
return "", err
295-
}
296-
root, err := findIntelRdtMountpointDir(f)
297-
f.Close()
298-
if err != nil {
299-
return "", err
300-
}
294+
root, err := findIntelRdtMountpointDir()
295+
if err != nil {
296+
intelRdtRootErr = err
297+
return
298+
}
301299

302-
if _, err := os.Stat(root); err != nil {
303-
return "", err
304-
}
300+
intelRdtRoot = root
301+
})
305302

306-
intelRdtRoot = root
307-
return intelRdtRoot, nil
303+
return intelRdtRoot, intelRdtRootErr
308304
}
309305

310306
type cpuInfoFlags struct {
Lines changed: 0 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package intelrdt
22

33
import (
4-
"errors"
5-
"io"
64
"os"
75
"path/filepath"
86
"strings"
@@ -127,141 +125,3 @@ func TestApply(t *testing.T) {
127125
t.Fatalf("unexpected tasks file, expected '1235', got %q", pids)
128126
}
129127
}
130-
131-
const (
132-
mountinfoValid = `18 40 0:18 / /sys rw,nosuid,nodev,noexec,relatime shared:6 - sysfs sysfs rw
133-
19 40 0:3 / /proc rw,nosuid,nodev,noexec,relatime shared:5 - proc proc rw
134-
20 40 0:5 / /dev rw,nosuid shared:2 - devtmpfs devtmpfs rw,size=131927256k,nr_inodes=32981814,mode=755
135-
21 18 0:17 / /sys/kernel/security rw,nosuid,nodev,noexec,relatime shared:7 - securityfs securityfs rw
136-
22 20 0:19 / /dev/shm rw,nosuid,nodev shared:3 - tmpfs tmpfs rw
137-
23 20 0:12 / /dev/pts rw,nosuid,noexec,relatime shared:4 - devpts devpts rw,gid=5,mode=620,ptmxmode=000
138-
24 40 0:20 / /run rw,nosuid,nodev shared:22 - tmpfs tmpfs rw,mode=755
139-
25 18 0:21 / /sys/fs/cgroup ro,nosuid,nodev,noexec shared:8 - tmpfs tmpfs ro,mode=755
140-
26 25 0:22 / /sys/fs/cgroup/systemd rw,nosuid,nodev,noexec,relatime shared:9 - cgroup cgroup rw,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd
141-
27 18 0:23 / /sys/fs/pstore rw,nosuid,nodev,noexec,relatime shared:20 - pstore pstore rw
142-
28 25 0:24 / /sys/fs/cgroup/perf_event rw,nosuid,nodev,noexec,relatime shared:10 - cgroup cgroup rw,perf_event
143-
29 25 0:25 / /sys/fs/cgroup/cpu,cpuacct rw,nosuid,nodev,noexec,relatime shared:11 - cgroup cgroup rw,cpuacct,cpu
144-
30 25 0:26 / /sys/fs/cgroup/memory rw,nosuid,nodev,noexec,relatime shared:12 - cgroup cgroup rw,memory
145-
31 25 0:27 / /sys/fs/cgroup/devices rw,nosuid,nodev,noexec,relatime shared:13 - cgroup cgroup rw,devices
146-
32 25 0:28 / /sys/fs/cgroup/hugetlb rw,nosuid,nodev,noexec,relatime shared:14 - cgroup cgroup rw,hugetlb
147-
33 25 0:29 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime shared:15 - cgroup cgroup rw,blkio
148-
34 25 0:30 / /sys/fs/cgroup/pids rw,nosuid,nodev,noexec,relatime shared:16 - cgroup cgroup rw,pids
149-
35 25 0:31 / /sys/fs/cgroup/cpuset rw,nosuid,nodev,noexec,relatime shared:17 - cgroup cgroup rw,cpuset
150-
36 25 0:32 / /sys/fs/cgroup/freezer rw,nosuid,nodev,noexec,relatime shared:18 - cgroup cgroup rw,freezer
151-
37 25 0:33 / /sys/fs/cgroup/net_cls,net_prio rw,nosuid,nodev,noexec,relatime shared:19 - cgroup cgroup rw,net_prio,net_cls
152-
38 18 0:34 / /sys/kernel/config rw,relatime shared:21 - configfs configfs rw
153-
40 0 253:0 / / rw,relatime shared:1 - ext4 /dev/mapper/vvrg-vvrg rw,data=ordered
154-
16 18 0:6 / /sys/kernel/debug rw,relatime shared:23 - debugfs debugfs rw
155-
41 18 0:16 / /sys/fs/resctrl rw,relatime shared:24 - resctrl resctrl rw
156-
42 20 0:36 / /dev/hugepages rw,relatime shared:25 - hugetlbfs hugetlbfs rw
157-
43 19 0:37 / /proc/sys/fs/binfmt_misc rw,relatime shared:26 - autofs systemd-1 rw,fd=32,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=35492
158-
44 20 0:15 / /dev/mqueue rw,relatime shared:27 - mqueue mqueue rw
159-
45 40 8:1 / /boot rw,relatime shared:28 - ext4 /dev/sda1 rw,stripe=4,data=ordered
160-
46 40 253:1 / /home rw,relatime shared:29 - ext4 /dev/mapper/vvhg-vvhg rw,data=ordered
161-
47 40 0:38 / /var/lib/nfs/rpc_pipefs rw,relatime shared:30 - rpc_pipefs sunrpc rw
162-
125 24 0:20 /mesos/containers /run/mesos/containers rw,nosuid shared:22 - tmpfs tmpfs rw,mode=755
163-
123 40 253:0 /var/lib/docker/containers /var/lib/docker/containers rw,relatime - ext4 /dev/mapper/vvrg-vvrg rw,data=ordered
164-
129 40 253:0 /var/lib/docker/overlay2 /var/lib/docker/overlay2 rw,relatime - ext4 /dev/mapper/vvrg-vvrg rw,data=ordered
165-
119 24 0:39 / /run/user/1009 rw,nosuid,nodev,relatime shared:100 - tmpfs tmpfs rw,size=26387788k,mode=700,uid=1009,gid=1009`
166-
167-
mountinfoMbaSc = `18 40 0:18 / /sys rw,nosuid,nodev,noexec,relatime shared:6 - sysfs sysfs rw
168-
19 40 0:3 / /proc rw,nosuid,nodev,noexec,relatime shared:5 - proc proc rw
169-
20 40 0:5 / /dev rw,nosuid shared:2 - devtmpfs devtmpfs rw,size=131927256k,nr_inodes=32981814,mode=755
170-
21 18 0:17 / /sys/kernel/security rw,nosuid,nodev,noexec,relatime shared:7 - securityfs securityfs rw
171-
22 20 0:19 / /dev/shm rw,nosuid,nodev shared:3 - tmpfs tmpfs rw
172-
23 20 0:12 / /dev/pts rw,nosuid,noexec,relatime shared:4 - devpts devpts rw,gid=5,mode=620,ptmxmode=000
173-
24 40 0:20 / /run rw,nosuid,nodev shared:22 - tmpfs tmpfs rw,mode=755
174-
25 18 0:21 / /sys/fs/cgroup ro,nosuid,nodev,noexec shared:8 - tmpfs tmpfs ro,mode=755
175-
26 25 0:22 / /sys/fs/cgroup/systemd rw,nosuid,nodev,noexec,relatime shared:9 - cgroup cgroup rw,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd
176-
27 18 0:23 / /sys/fs/pstore rw,nosuid,nodev,noexec,relatime shared:20 - pstore pstore rw
177-
28 25 0:24 / /sys/fs/cgroup/perf_event rw,nosuid,nodev,noexec,relatime shared:10 - cgroup cgroup rw,perf_event
178-
29 25 0:25 / /sys/fs/cgroup/cpu,cpuacct rw,nosuid,nodev,noexec,relatime shared:11 - cgroup cgroup rw,cpuacct,cpu
179-
30 25 0:26 / /sys/fs/cgroup/memory rw,nosuid,nodev,noexec,relatime shared:12 - cgroup cgroup rw,memory
180-
31 25 0:27 / /sys/fs/cgroup/devices rw,nosuid,nodev,noexec,relatime shared:13 - cgroup cgroup rw,devices
181-
32 25 0:28 / /sys/fs/cgroup/hugetlb rw,nosuid,nodev,noexec,relatime shared:14 - cgroup cgroup rw,hugetlb
182-
33 25 0:29 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime shared:15 - cgroup cgroup rw,blkio
183-
34 25 0:30 / /sys/fs/cgroup/pids rw,nosuid,nodev,noexec,relatime shared:16 - cgroup cgroup rw,pids
184-
35 25 0:31 / /sys/fs/cgroup/cpuset rw,nosuid,nodev,noexec,relatime shared:17 - cgroup cgroup rw,cpuset
185-
36 25 0:32 / /sys/fs/cgroup/freezer rw,nosuid,nodev,noexec,relatime shared:18 - cgroup cgroup rw,freezer
186-
37 25 0:33 / /sys/fs/cgroup/net_cls,net_prio rw,nosuid,nodev,noexec,relatime shared:19 - cgroup cgroup rw,net_prio,net_cls
187-
38 18 0:34 / /sys/kernel/config rw,relatime shared:21 - configfs configfs rw
188-
40 0 253:0 / / rw,relatime shared:1 - ext4 /dev/mapper/vvrg-vvrg rw,data=ordered
189-
16 18 0:6 / /sys/kernel/debug rw,relatime shared:23 - debugfs debugfs rw
190-
41 18 0:16 / /sys/fs/resctrl rw,relatime shared:24 - resctrl resctrl rw,mba_MBps
191-
42 20 0:36 / /dev/hugepages rw,relatime shared:25 - hugetlbfs hugetlbfs rw
192-
43 19 0:37 / /proc/sys/fs/binfmt_misc rw,relatime shared:26 - autofs systemd-1 rw,fd=32,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=35492
193-
44 20 0:15 / /dev/mqueue rw,relatime shared:27 - mqueue mqueue rw
194-
45 40 8:1 / /boot rw,relatime shared:28 - ext4 /dev/sda1 rw,stripe=4,data=ordered
195-
46 40 253:1 / /home rw,relatime shared:29 - ext4 /dev/mapper/vvhg-vvhg rw,data=ordered
196-
47 40 0:38 / /var/lib/nfs/rpc_pipefs rw,relatime shared:30 - rpc_pipefs sunrpc rw
197-
125 24 0:20 /mesos/containers /run/mesos/containers rw,nosuid shared:22 - tmpfs tmpfs rw,mode=755
198-
123 40 253:0 /var/lib/docker/containers /var/lib/docker/containers rw,relatime - ext4 /dev/mapper/vvrg-vvrg rw,data=ordered
199-
129 40 253:0 /var/lib/docker/overlay2 /var/lib/docker/overlay2 rw,relatime - ext4 /dev/mapper/vvrg-vvrg rw,data=ordered
200-
119 24 0:39 / /run/user/1009 rw,nosuid,nodev,relatime shared:100 - tmpfs tmpfs rw,size=26387788k,mode=700,uid=1009,gid=1009`
201-
)
202-
203-
func TestFindIntelRdtMountpointDir(t *testing.T) {
204-
testCases := []struct {
205-
name string
206-
input io.Reader
207-
isNotFoundError bool
208-
isError bool
209-
mbaScEnabled bool
210-
mountpoint string
211-
}{
212-
{
213-
name: "Valid mountinfo with MBA Software Controller disabled",
214-
input: strings.NewReader(mountinfoValid),
215-
mountpoint: "/sys/fs/resctrl",
216-
},
217-
{
218-
name: "Valid mountinfo with MBA Software Controller enabled",
219-
input: strings.NewReader(mountinfoMbaSc),
220-
mbaScEnabled: true,
221-
mountpoint: "/sys/fs/resctrl",
222-
},
223-
{
224-
name: "Empty mountinfo",
225-
input: strings.NewReader(""),
226-
isNotFoundError: true,
227-
},
228-
{
229-
name: "Broken mountinfo",
230-
input: strings.NewReader("baa"),
231-
isError: true,
232-
},
233-
}
234-
235-
for _, tc := range testCases {
236-
tc := tc
237-
t.Run(tc.name, func(t *testing.T) {
238-
mbaScEnabled = false
239-
mp, err := findIntelRdtMountpointDir(tc.input)
240-
if tc.isNotFoundError {
241-
if !errors.Is(err, errNotFound) {
242-
t.Errorf("expected errNotFound error, got %+v", err)
243-
}
244-
return
245-
}
246-
if tc.isError {
247-
if err == nil {
248-
t.Error("expected error, got nil")
249-
}
250-
return
251-
}
252-
if err != nil {
253-
t.Errorf("expected nil, got %+v", err)
254-
return
255-
}
256-
// no errors, check the results
257-
if tc.mbaScEnabled != mbaScEnabled {
258-
t.Errorf("expected mbaScEnabled=%v, got %v",
259-
tc.mbaScEnabled, mbaScEnabled)
260-
}
261-
if tc.mountpoint != mp {
262-
t.Errorf("expected mountpoint=%q, got %q",
263-
tc.mountpoint, mp)
264-
}
265-
})
266-
}
267-
}

libcontainer/intelrdt/util_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ func NewIntelRdtTestUtil(t *testing.T) *intelRdtTestUtil {
2626
config := &configs.Config{
2727
IntelRdt: &configs.IntelRdt{},
2828
}
29+
30+
// Assign fake intelRtdRoot value, returned by Root().
2931
intelRdtRoot = t.TempDir()
32+
// Make sure Root() won't even try to parse mountinfo.
33+
rootOnce.Do(func() {})
34+
3035
testIntelRdtPath := filepath.Join(intelRdtRoot, "resctrl")
3136

3237
// Ensure the full mock Intel RDT "resource control" filesystem path exists

0 commit comments

Comments
 (0)