Skip to content

Commit 62ccdb1

Browse files
author
Paweł Szulik
committed
Add mon groups for resctrl.
Signed-off-by: Paweł Szulik <[email protected]>
1 parent f8749ba commit 62ccdb1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+18738
-95
lines changed

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ require (
1818
github.com/pkg/errors v0.9.1
1919
github.com/seccomp/libseccomp-golang v0.9.1
2020
github.com/sirupsen/logrus v1.6.0
21+
github.com/stretchr/testify v1.6.1
2122
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
2223
// NOTE: urfave/cli must be <= v1.22.1 due to a regression: https://github.com/urfave/cli/issues/1092
2324
github.com/urfave/cli v1.22.1
2425
github.com/vishvananda/netlink v1.1.0
2526
golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775
27+
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
2628
)

go.sum

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSY
1111
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
1212
github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg=
1313
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
14+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1415
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
1516
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1617
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
@@ -42,8 +43,12 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5I
4243
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
4344
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
4445
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
46+
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
47+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
4548
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
4649
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
50+
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
51+
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
4752
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 h1:b6uOv7YOFK0TYG7HtkIgExQo+2RdLuwRft63jn2HWj8=
4853
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
4954
github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
@@ -59,5 +64,10 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w
5964
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6065
golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775 h1:TC0v2RSO1u2kn1ZugjrFXkRZAEaqMN/RW+OTZkBzmLE=
6166
golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
67+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
6268
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
6369
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
70+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
71+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
72+
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
73+
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

libcontainer/intelrdt/intelrdt.go

Lines changed: 165 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212
"strings"
1313
"sync"
1414

15+
"github.com/sirupsen/logrus"
16+
1517
"github.com/opencontainers/runc/libcontainer/configs"
1618
)
1719

@@ -167,10 +169,16 @@ type IntelRdtManager struct {
167169
Config *configs.Config
168170
Id string
169171
Path string
172+
Type string
170173
}
171174

172175
const (
173-
IntelRdtTasks = "tasks"
176+
IntelRdtTasks = "tasks"
177+
MonGroupDirectoryName = "mon_groups"
178+
// Monitoring group.
179+
MON = "MON"
180+
// Control group.
181+
CTRL_MON = "CTRL_MON"
174182
)
175183

