Skip to content

Commit 33437a8

Browse files
committed
Revert "[utils] GetNumOfPossibleCpus: switch from custom, file based implementation to get_nprocs()"
This reverts commit 54e362e.
1 parent 54e362e commit 33437a8

File tree

4 files changed

+78
-18
lines changed

4 files changed

+78
-18
lines changed

itest/utils_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
)
1313

1414
func TestGetNumOfPossibleCpus(t *testing.T) {
15-
cpus := goebpf.GetNumOfPossibleCpus()
15+
cpus, err := goebpf.GetNumOfPossibleCpus()
16+
assert.NoError(t, err)
1617
assert.True(t, cpus > 0)
1718
}

map.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,11 @@ func (m *EbpfMap) Create() error {
422422

423423
// Per-CPU maps require extra space to store values from ALL possible CPUs
424424
if m.isPerCpu() {
425-
m.valueRealSize = m.ValueSize * GetNumOfPossibleCpus()
425+
numCpus, err := GetNumOfPossibleCpus()
426+
if err != nil {
427+
return err
428+
}
429+
m.valueRealSize = m.ValueSize * numCpus
426430
} else {
427431
m.valueRealSize = m.ValueSize
428432
}

utils.go

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,6 @@ package goebpf
1313
#include "bpf.h"
1414
#include "bpf_helpers.h"
1515
16-
17-
// Mac does not have "sys/sysinfo.h" header, so making dummy here
18-
#ifdef __APPLE__
19-
static int get_nprocs(void)
20-
{
21-
return 0;
22-
}
23-
#else
24-
#include "sys/sysinfo.h"
25-
#endif
26-
27-
2816
static int ebpf_obj_pin(__u32 fd, const char *pathname,
2917
void *log_buf, size_t log_size)
3018
{
@@ -117,7 +105,9 @@ import (
117105
"encoding/hex"
118106
"errors"
119107
"fmt"
108+
"io/ioutil"
120109
"net"
110+
"strconv"
121111
"strings"
122112
"sync"
123113
"time"
@@ -294,16 +284,49 @@ func closeFd(fd int) error {
294284
return nil
295285
}
296286

287+
// Helper to get number of possible system CPUs from string
288+
func parseNumOfPossibleCpus(data string) (int, error) {
289+
eInvalid := errors.New("Unable to get # of possible CPUs: invalid file format")
290+
// VM support: when machine has only one CPU input is "0"
291+
if strings.TrimSpace(data) == "0" {
292+
return 1, nil
293+
}
294+
// Otherwise input looks like:
295+
// 0-14
296+
// where 0 is first possible CPU and 14 is the last
297+
items := strings.Split(strings.TrimSpace(data), "-")
298+
if len(items) != 2 {
299+
return 0, eInvalid
300+
}
301+
first, err := strconv.Atoi(items[0])
302+
if err != nil || first != 0 {
303+
return 0, eInvalid
304+
}
305+
second, err := strconv.Atoi(items[1])
306+
if err != nil {
307+
return 0, eInvalid
308+
}
309+
310+
return second + 1, nil
311+
}
312+
297313
// GetNumOfPossibleCpus returns number of CPU available to eBPF program
298314
// NOTE: this is not the same as runtime.NumCPU()
299-
func GetNumOfPossibleCpus() int {
315+
func GetNumOfPossibleCpus() (int, error) {
316+
// Idea taken from
317+
// https://elixir.bootlin.com/linux/latest/source/tools/testing/selftests/bpf/bpf_util.h#L10
318+
// P.S. runtime.NumCPU() cannot be used since it returns number of logical CPUs
319+
var err error
300320

301-
// Do syscall only once
302321
getPossibleCpusOnce.Do(func() {
303-
numPossibleCpus = int(C.get_nprocs())
322+
var data []byte
323+
data, err = ioutil.ReadFile("/sys/devices/system/cpu/possible")
324+
if err == nil {
325+
numPossibleCpus, err = parseNumOfPossibleCpus(string(data))
326+
}
304327
})
305328

306-
return numPossibleCpus
329+
return numPossibleCpus, err
307330
}
308331

309332
// ParseFlexibleIntegerLittleEndian converts flexible amount of bytes

utils_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,38 @@ import (
99
"github.com/stretchr/testify/assert"
1010
)
1111

12+
func TestParseNumOfPossibleCpus(t *testing.T) {
13+
runs := map[string]int{
14+
"0": 1,
15+
"0-0": 1,
16+
"0-1": 2,
17+
"0-14": 15,
18+
"0-1\r\n": 2,
19+
}
20+
21+
for str, numExpected := range runs {
22+
num, err := parseNumOfPossibleCpus(str)
23+
assert.NoError(t, err)
24+
assert.Equal(t, numExpected, num)
25+
}
26+
27+
// Negative runs
28+
runsNegative := []string{
29+
"",
30+
"1",
31+
"1-1",
32+
"1-",
33+
"-1",
34+
"\r\n",
35+
}
36+
37+
for _, str := range runsNegative {
38+
num, err := parseNumOfPossibleCpus(str)
39+
assert.Error(t, err)
40+
assert.Equal(t, 0, num)
41+
}
42+
}
43+
1244
// Negative test for closeFd()
1345
func TestCloseFd(t *testing.T) {
1446
err := closeFd(1111) // Some non-existing fd

0 commit comments

Comments
 (0)