@@ -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
172175const (
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
176184var (
@@ -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
552571func (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
586615func (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
594636func (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
754824func (raw * intelRdtData ) join (id string ) (string , error ) {
0 commit comments