Skip to content

Commit

Permalink
fix(perf) skip to process nil ring
Browse files Browse the repository at this point in the history
Signed-off-by: zhuhuijun <zhuhuijunzhj@gmail.com>
  • Loading branch information
Ghostbaby committed Jul 8, 2024
1 parent f2b2f6d commit 92b7a1c
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 4 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

.idea
59 changes: 56 additions & 3 deletions cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,34 @@ package ebpf
import (
"fmt"
"os"
"strconv"
"strings"
"sync"
)

var possibleCPU = sync.OnceValues(func() (int, error) {
return parseCPUsFromFile("/sys/devices/system/cpu/possible")
return parseCPUsFromFile("/sys/devices/system/cpu/possible", parseCPUs)
})

var onlineCPU = sync.OnceValues(func() (int, error) {
return parseCPUsFromFile("/sys/devices/system/cpu/online", parseOnlineCPUs)
})

// parseCPUsFromFile reads the content of a file and parses the number of CPUs
type parseCPUsHandler func(string) (int, error)

// PossibleCPU returns the max number of CPUs a system may possibly have
// Logical CPU numbers must be of the form 0-n
func PossibleCPU() (int, error) {
return possibleCPU()
}

// OnlineCPU returns the number of CPUs currently online
// Logical CPU numbers must be of the form 0-n,n+2,(n+3)-(n+6)
func OnlineCPU() (int, error) {
return onlineCPU()
}

// MustPossibleCPU is a helper that wraps a call to PossibleCPU and panics if
// the error is non-nil.
func MustPossibleCPU() int {
Expand All @@ -27,13 +41,13 @@ func MustPossibleCPU() int {
return cpus
}

func parseCPUsFromFile(path string) (int, error) {
func parseCPUsFromFile(path string, parse parseCPUsHandler) (int, error) {
spec, err := os.ReadFile(path)
if err != nil {
return 0, err
}

n, err := parseCPUs(string(spec))
n, err := parse(string(spec))
if err != nil {
return 0, fmt.Errorf("can't parse %s: %v", path, err)
}
Expand Down Expand Up @@ -64,3 +78,42 @@ func parseCPUs(spec string) (int, error) {
// cpus is 0 indexed
return high + 1, nil
}

// OnlineCPU returns the number of CPUs currently online
func parseOnlineCPUs(spec string) (int, error) {
// trim leading and trailing spaces
spec = strings.TrimSpace(spec)
if spec == "" {
return 0, fmt.Errorf("spec cannot be empty")
}

// split the string by comma
ranges := strings.Split(spec, ",")
totalCPUs := 0
for _, r := range ranges {
// skip empty ranges
if len(r) == 0 {
continue
}

// check if it's a single number
if !strings.Contains(r, "-") {
_, err := strconv.Atoi(r)
if err != nil {
return 0, fmt.Errorf("invalid CPU number '%s': %v", r, err)
}
totalCPUs++
continue
}

// check if it's a range
var low, high int
n, err := fmt.Sscanf(r, "%d-%d", &low, &high)
if n != 2 || err != nil || high < low {
return 0, fmt.Errorf("invalid range format: '%s'", r)
}
totalCPUs += high - low + 1
}

return totalCPUs, nil
}
105 changes: 105 additions & 0 deletions cpu_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,108 @@ func TestParseCPUs(t *testing.T) {
}
}
}

func Test_parseCPUsPlus(t *testing.T) {
type args struct {
spec string
}
tests := []struct {
name string
args args
want int
wantErr bool
}{
{
name: "null",
args: args{
spec: "",
},
want: 0,
wantErr: true,
},
{
name: "\n",
args: args{
spec: "\n",
},
want: 0,
wantErr: true,
},
{
name: "1,",
args: args{
spec: "1,",
},
want: 1,
wantErr: false,
},
{
name: "0",
args: args{
spec: "0",
},
want: 1,
wantErr: false,
},
{
name: "0-",
args: args{
spec: "0-",
},
want: 0,
wantErr: true,
},
{
name: "0-1",
args: args{
spec: "0-1",
},
want: 2,
wantErr: false,
},
{
name: "0-1\n",
args: args{
spec: "0-1\n",
},
want: 2,
wantErr: false,
},
{
name: "0-15",
args: args{
spec: "0-15",
},
want: 16,
wantErr: false,
},
{
name: "0-6,8-9,11,13-15",
args: args{
spec: "0-6,8-9,11,13-15",
},
want: 13,
wantErr: false,
},
{
name: "0-6,8-,11,13-15",
args: args{
spec: "0-6,8-,11,13-15",
},
want: 0,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := parseOnlineCPUs(tt.args.spec)
if (err != nil) != tt.wantErr {
t.Errorf("parseCPUs() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("parseCPUs() got = %v, want %v", got, tt.want)
}
})
}
}
2 changes: 1 addition & 1 deletion map.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func (spec *MapSpec) fixupMagicFields() (*MapSpec, error) {
spec.KeySize = 4
spec.ValueSize = 4

n, err := PossibleCPU()
n, err := OnlineCPU()
if err != nil {
return nil, fmt.Errorf("fixup perf event array: %w", err)
}
Expand Down

0 comments on commit 92b7a1c

Please sign in to comment.