176184
var (
@@ -548,26 +556,47 @@ func GetIntelRdtPath(id string) (string, error) {
548556
return path, nil
549557
}
550558

559+
// Get the 'container_id" path in Intel RDT "monitoring group" filesystem.
560+
func GetMonGroupIntelRdtPath(id string) (string, error) {
561+
rootPath, err := getIntelRdtRoot()
562+
if err != nil {
563+
return "", err
564+
}
565+
566+
path := filepath.Join(rootPath, MonGroupDirectoryName, id)
567+
return path, nil
568+
}
569+
551570
// Applies Intel RDT configuration to the process with the specified pid
552571
func (m *IntelRdtManager) Apply(pid int) (err error) {
553-
// If intelRdt is not specified in config, we do nothing
554-
if m.Config.IntelRdt == nil {
572+
switch m.Type {
573+
case CTRL_MON:
574+
// If intelRdt is not specified in config, we do nothing
575+
if m.Config.IntelRdt == nil {
576+
return nil
577+
}
578+
rdtData, err := getIntelRdtData(m.Config, pid)
579+
if err != nil && !IsNotFound(err) {
580+
return err
581+
}
582+
583+
m.mu.Lock()
584+
defer m.mu.Unlock()
585+
path, err := rdtData.join(m.Id)
586+
if err != nil {
587+
return err
588+
}
589+
590+
m.Path = path
555591
return nil
556-
}
557-
d, err := getIntelRdtData(m.Config, pid)
558-
if err != nil && !IsNotFound(err) {
559-
return err
560-
}
561592

562-
m.mu.Lock()
563-
defer m.mu.Unlock()
564-
path, err := d.join(m.Id)
565-
if err != nil {
566-
return err
593+
case MON:
594+
m.mu.Lock()
595+
defer m.mu.Unlock()
596+
return WriteIntelRdtTasks(m.Path, pid)
567597
}
568598

569-
m.Path = path
570-
return nil
599+
return fmt.Errorf("couldn't recognize resctrl type: %v", m.Type)
571600
}
572601

573602
// Destroys the Intel RDT 'container_id' group
@@ -584,94 +613,124 @@ func (m *IntelRdtManager) Destroy() error {
584613
// Returns Intel RDT path to save in a state file and to be able to
585614
// restore the object later
586615
func (m *IntelRdtManager) GetPath() string {
616+
var err error
587617
if m.Path == "" {
588-
m.Path, _ = GetIntelRdtPath(m.Id)
618+
switch m.Type {
619+
case CTRL_MON:
620+
m.Path, err = GetIntelRdtPath(m.Id)
621+
if err != nil {
622+
logrus.Errorf("couldn't obtain Resctrl control group path for manager with id %v: %v", m.Id, err)
623+
}
624+
case MON:
625+
flattedContainerID := strings.Replace(m.Id, "/", "-", -1)
626+
m.Path, err = GetMonGroupIntelRdtPath(flattedContainerID)
627+
if err != nil {
628+
logrus.Errorf("couldn't obtain Resctrl monitoring group path for manager with id %v: %v", m.Id, err)
629+
}
630+
}
589631
}
590632
return m.Path
591633
}
592634

593635
// Returns statistics for Intel RDT
594636
func (m *IntelRdtManager) GetStats() (*Stats, error) {
595-
// If intelRdt is not specified in config
596-
if m.Config.IntelRdt == nil {
597-
return nil, nil
598-
}
599-
600637
m.mu.Lock()
601638
defer m.mu.Unlock()
602639
stats := NewStats()
603640

604-
rootPath, err := getIntelRdtRoot()
605-
if err != nil {
606-
return nil, err
607-
}
608-
// The read-only L3 cache and memory bandwidth schemata in root
609-
tmpRootStrings, err := getIntelRdtParamString(rootPath, "schemata")
610-
if err != nil {
611-
return nil, err
612-
}
613-
schemaRootStrings := strings.Split(tmpRootStrings, "\n")
614-
615-
// The L3 cache and memory bandwidth schemata in 'container_id' group
616-
containerPath := m.GetPath()
617-
tmpStrings, err := getIntelRdtParamString(containerPath, "schemata")
618-
if err != nil {
619-
return nil, err
620-
}
621-
schemaStrings := strings.Split(tmpStrings, "\n")
641+
switch m.Type {
642+
case CTRL_MON:
643+
containerPath := m.GetPath()
622644

623-
if IsCatEnabled() {
624-
// The read-only L3 cache information
625-
l3CacheInfo, err := getL3CacheInfo()
645+
err := getMonitoringStats(containerPath, stats)
626646
if err != nil {
627647
return nil, err
628648
}
629-
stats.L3CacheInfo = l3CacheInfo
630649

631-
// The read-only L3 cache schema in root
632-
for _, schemaRoot := range schemaRootStrings {
633-
if strings.Contains(schemaRoot, "L3") {
634-
stats.L3CacheSchemaRoot = strings.TrimSpace(schemaRoot)
650+
// If intelRdt is not specified in config
651+
if m.Config != nil {
652+
if m.Config.IntelRdt == nil {
653+
return nil, nil
635654
}
636-
}
637655

638-
// The L3 cache schema in 'container_id' group
639-
for _, schema := range schemaStrings {
640-
if strings.Contains(schema, "L3") {
641-
stats.L3CacheSchema = strings.TrimSpace(schema)
656+
rootPath, err := getIntelRdtRoot()
657+
if err != nil {
658+
return nil, err
642659
}
643-
}
644-
}
660+
// The read-only L3 cache and memory bandwidth schemata in root
661+
tmpRootStrings, err := getIntelRdtParamString(rootPath, "schemata")
662+
if err != nil {
663+
return nil, err
664+
}
665+
schemaRootStrings := strings.Split(tmpRootStrings, "\n")
645666

646-
if IsMbaEnabled() {
647-
// The read-only memory bandwidth information
648-
memBwInfo, err := getMemBwInfo()
649-
if err != nil {
650-
return nil, err
651-
}
652-
stats.MemBwInfo = memBwInfo
667+
// The L3 cache and memory bandwidth schemata in 'container_id' group
653668

654-
// The read-only memory bandwidth information
655-
for _, schemaRoot := range schemaRootStrings {
656-
if strings.Contains(schemaRoot, "MB") {
657-
stats.MemBwSchemaRoot = strings.TrimSpace(schemaRoot)
669+
tmpStrings, err := getIntelRdtParamString(containerPath, "schemata")
670+
if err != nil {
671+
return nil, err
658672
}
659-
}
673+
schemaStrings := strings.Split(tmpStrings, "\n")
674+
675+
if IsCatEnabled() {
676+
// The read-only L3 cache information
677+
l3CacheInfo, err := getL3CacheInfo()
678+
if err != nil {
679+
return nil, err
680+
}
681+
stats.L3CacheInfo = l3CacheInfo
660682

661-
// The memory bandwidth schema in 'container_id' group
662-
for _, schema := range schemaStrings {
663-
if strings.Contains(schema, "MB") {
664-
stats.MemBwSchema = strings.TrimSpace(schema)
683+
// The read-only L3 cache schema in root
684+
for _, schemaRoot := range schemaRootStrings {
685+
if strings.Contains(schemaRoot, "L3") {
686+
stats.L3CacheSchemaRoot = strings.TrimSpace(schemaRoot)
687+
}
688+
}
689+
690+
// The L3 cache schema in 'container_id' group
691+
for _, schema := range schemaStrings {
692+
if strings.Contains(schema, "L3") {
693+
stats.L3CacheSchema = strings.TrimSpace(schema)
694+
}
695+
}
696+
}
697+
698+
if IsMbaEnabled() {
699+
// The read-only memory bandwidth information
700+
memBwInfo, err := getMemBwInfo()
701+
if err != nil {
702+
return nil, err
703+
}
704+
stats.MemBwInfo = memBwInfo
705+
706+
// The read-only memory bandwidth information
707+
for _, schemaRoot := range schemaRootStrings {
708+
if strings.Contains(schemaRoot, "MB") {
709+
stats.MemBwSchemaRoot = strings.TrimSpace(schemaRoot)
710+
}
711+
}
712+
713+
// The memory bandwidth schema in 'container_id' group
714+
for _, schema := range schemaStrings {
715+
if strings.Contains(schema, "MB") {
716+
stats.MemBwSchema = strings.TrimSpace(schema)
717+
}
718+
}
665719
}
666720
}
667-
}
668721

669-
err = getMonitoringStats(containerPath, stats)
670-
if err != nil {
671-
return nil, err
672-
}
722+
return stats, nil
723+
724+
case MON:
725+
path := m.GetPath()
673726

674-
return stats, nil
727+
err := getMonitoringStats(path, stats)
728+
if err != nil {
729+
return nil, err
730+
}
731+
return stats, nil
732+
}
733+
return nil, fmt.Errorf("couldn't obtain stats from: %q resctrl manager of type: %q", m.Id, m.Type)
675734
}
676735

677736
// Set Intel RDT "resource control" filesystem as configured.
@@ -721,34 +780,45 @@ func (m *IntelRdtManager) Set(container *configs.Config) error {
721780
// For example, on a two-socket machine, the schema line could be
722781
// "MB:0=5000;1=7000" which means 5000 MBps memory bandwidth limit on
723782
// socket 0 and 7000 MBps memory bandwidth limit on socket 1.
724-
if container.IntelRdt != nil {
725-
path := m.GetPath()
726-
l3CacheSchema := container.IntelRdt.L3CacheSchema
727-
memBwSchema := container.IntelRdt.MemBwSchema
783+
switch m.Type {
784+
case CTRL_MON:
785+
if container.IntelRdt != nil {
786+
path := m.GetPath()
787+
l3CacheSchema := container.IntelRdt.L3CacheSchema
788+
memBwSchema := container.IntelRdt.MemBwSchema
789+
790+
// Write a single joint schema string to schemata file
791+
if l3CacheSchema != "" && memBwSchema != "" {
792+
if err := writeFile(path, "schemata", l3CacheSchema+"\n"+memBwSchema); err != nil {
793+
return NewLastCmdError(err)
794+
}
795+
}
728796

729-
// Write a single joint schema string to schemata file
730-
if l3CacheSchema != "" && memBwSchema != "" {
731-
if err := writeFile(path, "schemata", l3CacheSchema+"\n"+memBwSchema); err != nil {
732-
return NewLastCmdError(err)
797+
// Write only L3 cache schema string to schemata file
798+
if l3CacheSchema != "" && memBwSchema == "" {
799+
if err := writeFile(path, "schemata", l3CacheSchema); err != nil {
800+
return NewLastCmdError(err)
801+
}
733802
}
734-
}
735803

736-
// Write only L3 cache schema string to schemata file
737-
if l3CacheSchema != "" && memBwSchema == "" {
738-
if err := writeFile(path, "schemata", l3CacheSchema); err != nil {
739-
return NewLastCmdError(err)
804+
// Write only memory bandwidth schema string to schemata file
805+
if l3CacheSchema == "" && memBwSchema != "" {
806+
if err := writeFile(path, "schemata", memBwSchema); err != nil {
807+
return NewLastCmdError(err)
808+
}
740809
}
741810
}
742811

743-
// Write only memory bandwidth schema string to schemata file
744-
if l3CacheSchema == "" && memBwSchema != "" {
745-
if err := writeFile(path, "schemata", memBwSchema); err != nil {
746-
return NewLastCmdError(err)
747-
}
812+
case MON:
813+
if _, err := os.Stat(m.GetPath()); err == nil {
814+
return nil
815+
}
816+
if err := os.Mkdir(m.GetPath(), 0755); err != nil {
817+
return err
748818
}
749819
}
750820

751-
return nil
821+
return fmt.Errorf("couldn't set configuration for: %q resctrl manager of type: %q", m.Id, m.Type)
752822
}
753823

754824
func (raw *intelRdtData) join(id string) (string, error) {

0 commit comments

Comments
 (0)