Skip to content

Commit 1b59b51

Browse files
committed
Add memory policy support
1 parent 0ea5ed0 commit 1b59b51

File tree

10 files changed

+233
-35
lines changed

10 files changed

+233
-35
lines changed

cmd/oci-runtime-tool/generate.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import (
1616
"github.com/opencontainers/runtime-tools/generate"
1717
"github.com/opencontainers/runtime-tools/generate/seccomp"
1818
"github.com/urfave/cli"
19+
20+
mpolCheck "github.com/opencontainers/runtime-tools/validate/memorypolicy"
1921
)
2022

2123
var generateFlags = []cli.Flag{
@@ -64,6 +66,9 @@ var generateFlags = []cli.Flag{
6466
cli.StringFlag{Name: "linux-mems", Usage: "list of memory nodes in the cpuset (default is to use any available memory node)"},
6567
cli.Uint64Flag{Name: "linux-mem-swap", Usage: "total memory limit (memory + swap) (in bytes)"},
6668
cli.Uint64Flag{Name: "linux-mem-swappiness", Usage: "how aggressive the kernel will swap memory pages (Range from 0 to 100)"},
69+
cli.StringFlag{Name: "linux-memorypolicy-mode", Usage: "memory policy defines from which nodes memory is allocated by default, e.g MPOL_INTERLEAVE"},
70+
cli.StringFlag{Name: "linux-memorypolicy-nodes", Usage: "memory nodes related to the linux-memorypolicy-mode, e.g 0-3,7"},
71+
cli.StringSliceFlag{Name: "linux-memorypolicy-flags", Usage: "optional memory policy mode flags, e.g MPOL_F_STATIC_NODES"},
6772
cli.StringFlag{Name: "linux-mount-label", Usage: "selinux mount context label"},
6873
cli.StringSliceFlag{Name: "linux-namespace-add", Usage: "adds a namespace to the set of namespaces to create or join of the form 'ns[:path]'"},
6974
cli.StringSliceFlag{Name: "linux-namespace-remove", Usage: "removes a namespace from the set of namespaces to create or join of the form 'ns'"},
@@ -782,6 +787,28 @@ func setupSpec(g *generate.Generator, context *cli.Context) error {
782787
g.SetLinuxResourcesMemorySwappiness(context.Uint64("linux-mem-swappiness"))
783788
}
784789

790+
if context.IsSet("linux-memorypolicy-mode") {
791+
mpolMode := context.String("linux-memorypolicy-mode")
792+
if err := mpolCheck.MpolModeValid(mpolMode); err != nil {
793+
return err
794+
}
795+
g.SetLinuxMemoryPolicyMode(mpolMode)
796+
}
797+
798+
if context.IsSet("linux-memorypolicy-nodes") {
799+
g.SetLinuxMemoryPolicyNodes(context.String("linux-memorypolicy-nodes"))
800+
}
801+
802+
if context.IsSet("linux-memorypolicy-flags") {
803+
mpolFlags := context.StringSlice("linux-memorypolicy-flags")
804+
for _, flag := range mpolFlags {
805+
if err := mpolCheck.MpolFlagValid(flag); err != nil {
806+
return err
807+
}
808+
}
809+
g.SetLinuxMemoryPolicyFlags(mpolFlags)
810+
}
811+
785812
if context.IsSet("linux-network-classid") {
786813
g.SetLinuxResourcesNetworkClassID(uint32(context.Int("linux-network-classid")))
787814
}

generate/config.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,13 @@ func (g *Generator) initConfigLinuxResourcesMemory() {
109109
}
110110
}
111111

112+
func (g *Generator) initConfigLinuxMemoryPolicy() {
113+
g.initConfigLinux()
114+
if g.Config.Linux.MemoryPolicy == nil {
115+
g.Config.Linux.MemoryPolicy = &rspec.LinuxMemoryPolicy{}
116+
}
117+
}
118+
112119
func (g *Generator) initConfigLinuxResourcesNetwork() {
113120
g.initConfigLinuxResources()
114121
if g.Config.Linux.Resources.Network == nil {

generate/generate.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,26 @@ func (g *Generator) SetLinuxResourcesMemorySwappiness(swappiness uint64) {
926926
g.Config.Linux.Resources.Memory.Swappiness = &swappiness
927927
}
928928

929+
// SetLinuxMemoryPolicyMode sets g.Config.Linux.MemoryPolicy.Mode
930+
func (g *Generator) SetLinuxMemoryPolicyMode(mode string) {
931+
g.initConfigLinuxMemoryPolicy()
932+
g.Config.Linux.MemoryPolicy.Mode = rspec.MemoryPolicyModeType(mode)
933+
}
934+
935+
// SetLinuxMemoryPolicyNodes sets g.Config.Linux.MemoryPolicy.Nodes
936+
func (g *Generator) SetLinuxMemoryPolicyNodes(nodes string) {
937+
g.initConfigLinuxMemoryPolicy()
938+
g.Config.Linux.MemoryPolicy.Nodes = nodes
939+
}
940+
941+
// SetLinuxMemoryPolicyFlags sets g.Config.Linux.MemoryPolicy.Flags
942+
func (g *Generator) SetLinuxMemoryPolicyFlags(flags []string) {
943+
g.initConfigLinuxMemoryPolicy()
944+
for _, flag := range flags {
945+
g.Config.Linux.MemoryPolicy.Flags = append(g.Config.Linux.MemoryPolicy.Flags, rspec.MemoryPolicyFlagType(flag))
946+
}
947+
}
948+
929949
// SetLinuxResourcesMemoryDisableOOMKiller sets g.Config.Linux.Resources.Memory.DisableOOMKiller.
930950
func (g *Generator) SetLinuxResourcesMemoryDisableOOMKiller(disable bool) {
931951
g.initConfigLinuxResourcesMemory()

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ require (
1010
github.com/moby/sys/capability v0.4.0
1111
github.com/moby/sys/mountinfo v0.7.2
1212
github.com/mrunalp/fileutils v0.5.0
13-
github.com/opencontainers/runtime-spec v1.1.0
13+
github.com/opencontainers/runtime-spec v1.2.2-0.20250804081626-bfdffd548aa6
1414
github.com/opencontainers/selinux v1.9.1
1515
github.com/sirupsen/logrus v1.8.1
1616
github.com/stretchr/testify v1.3.0

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l
1111
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
1212
github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b h1:Ga1nclDSe8gOw37MVLMhfu2QKWtD6gvtQ298zsKVh8g=
1313
github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs=
14-
github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
15-
github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4=
1614
github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk=
1715
github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I=
16+
github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
17+
github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4=
1818
github.com/mrunalp/fileutils v0.5.0 h1:NKzVxiH7eSk+OQ4M+ZYW1K6h27RUV3MI6NUTsHhU6Z4=
1919
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
20-
github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg=
21-
github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
20+
github.com/opencontainers/runtime-spec v1.2.2-0.20250804081626-bfdffd548aa6 h1:6S6r1L8VO9b1UfgIQi+nteqlElma9KDlzZw/nM3ctI0=
21+
github.com/opencontainers/runtime-spec v1.2.2-0.20250804081626-bfdffd548aa6/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
2222
github.com/opencontainers/selinux v1.9.1 h1:b4VPEF3O5JLZgdTDBmGepaaIbAo0GqoF6EBRq5f/g3Y=
2323
github.com/opencontainers/selinux v1.9.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
2424
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=

validate/memorypolicy/validate.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package memorypolicy
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
rspec "github.com/opencontainers/runtime-spec/specs-go"
8+
)
9+
10+
var (
11+
knownModes map[rspec.MemoryPolicyModeType]struct{} = map[rspec.MemoryPolicyModeType]struct{}{
12+
rspec.MpolDefault: {},
13+
rspec.MpolBind: {},
14+
rspec.MpolInterleave: {},
15+
rspec.MpolWeightedInterleave: {},
16+
rspec.MpolPreferred: {},
17+
rspec.MpolPreferredMany: {},
18+
rspec.MpolLocal: {},
19+
}
20+
21+
knownModeFlags map[rspec.MemoryPolicyFlagType]struct{} = map[rspec.MemoryPolicyFlagType]struct{}{
22+
rspec.MpolFNumaBalancing: {},
23+
rspec.MpolFRelativeNodes: {},
24+
rspec.MpolFStaticNodes: {},
25+
}
26+
)
27+
28+
func MpolModeValid(mode string) error {
29+
if !strings.HasPrefix(mode, "MPOL_") {
30+
return fmt.Errorf("memory policy mode %q must start with 'MPOL_'", mode)
31+
}
32+
if _, ok := knownModes[rspec.MemoryPolicyModeType(mode)]; !ok {
33+
return fmt.Errorf("invalid memory policy mode %q", mode)
34+
}
35+
return nil
36+
}
37+
38+
func MpolFlagValid(flag string) error {
39+
if !strings.HasPrefix(flag, "MPOL_F_") {
40+
return fmt.Errorf("memory policy flag %q must start with 'MPOL_F_'", flag)
41+
}
42+
if _, ok := knownModeFlags[rspec.MemoryPolicyFlagType(flag)]; !ok {
43+
return fmt.Errorf("invalid memory policy flag %q", flag)
44+
}
45+
return nil
46+
}

validate/validate_linux.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
rspec "github.com/opencontainers/runtime-spec/specs-go"
1616
osFilepath "github.com/opencontainers/runtime-tools/filepath"
1717
"github.com/opencontainers/runtime-tools/specerror"
18+
mpolCheck "github.com/opencontainers/runtime-tools/validate/memorypolicy"
1819
"github.com/opencontainers/selinux/go-selinux/label"
1920
"github.com/sirupsen/logrus"
2021
)
@@ -221,5 +222,16 @@ func (v *Validator) CheckLinux() (errs error) {
221222
}
222223
}
223224

225+
if v.spec.Linux.MemoryPolicy != nil {
226+
if err := mpolCheck.MpolModeValid(string(v.spec.Linux.MemoryPolicy.Mode)); err != nil {
227+
errs = multierror.Append(errs, err)
228+
}
229+
for _, flag := range v.spec.Linux.MemoryPolicy.Flags {
230+
if err := mpolCheck.MpolFlagValid(string(flag)); err != nil {
231+
errs = multierror.Append(errs, err)
232+
}
233+
}
234+
}
235+
224236
return
225237
}

0 commit comments

Comments
 (0)