Skip to content

Commit

Permalink
Merge pull request #170 from intel/targetnotsupported
Browse files Browse the repository at this point in the history
if instructions event cannot be collected then assume target is not s…
  • Loading branch information
harp-intel authored Jan 24, 2025
2 parents 3704eec + 0666293 commit 9b4fd02
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 9 deletions.
33 changes: 25 additions & 8 deletions cmd/metrics/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type Metadata struct {
PerfSupportedEvents string
PMUDriverVersion string
SocketCount int
SupportsInstructions bool
SupportsFixedCycles bool
SupportsFixedInstructions bool
SupportsFixedTMA bool
Expand Down Expand Up @@ -111,11 +112,25 @@ func LoadMetadata(myTarget target.Target, noRoot bool, perfPath string, localTem
}
slowFuncChannel <- err
}()
// instructions
go func() {
var err error
var output string
if metadata.SupportsInstructions, output, err = getSupportsEvent(myTarget, "instructions", noRoot, perfPath, localTempDir); err != nil {
slog.Warn("failed to determine if instructions event is supported, assuming not supported", slog.String("error", err.Error()))
err = nil
} else {
if !metadata.SupportsInstructions {
slog.Warn("instructions event not supported", slog.String("output", output))
}
}
slowFuncChannel <- err
}()
// ref_cycles
go func() {
var err error
var output string
if metadata.SupportsRefCycles, output, err = getSupportsRefCycles(myTarget, noRoot, perfPath, localTempDir); err != nil {
if metadata.SupportsRefCycles, output, err = getSupportsEvent(myTarget, "ref-cycles", noRoot, perfPath, localTempDir); err != nil {
slog.Warn("failed to determine if ref_cycles is supported, assuming not supported", slog.String("error", err.Error()))
err = nil
} else {
Expand Down Expand Up @@ -204,6 +219,7 @@ func LoadMetadata(myTarget target.Target, noRoot bool, perfPath string, localTem
errs = append(errs, <-slowFuncChannel)
errs = append(errs, <-slowFuncChannel)
errs = append(errs, <-slowFuncChannel)
errs = append(errs, <-slowFuncChannel)
for _, errInside := range errs {
if errInside != nil {
slog.Error("error loading metadata", slog.String("error", errInside.Error()), slog.String("target", myTarget.GetName()))
Expand Down Expand Up @@ -249,6 +265,7 @@ func (md Metadata) String() string {
"Threads per Core: %d, "+
"TSC Frequency (Hz): %d, "+
"TSC: %d, "+
"Instructions event supported: %t, "+
"Fixed cycles slot supported: %t, "+
"Fixed instructions slot supported: %t, "+
"Fixed TMA slot supported: %t, "+
Expand All @@ -267,6 +284,7 @@ func (md Metadata) String() string {
md.ThreadsPerCore,
md.TSCFrequencyHz,
md.TSC,
md.SupportsInstructions,
md.SupportsFixedCycles,
md.SupportsFixedInstructions,
md.SupportsFixedTMA,
Expand Down Expand Up @@ -378,17 +396,16 @@ func getPerfSupportedEvents(myTarget target.Target, perfPath string) (supportedE
return
}

// getSupportsRefCycles() - checks if the ref-cycles event is supported by perf
// On some VMs, the ref-cycles event is not supported and perf returns an error
func getSupportsRefCycles(myTarget target.Target, noRoot bool, perfPath string, localTempDir string) (supported bool, output string, err error) {
// getSupportsEvent() - checks if the event is supported by perf
func getSupportsEvent(myTarget target.Target, event string, noRoot bool, perfPath string, localTempDir string) (supported bool, output string, err error) {
scriptDef := script.ScriptDefinition{
Name: "perf stat ref-cycles",
Script: perfPath + " stat -a -e ref-cycles sleep 1",
Name: "perf stat " + event,
Script: perfPath + " stat -a -e " + event + " sleep 1",
Superuser: !noRoot,
}
scriptOutput, err := script.RunScript(myTarget, scriptDef, localTempDir)
if err != nil {
err = fmt.Errorf("failed to determine if ref-cycles is supported: %s, %d, %v", scriptOutput.Stderr, scriptOutput.Exitcode, err)
err = fmt.Errorf("failed to determine if %s is supported: %s, %d, %v", event, scriptOutput.Stderr, scriptOutput.Exitcode, err)
return
}
supported = !strings.Contains(scriptOutput.Stderr, "<not supported>")
Expand Down Expand Up @@ -509,7 +526,7 @@ func getSupportsFixedEvent(myTarget target.Target, event string, uarch string, n
eventList = append(eventList, event)
}
scriptDef := script.ScriptDefinition{
Name: "perf stat " + event,
Name: "perf stat fixed" + event,
Script: perfPath + " stat -a -e '{" + strings.Join(eventList, ",") + "}' sleep 1",
Superuser: !noRoot,
}
Expand Down
9 changes: 8 additions & 1 deletion cmd/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -662,10 +662,11 @@ func runCmd(cmd *cobra.Command, args []string) error {
}
// wait for all metrics to be prepared
numTargetsWithPreparedMetrics := 0
for range targetContexts {
for _, ctx := range targetContexts {
targetError := <-channelTargetError
if targetError.err != nil {
slog.Error("failed to prepare metrics", slog.String("target", targetError.target.GetName()), slog.String("error", targetError.err.Error()))
_ = multiSpinner.Status(ctx.target.GetName(), fmt.Sprintf("Error: %v", targetError.err))
} else {
numTargetsWithPreparedMetrics++
}
Expand Down Expand Up @@ -893,6 +894,12 @@ func prepareMetrics(targetContext *targetContext, localTempDir string, channelEr
channelError <- targetError{target: myTarget, err: err}
return
}
if !targetContext.metadata.SupportsInstructions {
slog.Info("Target does not support instructions event collection", slog.String("target", myTarget.GetName()))
targetContext.err = fmt.Errorf("target not supported, does not support instructions event collection")
channelError <- targetError{target: myTarget, err: targetContext.err}
return
}
slog.Info(targetContext.metadata.String())
// load event definitions
var uncollectableEvents []string
Expand Down

0 comments on commit 9b4fd02

Please sign in to comment.