Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

if instructions event cannot be collected then assume target is not s… #170

Merged
merged 3 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading