Skip to content

Commit b3a3254

Browse files
committed
mempolicy: go interface for set_mempolicy and get_mempolicy syscalls
Signed-off-by: Antti Kervinen <[email protected]>
1 parent c8e943a commit b3a3254

File tree

1 file changed

+131
-0
lines changed

1 file changed

+131
-0
lines changed

pkg/mempolicy/mempolicy.go

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// Copyright The NRI Plugins Authors. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// mempolicy package provides low-level functions to set and get
16+
// default memory policyfor a process using the Linux kernel's
17+
// set_mempolicy and get_mempolicy syscalls.
18+
package mempolicy
19+
20+
import (
21+
"fmt"
22+
"syscall"
23+
"unsafe"
24+
)
25+
26+
const (
27+
MPOL_DEFAULT = iota
28+
MPOL_PREFERRED
29+
MPOL_BIND
30+
MPOL_INTERLEAVE
31+
MPOL_LOCAL
32+
MPOL_PREFERRED_MANY
33+
MPOL_WEIGHTED_INTERLEAVE
34+
35+
MPOL_F_STATIC_NODES uint = (1 << 15)
36+
MPOL_F_RELATIVE_NODES uint = (1 << 14)
37+
MPOL_F_NUMA_BALANCING uint = (1 << 13)
38+
39+
SYS_SET_MEMPOLICY = 238
40+
SYS_GET_MEMPOLICY = 239
41+
42+
MAX_NUMA_NODES = 1024
43+
)
44+
45+
var Modes = map[string]uint{
46+
"MPOL_DEFAULT": MPOL_DEFAULT,
47+
"MPOL_PREFERRED": MPOL_PREFERRED,
48+
"MPOL_BIND": MPOL_BIND,
49+
"MPOL_INTERLEAVE": MPOL_INTERLEAVE,
50+
"MPOL_LOCAL": MPOL_LOCAL,
51+
"MPOL_PREFERRED_MANY": MPOL_PREFERRED_MANY,
52+
"MPOL_WEIGHTED_INTERLEAVE": MPOL_WEIGHTED_INTERLEAVE,
53+
}
54+
55+
var Flags = map[string]uint{
56+
"MPOL_F_STATIC_NODES": MPOL_F_STATIC_NODES,
57+
"MPOL_F_RELATIVE_NODES": MPOL_F_RELATIVE_NODES,
58+
"MPOL_F_NUMA_BALANCING": MPOL_F_NUMA_BALANCING,
59+
}
60+
61+
var ModeNames map[uint]string
62+
63+
var FlagNames map[uint]string
64+
65+
func nodesToMask(nodes []int) ([]uint64, error) {
66+
maxNode := 0
67+
for _, node := range nodes {
68+
if node > maxNode {
69+
maxNode = node
70+
}
71+
if node < 0 {
72+
return nil, fmt.Errorf("node %d out of range", node)
73+
}
74+
}
75+
if maxNode >= MAX_NUMA_NODES {
76+
return nil, fmt.Errorf("node %d out of range", maxNode)
77+
}
78+
mask := make([]uint64, (maxNode/64)+1)
79+
for _, node := range nodes {
80+
mask[node/64] |= (1 << (node % 64))
81+
}
82+
return mask, nil
83+
}
84+
85+
func maskToNodes(mask []uint64) []int {
86+
nodes := make([]int, 0)
87+
for i := range MAX_NUMA_NODES {
88+
if (mask[i/64] & (1 << (i % 64))) != 0 {
89+
nodes = append(nodes, i)
90+
}
91+
}
92+
return nodes
93+
}
94+
95+
// SetMempolicy calls set_mempolicy syscall
96+
func SetMempolicy(mpol uint, nodes []int) error {
97+
nodeMask, err := nodesToMask(nodes)
98+
if err != nil {
99+
return err
100+
}
101+
nodeMaskPtr := unsafe.Pointer(&nodeMask[0])
102+
_, _, errno := syscall.Syscall(SYS_SET_MEMPOLICY, uintptr(mpol), uintptr(nodeMaskPtr), uintptr(len(nodeMask)*64))
103+
if errno != 0 {
104+
return syscall.Errno(errno)
105+
}
106+
return nil
107+
}
108+
109+
// GetMempolicy calls get_mempolicy syscall
110+
func GetMempolicy() (uint, []int, error) {
111+
var mpol uint
112+
maxNode := uint64(MAX_NUMA_NODES)
113+
nodeMask := make([]uint64, maxNode/64)
114+
nodeMaskPtr := unsafe.Pointer(&nodeMask[0])
115+
_, _, errno := syscall.Syscall(SYS_GET_MEMPOLICY, uintptr(unsafe.Pointer(&mpol)), uintptr(nodeMaskPtr), uintptr(maxNode))
116+
if errno != 0 {
117+
return 0, []int{}, syscall.Errno(errno)
118+
}
119+
return mpol, maskToNodes(nodeMask), nil
120+
}
121+
122+
func init() {
123+
ModeNames = make(map[uint]string)
124+
for k, v := range Modes {
125+
ModeNames[v] = k
126+
}
127+
FlagNames = make(map[uint]string)
128+
for k, v := range Flags {
129+
FlagNames[v] = k
130+
}
131+
}

0 commit comments

Comments
 (0)