From 2549545df5ae003e3fdc1d3b662d7730f66f70aa Mon Sep 17 00:00:00 2001 From: Xiaochen Shen Date: Wed, 20 Sep 2017 00:13:29 +0800 Subject: [PATCH 1/2] intelrdt: always init IntelRdtManager if Intel RDT is enabled In current implementation: Either Intel RDT is not enabled by hardware and kernel, or intelRdt is not specified in original config, we don't init IntelRdtManager in the container to handle intelrdt constraint. It is a tradeoff that Intel RDT has hardware limitation to support only limited number of groups. This patch makes a minor change to support update command: Whether or not intelRdt is specified in config, we always init IntelRdtManager in the container if Intel RDT is enabled. If intelRdt is not specified in original config, we just don't Apply() to create intelrdt group or attach tasks for this container. In update command, we could re-enable through IntelRdtManager.Apply() and then update intelrdt constraint. Signed-off-by: Xiaochen Shen --- libcontainer/factory_linux.go | 6 ++---- libcontainer/intelrdt/intelrdt.go | 4 ++++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libcontainer/factory_linux.go b/libcontainer/factory_linux.go index 89deb96e..83aeb8f1 100644 --- a/libcontainer/factory_linux.go +++ b/libcontainer/factory_linux.go @@ -213,8 +213,7 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err newgidmapPath: l.NewgidmapPath, cgroupManager: l.NewCgroupsManager(config.Cgroups, nil), } - c.intelRdtManager = nil - if intelrdt.IsEnabled() && c.config.IntelRdt != nil { + if intelrdt.IsEnabled() { c.intelRdtManager = l.NewIntelRdtManager(config, id, "") } c.state = &stoppedState{c: c} @@ -256,8 +255,7 @@ func (l *LinuxFactory) Load(id string) (Container, error) { if err := c.refreshState(); err != nil { return nil, err } - c.intelRdtManager = nil - if intelrdt.IsEnabled() && c.config.IntelRdt != nil { + if intelrdt.IsEnabled() { c.intelRdtManager = l.NewIntelRdtManager(&state.Config, id, state.IntelRdtPath) } return c, nil diff --git a/libcontainer/intelrdt/intelrdt.go b/libcontainer/intelrdt/intelrdt.go index 667625a1..ebb68f94 100644 --- a/libcontainer/intelrdt/intelrdt.go +++ b/libcontainer/intelrdt/intelrdt.go @@ -401,6 +401,10 @@ func GetIntelRdtPath(id string) (string, error) { // Applies Intel RDT configuration to the process with the specified pid func (m *IntelRdtManager) Apply(pid int) (err error) { + // If intelRdt is not specified in config, we do nothing + if m.Config.IntelRdt == nil { + return nil + } d, err := getIntelRdtData(m.Config, pid) if err != nil && !IsNotFound(err) { return err From 65918b02a9c30a8017ad3fa9ec7369ed7c66463e Mon Sep 17 00:00:00 2001 From: Xiaochen Shen Date: Wed, 20 Sep 2017 01:33:35 +0800 Subject: [PATCH 2/2] intelrdt: add update command support Add runc update command support for Intel RDT/CAT. for example: runc update --l3-cache-schema "L3:0=f;1=f" Signed-off-by: Xiaochen Shen --- update.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/update.go b/update.go index 133be999..9bb6b610 100644 --- a/update.go +++ b/update.go @@ -9,6 +9,8 @@ import ( "strconv" "github.com/docker/go-units" + "github.com/opencontainers/runc/libcontainer/configs" + "github.com/opencontainers/runc/libcontainer/intelrdt" "github.com/opencontainers/runtime-spec/specs-go" "github.com/urfave/cli" ) @@ -112,6 +114,10 @@ other options are ignored. Name: "pids-limit", Usage: "Maximum number of pids allowed in the container", }, + cli.StringFlag{ + Name: "l3-cache-schema", + Usage: "The string of Intel RDT/CAT L3 cache schema", + }, }, Action: func(context *cli.Context) error { if err := checkArgs(context, 1, exactArgs); err != nil { @@ -254,6 +260,34 @@ other options are ignored. config.Cgroups.Resources.MemorySwap = *r.Memory.Swap config.Cgroups.Resources.PidsLimit = r.Pids.Limit + // Update Intel RDT/CAT + if val := context.String("l3-cache-schema"); val != "" { + if !intelrdt.IsEnabled() { + return fmt.Errorf("Intel RDT: l3 cache schema is not enabled") + } + + // If intelRdt is not specified in original configuration, we just don't + // Apply() to create intelRdt group or attach tasks for this container. + // In update command, we could re-enable through IntelRdtManager.Apply() + // and then update intelrdt constraint. + if config.IntelRdt == nil { + state, err := container.State() + if err != nil { + return err + } + config.IntelRdt = &configs.IntelRdt{} + intelRdtManager := intelrdt.IntelRdtManager{ + Config: &config, + Id: container.ID(), + Path: state.IntelRdtPath, + } + if err := intelRdtManager.Apply(state.InitProcessPid); err != nil { + return err + } + } + config.IntelRdt.L3CacheSchema = val + } + return container.Set(config) }, }