Skip to content

Commit

Permalink
Bug Fix: SystemCPUfreq fails when any core is offline
Browse files Browse the repository at this point in the history
Signed-off-by: taherk <tkkathana@gmail.com>
  • Loading branch information
taherkk authored and discordianfish committed Mar 20, 2023
1 parent 80824fa commit f930a52
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 7 deletions.
74 changes: 68 additions & 6 deletions sysfs/system_cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,49 @@ func parseCPUThermalThrottle(cpuPath string) (*CPUThermalThrottle, error) {
return &t, nil
}

func binSearch(elem uint16, elemSlice *[]uint16) bool {
if len(*elemSlice) == 0 {
return false
}

if len(*elemSlice) == 1 {
return elem == (*elemSlice)[0]
}

start := 0
end := len(*elemSlice) - 1

var mid int

for start <= end {
mid = (start + end) / 2
if (*elemSlice)[mid] == elem {
return true
} else if (*elemSlice)[mid] > elem {
end = mid - 1
} else if (*elemSlice)[mid] < elem {
start = mid + 1
}
}

return false
}

func filterOfflineCPUs(offlineCpus *[]uint16, cpus *[]string) error {
for i, cpu := range *cpus {
cpuName := strings.TrimPrefix(filepath.Base(cpu), "cpu")
cpuNameUint16, err := strconv.Atoi(cpuName)
if err != nil {
return err
}
if binSearch(uint16(cpuNameUint16), offlineCpus) {
*cpus = append((*cpus)[:i], (*cpus)[i+1:]...)
}
}

return nil
}

// SystemCpufreq returns CPU frequency metrics for all CPUs.
func (fs FS) SystemCpufreq() ([]SystemCPUCpufreqStats, error) {
var g errgroup.Group
Expand All @@ -151,6 +194,25 @@ func (fs FS) SystemCpufreq() ([]SystemCPUCpufreqStats, error) {
return nil, err
}

line, err := util.ReadFileNoStat(fs.sys.Path("devices/system/cpu/offline"))
if err != nil {
return nil, err
}

if strings.TrimSpace(string(line)) != "" {
offlineCPUs, err := parseCPURange(line)
if err != nil {
return nil, err
}

if len(offlineCPUs) > 0 {
err = filterOfflineCPUs(&offlineCPUs, &cpus)
if err != nil {
return nil, err
}
}
}

systemCpufreq := make([]SystemCPUCpufreqStats, len(cpus))
for i, cpu := range cpus {
cpuName := strings.TrimPrefix(filepath.Base(cpu), "cpu")
Expand Down Expand Up @@ -251,12 +313,12 @@ func (fs FS) IsolatedCPUs() ([]uint16, error) {
return nil, err
}

return parseIsolatedCPUs(isolcpus)
return parseCPURange(isolcpus)
}

func parseIsolatedCPUs(data []byte) ([]uint16, error) {
func parseCPURange(data []byte) ([]uint16, error) {

var isolcpusInt = []uint16{}
var cpusInt = []uint16{}

for _, cpu := range strings.Split(strings.TrimRight(string(data), "\n"), ",") {
if cpu == "" {
Expand All @@ -277,7 +339,7 @@ func parseIsolatedCPUs(data []byte) ([]uint16, error) {
}

for i := startRange; i <= endRange; i++ {
isolcpusInt = append(isolcpusInt, uint16(i))
cpusInt = append(cpusInt, uint16(i))
}
continue
}
Expand All @@ -286,7 +348,7 @@ func parseIsolatedCPUs(data []byte) ([]uint16, error) {
if err != nil {
return nil, err
}
isolcpusInt = append(isolcpusInt, uint16(cpuN))
cpusInt = append(cpusInt, uint16(cpuN))
}
return isolcpusInt, nil
return cpusInt, nil
}
23 changes: 22 additions & 1 deletion sysfs/system_cpu_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ func TestIsolatedParsingCPU(t *testing.T) {
}
for _, params := range testParams {
t.Run("blabla", func(t *testing.T) {
res, err := parseIsolatedCPUs(params.in)
res, err := parseCPURange(params.in)
if !reflect.DeepEqual(res, params.res) {
t.Fatalf("should have %v result: got %v", params.res, res)
}
Expand Down Expand Up @@ -193,3 +193,24 @@ func TestIsolatedCPUs(t *testing.T) {
t.Errorf("Error not correct: want %v, have %v", nil, err)
}
}

func TestBinSearch(t *testing.T) {
var testParams = []struct {
elem uint16
elems []uint16
res bool
}{
{3, []uint16{1, 3, 5, 7, 9}, true},
{4, []uint16{1, 3, 5, 7, 9}, false},
{2, []uint16{}, false},
}

for _, param := range testParams {
res := binSearch(param.elem, &param.elems)

if res != param.res {
t.Fatalf("Result not correct: want %v, have %v", param.res, res)
}

}
}
5 changes: 5 additions & 0 deletions testdata/fixtures.ttar
Original file line number Diff line number Diff line change
Expand Up @@ -12729,6 +12729,11 @@ Lines: 1
1,2-7,9
Mode: 664
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/sys/devices/system/cpu/offline
Lines: 1
2,12-15
Mode: 664
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/sys/devices/system/node
Mode: 775
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Expand Down

0 comments on commit f930a52

Please sign in to comment.