Skip to content

Commit

Permalink
common api: support memory.stat
Browse files Browse the repository at this point in the history
Signed-off-by: Robin Lu <[email protected]>
  • Loading branch information
lubinszARM committed Jul 12, 2024
1 parent 3f551e7 commit 20d207f
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 0 deletions.
6 changes: 6 additions & 0 deletions pkg/util/cgroup/common/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,12 @@ type MemoryStats struct {
Usage uint64
}

// MemoryDetailedStats get detailed cgroup memory data
type MemoryDetailedStats struct {
File uint64
FileInactive uint64
}

// CPUStats get cgroup cpu data
type CPUStats struct {
CpuPeriod uint64
Expand Down
4 changes: 4 additions & 0 deletions pkg/util/cgroup/manager/cgroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ func GetMemoryWithAbsolutePath(absCgroupPath string) (*common.MemoryStats, error
return GetManager().GetMemory(absCgroupPath)
}

func GetDetailedMemoryWithAbsolutePath(absCgroupPath string) (*common.MemoryDetailedStats, error) {
return GetManager().GetDetailedMemory(absCgroupPath)
}

func GetIOCostQoSWithRelativePath(relCgroupPath string) (map[string]*common.IOCostQoSData, error) {
absCgroupPath := common.GetAbsCgroupPath(common.CgroupSubsysIO, relCgroupPath)
return GetIOCostQoSWithAbsolutePath(absCgroupPath)
Expand Down
1 change: 1 addition & 0 deletions pkg/util/cgroup/manager/cgroup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func testManager(t *testing.T, version string) {

_, _ = GetMemoryWithRelativePath("/")
_, _ = GetMemoryWithAbsolutePath("/")
_, _ = GetDetailedMemoryWithAbsolutePath("/")
_, _ = GetCPUWithRelativePath("/")
_, _ = GetMetricsWithRelativePath("/", map[string]struct{}{"cpu": {}})
_, _ = GetPidsWithRelativePath("/")
Expand Down
4 changes: 4 additions & 0 deletions pkg/util/cgroup/manager/fake_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ func (f *FakeCgroupManager) GetNumaMemory(absCgroupPath string) (map[int]*common
return nil, nil
}

func (f *FakeCgroupManager) GetDetailedMemory(absCgroupPath string) (*common.MemoryDetailedStats, error) {
return nil, nil
}

func (f *FakeCgroupManager) GetCPU(absCgroupPath string) (*common.CPUStats, error) {
return nil, nil
}
Expand Down
1 change: 1 addition & 0 deletions pkg/util/cgroup/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type Manager interface {

GetMemory(absCgroupPath string) (*common.MemoryStats, error)
GetNumaMemory(absCgroupPath string) (map[int]*common.MemoryNumaMetrics, error)
GetDetailedMemory(absCgroupPath string) (*common.MemoryDetailedStats, error)
GetCPU(absCgroupPath string) (*common.CPUStats, error)
GetCPUSet(absCgroupPath string) (*common.CPUSetStats, error)
GetIOCostQoS(absCgroupPath string) (map[string]*common.IOCostQoSData, error)
Expand Down
44 changes: 44 additions & 0 deletions pkg/util/cgroup/manager/v1/fs_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package v1
import (
"errors"
"fmt"
"io/ioutil"
"path"
"path/filepath"
"strconv"
Expand Down Expand Up @@ -217,6 +218,36 @@ func (m *manager) ApplyUnifiedData(absCgroupPath, cgroupFileName, data string) e
return nil
}

func GetMemoryStatsFromStatFile(absCgroupPath string) (uint64, uint64, error) {
statFile := filepath.Join(absCgroupPath, "memory.stat")
content, err := ioutil.ReadFile(statFile)
if err != nil {
return 0, 0, fmt.Errorf("failed to read %s: %v", statFile, err)
}

var cache, fileInactive uint64
lines := strings.Split(string(content), "\n")
for _, line := range lines {
fields := strings.Fields(line)
if len(fields) < 2 {
continue
}
key := fields[0]
value, err := strconv.ParseUint(fields[1], 10, 64)
if err != nil {
return 0, 0, fmt.Errorf("failed to parse value in %s: %v", statFile, err)
}
switch key {
case "cache":
cache = value
case "total_inactive_file":
fileInactive = value
}
}

return cache, fileInactive, nil
}

func (m *manager) GetMemory(absCgroupPath string) (*common.MemoryStats, error) {
memoryStats := &common.MemoryStats{}
moduleName := "memory"
Expand All @@ -238,6 +269,19 @@ func (m *manager) GetMemory(absCgroupPath string) (*common.MemoryStats, error) {
return memoryStats, nil
}

func (m *manager) GetDetailedMemory(absCgroupPath string) (*common.MemoryDetailedStats, error) {
memoryStats := &common.MemoryDetailedStats{}

cache, fileInactive, err := GetMemoryStatsFromStatFile(absCgroupPath)
if err != nil {
return nil, err
}
memoryStats.File = cache
memoryStats.FileInactive = fileInactive

return memoryStats, nil
}

func (m *manager) GetNumaMemory(absCgroupPath string) (map[int]*common.MemoryNumaMetrics, error) {
numaStat, err := common.ParseCgroupNumaValue(absCgroupPath, "memory.numa_stat")
if err != nil {
Expand Down
46 changes: 46 additions & 0 deletions pkg/util/cgroup/manager/v1/fs_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,49 @@ func Test_manager_ApplyMemory(t *testing.T) {
})
}
}

func Test_manager_GetDetailedMemory(t *testing.T) {
t.Parallel()

type args struct {
absCgroupPath string
}
tests := []struct {
name string
m *manager
args args
want *common.MemoryDetailedStats
wantErr bool
}{
{
name: "test get memory",
m: NewManager(),
args: args{
absCgroupPath: "test-fake-path",
},
want: nil,
wantErr: true,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
m := &manager{}
got, err := m.GetDetailedMemory(tt.args.absCgroupPath)
if (err != nil) != tt.wantErr {
t.Errorf("manager.GetMemory() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("manager.GetMemory() = %v, want %v", got, tt.want)
}

_, _, err = GetMemoryStatsFromStatFile(tt.args.absCgroupPath)
if (err != nil) != tt.wantErr {
t.Errorf("GetMemoryStatsFromStatFile() error = %v, wantErr %v", err, tt.wantErr)
return
}
})
}
}
43 changes: 43 additions & 0 deletions pkg/util/cgroup/manager/v2/fs_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,49 @@ func (m *manager) GetMemory(absCgroupPath string) (*common.MemoryStats, error) {
return memoryStats, nil
}

func GetMemoryStatsFromStatFile(absCgroupPath string) (uint64, uint64, error) {
statFile := filepath.Join(absCgroupPath, "memory.stat")
content, err := ioutil.ReadFile(statFile)
if err != nil {
return 0, 0, fmt.Errorf("failed to read %s: %v", statFile, err)
}

var cache, fileInactive uint64
lines := strings.Split(string(content), "\n")
for _, line := range lines {
fields := strings.Fields(line)
if len(fields) < 2 {
continue
}
key := fields[0]
value, err := strconv.ParseUint(fields[1], 10, 64)
if err != nil {
return 0, 0, fmt.Errorf("failed to parse value in %s: %v", statFile, err)
}
switch key {
case "file":
cache = value
case "inactive_file":
fileInactive = value
}
}

return cache, fileInactive, nil
}

func (m *manager) GetDetailedMemory(absCgroupPath string) (*common.MemoryDetailedStats, error) {
memoryStats := &common.MemoryDetailedStats{}

cache, fileInactive, err := GetMemoryStatsFromStatFile(absCgroupPath)
if err != nil {
return nil, err
}
memoryStats.File = cache
memoryStats.FileInactive = fileInactive

return memoryStats, nil
}

func (m *manager) GetNumaMemory(absCgroupPath string) (map[int]*common.MemoryNumaMetrics, error) {
numaStat, err := common.ParseCgroupNumaValue(absCgroupPath, "memory.numa_stat")
general.Infof("get cgroup %+v numa stat %+v", absCgroupPath, numaStat)
Expand Down
46 changes: 46 additions & 0 deletions pkg/util/cgroup/manager/v2/fs_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -949,3 +949,49 @@ func Test_parseDeviceIOCostModel(t *testing.T) {
})
}
}

func Test_manager_GetDetailedMemory(t *testing.T) {
t.Parallel()

type args struct {
absCgroupPath string
}
tests := []struct {
name string
m *manager
args args
want *common.MemoryDetailedStats
wantErr bool
}{
{
name: "test get memory",
m: NewManager(),
args: args{
absCgroupPath: "test-fake-path",
},
want: nil,
wantErr: true,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
m := &manager{}
got, err := m.GetDetailedMemory(tt.args.absCgroupPath)
if (err != nil) != tt.wantErr {
t.Errorf("manager.GetMemory() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("manager.GetMemory() = %v, want %v", got, tt.want)
}

_, _, err = GetMemoryStatsFromStatFile(tt.args.absCgroupPath)
if (err != nil) != tt.wantErr {
t.Errorf("GetMemoryStatsFromStatFile() error = %v, wantErr %v", err, tt.wantErr)
return
}
})
}
}

0 comments on commit 20d207f

Please sign in to comment.