2021-11-04 08:14:51 +00:00
|
|
|
/*
|
|
|
|
Copyright 2021 The Kubernetes Authors.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package utils
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"testing"
|
|
|
|
|
2022-10-14 12:28:52 +00:00
|
|
|
corev1 "k8s.io/api/core/v1"
|
2021-11-04 08:14:51 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
HugepageSize2Mi = 2048
|
|
|
|
HugepageSize1Gi = 1048576
|
|
|
|
)
|
|
|
|
|
|
|
|
const testMeminfo = `Node 0 MemTotal: 32718644 kB
|
|
|
|
Node 0 MemFree: 2915988 kB
|
|
|
|
Node 0 MemUsed: 29802656 kB
|
|
|
|
Node 0 Active: 19631832 kB
|
|
|
|
Node 0 Inactive: 8089096 kB
|
|
|
|
Node 0 Active(anon): 10104396 kB
|
|
|
|
Node 0 Inactive(anon): 511432 kB
|
|
|
|
Node 0 Active(file): 9527436 kB
|
|
|
|
Node 0 Inactive(file): 7577664 kB
|
|
|
|
Node 0 Unevictable: 637864 kB
|
|
|
|
Node 0 Mlocked: 0 kB
|
|
|
|
Node 0 Dirty: 1140 kB
|
|
|
|
Node 0 Writeback: 0 kB
|
|
|
|
Node 0 FilePages: 18206092 kB
|
|
|
|
Node 0 Mapped: 2000244 kB
|
|
|
|
Node 0 AnonPages: 10152780 kB
|
|
|
|
Node 0 Shmem: 1249348 kB
|
|
|
|
Node 0 KernelStack: 37440 kB
|
|
|
|
Node 0 PageTables: 110460 kB
|
|
|
|
Node 0 NFS_Unstable: 0 kB
|
|
|
|
Node 0 Bounce: 0 kB
|
|
|
|
Node 0 WritebackTmp: 0 kB
|
|
|
|
Node 0 KReclaimable: 843624 kB
|
|
|
|
Node 0 Slab: 1198060 kB
|
|
|
|
Node 0 SReclaimable: 843624 kB
|
|
|
|
Node 0 SUnreclaim: 354436 kB
|
|
|
|
Node 0 AnonHugePages: 26624 kB
|
|
|
|
Node 0 ShmemHugePages: 0 kB
|
|
|
|
Node 0 ShmemPmdMapped: 0 kB
|
|
|
|
Node 0 FileHugePages: 0 kB
|
|
|
|
Node 0 FilePmdMapped: 0 kB
|
|
|
|
Node 0 HugePages_Total: 0
|
|
|
|
Node 0 HugePages_Free: 0
|
|
|
|
Node 0 HugePages_Surp: 0`
|
|
|
|
|
|
|
|
func TestGetMemoryResourceCounters(t *testing.T) {
|
|
|
|
rootDir, err := os.MkdirTemp("", "fakehp")
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("failed to create temporary directory: %v", err)
|
|
|
|
}
|
|
|
|
defer os.RemoveAll(rootDir) // clean up
|
|
|
|
|
|
|
|
sysBusNodeBasepath = rootDir
|
|
|
|
|
|
|
|
// set mock hugepages
|
|
|
|
if err := makeHugepagesTree(rootDir, 2); err != nil {
|
|
|
|
t.Errorf("failed to setup the fake tree on %q: %v", rootDir, err)
|
|
|
|
}
|
|
|
|
if err := setHPCount(rootDir, 0, HugepageSize2Mi, 6); err != nil {
|
|
|
|
t.Errorf("failed to setup hugepages on node %d the fake tree on %q: %v", 0, rootDir, err)
|
|
|
|
}
|
|
|
|
if err := setHPCount(rootDir, 1, HugepageSize2Mi, 8); err != nil {
|
|
|
|
t.Errorf("failed to setup hugepages on node %d the fake tree on %q: %v", 0, rootDir, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// set mock memory
|
|
|
|
if err := makeMemoryTree(rootDir, 2); err != nil {
|
|
|
|
t.Errorf("failed to setup the fake tree on %q: %v", rootDir, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
memoryCounters, err := GetNumaMemoryResources()
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("unexpected error: %v", err)
|
|
|
|
}
|
|
|
|
if memoryCounters[0]["hugepages-2Mi"] != 12582912 {
|
|
|
|
t.Errorf("found unexpected amount of 2Mi hugepages under the NUMA node 0: %d", memoryCounters[0]["hugepages-2Mi"])
|
|
|
|
}
|
|
|
|
if memoryCounters[1]["hugepages-2Mi"] != 16777216 {
|
|
|
|
t.Errorf("found unexpected amount of 2Mi hugepages under the NUMA node 1: %d", memoryCounters[1]["hugepages-2Mi"])
|
|
|
|
}
|
|
|
|
|
|
|
|
if memoryCounters[0]["hugepages-1Gi"] != 0 {
|
|
|
|
t.Errorf("found unexpected 1Gi hugepages for node 0: %v", memoryCounters[0]["hugepages-1Gi"])
|
|
|
|
}
|
|
|
|
if memoryCounters[1]["hugepages-1Gi"] != 0 {
|
|
|
|
t.Errorf("found unexpected 1Gi hugepages for node 1: %v", memoryCounters[0]["hugepages-1Gi"])
|
|
|
|
}
|
|
|
|
|
|
|
|
if memoryCounters[0]["memory"] != 32718644*1024 {
|
2022-10-14 12:28:52 +00:00
|
|
|
t.Errorf("found unexpected amount of memory under the NUMA node 0: %d", memoryCounters[0][corev1.ResourceMemory])
|
2021-11-04 08:14:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if memoryCounters[1]["memory"] != 32718644*1024 {
|
2022-10-14 12:28:52 +00:00
|
|
|
t.Errorf("found unexpected amount of memory under the NUMA node 1: %d", memoryCounters[0][corev1.ResourceMemory])
|
2021-11-04 08:14:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func makeMemoryTree(root string, numNodes int) error {
|
|
|
|
for idx := 0; idx < numNodes; idx++ {
|
|
|
|
path := filepath.Join(
|
|
|
|
root,
|
|
|
|
fmt.Sprintf("node%d", idx),
|
|
|
|
)
|
|
|
|
if err := os.MkdirAll(path, 0755); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
meminfoFile := filepath.Join(path, "meminfo")
|
|
|
|
if err := os.WriteFile(meminfoFile, []byte(testMeminfo), 0644); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func makeHugepagesTree(root string, numNodes int) error {
|
|
|
|
for idx := 0; idx < numNodes; idx++ {
|
|
|
|
for _, size := range []int{HugepageSize2Mi, HugepageSize1Gi} {
|
|
|
|
path := filepath.Join(
|
|
|
|
root,
|
|
|
|
fmt.Sprintf("node%d", idx),
|
|
|
|
"hugepages",
|
|
|
|
fmt.Sprintf("hugepages-%dkB", size),
|
|
|
|
)
|
|
|
|
if err := os.MkdirAll(path, 0755); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := setHPCount(root, idx, size, 0); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func setHPCount(root string, nodeID, pageSize, numPages int) error {
|
|
|
|
path := filepath.Join(
|
|
|
|
root,
|
|
|
|
fmt.Sprintf("node%d", nodeID),
|
|
|
|
"hugepages",
|
|
|
|
fmt.Sprintf("hugepages-%dkB", pageSize),
|
|
|
|
"nr_hugepages",
|
|
|
|
)
|
|
|
|
return os.WriteFile(path, []byte(fmt.Sprintf("%d", numPages)), 0644)
|
|
|
|
}
|