Skip to content

Commit

Permalink
return errors for profiler initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
hodgesds committed Sep 14, 2021
1 parent 23ae223 commit 3ce7e7d
Show file tree
Hide file tree
Showing 17 changed files with 150 additions and 90 deletions.
1 change: 1 addition & 0 deletions bpf.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build linux
// +build linux

package perf
Expand Down
105 changes: 63 additions & 42 deletions cache_profiler.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build linux
// +build linux

package perf
Expand Down Expand Up @@ -61,159 +62,179 @@ type cacheProfiler struct {
}

// NewCacheProfiler returns a new cache profiler.
func NewCacheProfiler(pid, cpu int, opts ...int) CacheProfiler {
func NewCacheProfiler(pid, cpu int, opts ...int) (CacheProfiler, error) {
profilers := map[int]Profiler{}

// L1 data
op := unix.PERF_COUNT_HW_CACHE_OP_READ
result := unix.PERF_COUNT_HW_CACHE_RESULT_ACCESS
l1dataReadHit, err := NewL1DataProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[L1DataReadHit] = l1dataReadHit
if err != nil {
return nil, err
}
profilers[L1DataReadHit] = l1dataReadHit

op = unix.PERF_COUNT_HW_CACHE_OP_READ
result = unix.PERF_COUNT_HW_CACHE_RESULT_MISS
l1dataReadMiss, err := NewL1DataProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[L1DataReadMiss] = l1dataReadMiss
if err != nil {
return nil, err
}
profilers[L1DataReadMiss] = l1dataReadMiss

op = unix.PERF_COUNT_HW_CACHE_OP_WRITE
result = unix.PERF_COUNT_HW_CACHE_RESULT_ACCESS
l1dataWriteHit, err := NewL1DataProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[L1DataWriteHit] = l1dataWriteHit
if err != nil {
return nil, err
}
profilers[L1DataWriteHit] = l1dataWriteHit

// L1 instruction
op = unix.PERF_COUNT_HW_CACHE_OP_READ
result = unix.PERF_COUNT_HW_CACHE_RESULT_MISS
l1InstrReadMiss, err := NewL1InstrProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[L1InstrReadMiss] = l1InstrReadMiss
if err != nil {
return nil, err
}
profilers[L1InstrReadMiss] = l1InstrReadMiss

// Last Level
op = unix.PERF_COUNT_HW_CACHE_OP_READ
result = unix.PERF_COUNT_HW_CACHE_RESULT_ACCESS
llReadHit, err := NewLLCacheProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[LLReadHit] = llReadHit
if err != nil {
return nil, err
}
profilers[LLReadHit] = llReadHit

op = unix.PERF_COUNT_HW_CACHE_OP_READ
result = unix.PERF_COUNT_HW_CACHE_RESULT_MISS
llReadMiss, err := NewLLCacheProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[LLReadMiss] = llReadMiss
if err != nil {
return nil, err
}
profilers[LLReadMiss] = llReadMiss

op = unix.PERF_COUNT_HW_CACHE_OP_WRITE
result = unix.PERF_COUNT_HW_CACHE_RESULT_ACCESS
llWriteHit, err := NewLLCacheProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[LLWriteHit] = llWriteHit
if err != nil {
return nil, err
}
profilers[LLWriteHit] = llWriteHit

op = unix.PERF_COUNT_HW_CACHE_OP_WRITE
result = unix.PERF_COUNT_HW_CACHE_RESULT_MISS
llWriteMiss, err := NewLLCacheProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[LLWriteMiss] = llWriteMiss
if err != nil {
return nil, err
}
profilers[LLWriteMiss] = llWriteMiss

// dTLB
op = unix.PERF_COUNT_HW_CACHE_OP_READ
result = unix.PERF_COUNT_HW_CACHE_RESULT_ACCESS
dTLBReadHit, err := NewDataTLBProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[DataTLBReadHit] = dTLBReadHit
if err != nil {
return nil, err
}
profilers[DataTLBReadHit] = dTLBReadHit

op = unix.PERF_COUNT_HW_CACHE_OP_READ
result = unix.PERF_COUNT_HW_CACHE_RESULT_MISS
dTLBReadMiss, err := NewDataTLBProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[DataTLBReadMiss] = dTLBReadMiss
if err != nil {
return nil, err
}
profilers[DataTLBReadMiss] = dTLBReadMiss

op = unix.PERF_COUNT_HW_CACHE_OP_WRITE
result = unix.PERF_COUNT_HW_CACHE_RESULT_ACCESS
dTLBWriteHit, err := NewDataTLBProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[DataTLBWriteHit] = dTLBWriteHit
if err != nil {
return nil, err
}
profilers[DataTLBWriteHit] = dTLBWriteHit

op = unix.PERF_COUNT_HW_CACHE_OP_WRITE
result = unix.PERF_COUNT_HW_CACHE_RESULT_MISS
dTLBWriteMiss, err := NewDataTLBProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[DataTLBWriteMiss] = dTLBWriteMiss
if err != nil {
return nil, err
}
profilers[DataTLBWriteMiss] = dTLBWriteMiss

// iTLB
op = unix.PERF_COUNT_HW_CACHE_OP_READ
result = unix.PERF_COUNT_HW_CACHE_RESULT_ACCESS
iTLBReadHit, err := NewInstrTLBProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[InstrTLBReadHit] = iTLBReadHit
if err != nil {
return nil, err
}
profilers[InstrTLBReadHit] = iTLBReadHit

op = unix.PERF_COUNT_HW_CACHE_OP_READ
result = unix.PERF_COUNT_HW_CACHE_RESULT_MISS
iTLBReadMiss, err := NewInstrTLBProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[InstrTLBReadMiss] = iTLBReadMiss
if err != nil {
return nil, err
}
profilers[InstrTLBReadMiss] = iTLBReadMiss

// BPU
op = unix.PERF_COUNT_HW_CACHE_OP_READ
result = unix.PERF_COUNT_HW_CACHE_RESULT_ACCESS
bpuReadHit, err := NewBPUProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[BPUReadHit] = bpuReadHit
if err != nil {
return nil, err
}
profilers[BPUReadHit] = bpuReadHit

op = unix.PERF_COUNT_HW_CACHE_OP_READ
result = unix.PERF_COUNT_HW_CACHE_RESULT_MISS
bpuReadMiss, err := NewBPUProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[BPUReadMiss] = bpuReadMiss
if err != nil {
return nil, err
}
profilers[BPUReadMiss] = bpuReadMiss

// Node
op = unix.PERF_COUNT_HW_CACHE_OP_READ
result = unix.PERF_COUNT_HW_CACHE_RESULT_ACCESS
nodeReadHit, err := NewNodeCacheProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[NodeCacheReadHit] = nodeReadHit
if err != nil {
return nil, err
}
profilers[NodeCacheReadHit] = nodeReadHit

op = unix.PERF_COUNT_HW_CACHE_OP_READ
result = unix.PERF_COUNT_HW_CACHE_RESULT_MISS
nodeReadMiss, err := NewNodeCacheProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[NodeCacheReadMiss] = nodeReadMiss
if err != nil {
return nil, err
}
profilers[NodeCacheReadMiss] = nodeReadMiss

op = unix.PERF_COUNT_HW_CACHE_OP_WRITE
result = unix.PERF_COUNT_HW_CACHE_RESULT_ACCESS
nodeWriteHit, err := NewNodeCacheProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[NodeCacheWriteHit] = nodeWriteHit
if err != nil {
return nil, err
}
profilers[NodeCacheWriteHit] = nodeWriteHit

op = unix.PERF_COUNT_HW_CACHE_OP_WRITE
result = unix.PERF_COUNT_HW_CACHE_RESULT_MISS
nodeWriteMiss, err := NewNodeCacheProfiler(pid, cpu, op, result, opts...)
if err == nil {
profilers[NodeCacheWriteMiss] = nodeWriteMiss
if err != nil {
return nil, err
}
profilers[NodeCacheWriteMiss] = nodeWriteMiss

return &cacheProfiler{
profilers: profilers,
}
}, nil
}

// Start is used to start the CacheProfiler, it will return an error if no
Expand Down
7 changes: 5 additions & 2 deletions cache_profiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import (
)

func TestCacheProfiler(t *testing.T) {
p := NewCacheProfiler(os.Getpid(), 0)
p, err := NewCacheProfiler(os.Getpid(), 0)
if err != nil {
t.Fatal(err)
}
defer func() {
if err := p.Close(); err != nil {
t.Fatal(err)
Expand All @@ -19,7 +22,7 @@ func TestCacheProfiler(t *testing.T) {
if err := p.Start(); err != nil {
t.Fatal(err)
}
_, err := p.Profile()
_, err = p.Profile()
if err != nil {
t.Fatal(err)
}
Expand Down
1 change: 1 addition & 0 deletions events.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build linux
// +build linux

package perf
Expand Down
1 change: 1 addition & 0 deletions fs_utils.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build linux
// +build linux

package perf
Expand Down
1 change: 1 addition & 0 deletions fs_utils_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build linux
// +build linux

package perf
Expand Down
1 change: 1 addition & 0 deletions group_profiler.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build linux
// +build linux

package perf
Expand Down
55 changes: 33 additions & 22 deletions hardware_profiler.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build linux
// +build linux

package perf
Expand All @@ -13,62 +14,72 @@ type hardwareProfiler struct {
}

// NewHardwareProfiler returns a new hardware profiler.
func NewHardwareProfiler(pid, cpu int, opts ...int) HardwareProfiler {
func NewHardwareProfiler(pid, cpu int, opts ...int) (HardwareProfiler, error) {
profilers := map[int]Profiler{}

cpuCycleProfiler, err := NewCPUCycleProfiler(pid, cpu, opts...)
if err == nil {
profilers[unix.PERF_COUNT_HW_CPU_CYCLES] = cpuCycleProfiler
if err != nil {
return nil, err
}
profilers[unix.PERF_COUNT_HW_CPU_CYCLES] = cpuCycleProfiler

instrProfiler, err := NewInstrProfiler(pid, cpu, opts...)
if err == nil {
profilers[unix.PERF_COUNT_HW_INSTRUCTIONS] = instrProfiler
if err != nil {
return nil, err
}
profilers[unix.PERF_COUNT_HW_INSTRUCTIONS] = instrProfiler

cacheRefProfiler, err := NewCacheRefProfiler(pid, cpu, opts...)
if err == nil {
profilers[unix.PERF_COUNT_HW_CACHE_REFERENCES] = cacheRefProfiler
if err != nil {
return nil, err
}
profilers[unix.PERF_COUNT_HW_CACHE_REFERENCES] = cacheRefProfiler

cacheMissesProfiler, err := NewCacheMissesProfiler(pid, cpu, opts...)
if err == nil {
profilers[unix.PERF_COUNT_HW_CACHE_MISSES] = cacheMissesProfiler
if err != nil {
return nil, err
}
profilers[unix.PERF_COUNT_HW_CACHE_MISSES] = cacheMissesProfiler

branchInstrProfiler, err := NewBranchInstrProfiler(pid, cpu, opts...)
if err == nil {
profilers[unix.PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = branchInstrProfiler
if err != nil {
return nil, err
}
profilers[unix.PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = branchInstrProfiler

branchMissesProfiler, err := NewBranchMissesProfiler(pid, cpu, opts...)
if err == nil {
profilers[unix.PERF_COUNT_HW_BRANCH_MISSES] = branchMissesProfiler
if err != nil {
return nil, err
}
profilers[unix.PERF_COUNT_HW_BRANCH_MISSES] = branchMissesProfiler

busCyclesProfiler, err := NewBusCyclesProfiler(pid, cpu, opts...)
if err == nil {
profilers[unix.PERF_COUNT_HW_BUS_CYCLES] = busCyclesProfiler
if err != nil {
return nil, err
}
profilers[unix.PERF_COUNT_HW_BUS_CYCLES] = busCyclesProfiler

stalledCyclesFrontProfiler, err := NewStalledCyclesFrontProfiler(pid, cpu, opts...)
if err == nil {
profilers[unix.PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = stalledCyclesFrontProfiler
if err != nil {
return nil, err
}
profilers[unix.PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = stalledCyclesFrontProfiler

stalledCyclesBackProfiler, err := NewStalledCyclesBackProfiler(pid, cpu, opts...)
if err == nil {
profilers[unix.PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = stalledCyclesBackProfiler
if err != nil {
return nil, err
}
profilers[unix.PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = stalledCyclesBackProfiler

refCPUCyclesProfiler, err := NewRefCPUCyclesProfiler(pid, cpu, opts...)
if err == nil {
profilers[unix.PERF_COUNT_HW_REF_CPU_CYCLES] = refCPUCyclesProfiler
if err != nil {
return nil, err
}
profilers[unix.PERF_COUNT_HW_REF_CPU_CYCLES] = refCPUCyclesProfiler

return &hardwareProfiler{
profilers: profilers,
}
}, nil
}

// Start is used to start the HardwareProfiler.
Expand Down
5 changes: 4 additions & 1 deletion hardware_profiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import (
)

func TestHardwareProfiler(t *testing.T) {
hwProfiler := NewHardwareProfiler(os.Getpid(), -1)
hwProfiler, err := NewHardwareProfiler(os.Getpid(), -1)
if err != nil {
t.Fatal(err)
}
defer func() {
if err := hwProfiler.Close(); err != nil {
t.Fatal(err)
Expand Down
2 changes: 1 addition & 1 deletion msr.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func MSRPaths() ([]string, error) {
}

// MSRs attemps to return all available MSRs.
func MSRs(onErr func(error)) []*MSR{
func MSRs(onErr func(error)) []*MSR {
paths, err := MSRPaths()
if err != nil {
onErr(err)
Expand Down
Loading

0 comments on commit 3ce7e7d

Please sign in to comment.