summaryrefslogtreecommitdiff
path: root/simpleperf
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2024-05-07 16:53:57 -0700
committerYabin Cui <yabinc@google.com>2024-05-07 16:53:57 -0700
commiteb98a8b5a1259ccf37bb194a28012d72c873103c (patch)
tree41868aea3b2eb7ee2398121e0f4566b14062976a /simpleperf
parenta7f60820125555a439b953ac7651f9e2d894e981 (diff)
downloadextras-eb98a8b5a1259ccf37bb194a28012d72c873103c.tar.gz
simpleperf: Enable ETM events after create aux buffer
Otherwise, ETM events can't be enabled successfully. Bug: 336375740 Test: run simpleperf manually Change-Id: I6583aebced57d739f98769cc39dab862569ec8ad
Diffstat (limited to 'simpleperf')
-rw-r--r--simpleperf/cmd_record.cpp11
-rw-r--r--simpleperf/event_selection_set.cpp45
-rw-r--r--simpleperf/event_selection_set.h3
3 files changed, 56 insertions, 3 deletions
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp
index 40582045..ee93e1ea 100644
--- a/simpleperf/cmd_record.cpp
+++ b/simpleperf/cmd_record.cpp
@@ -631,7 +631,7 @@ bool RecordCommand::PrepareRecording(Workload* workload) {
} else {
need_to_check_targets = true;
}
- if (delay_in_ms_ != 0) {
+ if (delay_in_ms_ != 0 || event_selection_set_.HasAuxTrace()) {
event_selection_set_.SetEnableCondition(false, false);
}
@@ -755,6 +755,12 @@ bool RecordCommand::PrepareRecording(Workload* workload) {
}
}
if (event_selection_set_.HasAuxTrace()) {
+ // ETM events can only be enabled successfully after MmapEventFiles().
+ if (delay_in_ms_ == 0 && !event_selection_set_.IsEnabledOnExec()) {
+ if (!event_selection_set_.EnableETMEvents()) {
+ return false;
+ }
+ }
// ETM data is dumped to kernel buffer only when there is no thread traced by ETM. It happens
// either when all monitored threads are scheduled off cpu, or when all etm perf events are
// disabled.
@@ -762,8 +768,7 @@ bool RecordCommand::PrepareRecording(Workload* workload) {
// makes less than expected data, especially in system wide recording. So add a periodic event
// to flush etm data by temporarily disable all perf events.
auto etm_flush = [this]() {
- return event_selection_set_.SetEnableEvents(false) &&
- event_selection_set_.SetEnableEvents(true);
+ return event_selection_set_.DisableETMEvents() && event_selection_set_.EnableETMEvents();
};
if (!loop->AddPeriodicEvent(SecondToTimeval(kDefaultEtmDataFlushPeriodInSec), etm_flush)) {
return false;
diff --git a/simpleperf/event_selection_set.cpp b/simpleperf/event_selection_set.cpp
index c75f8049..6a1e5a9e 100644
--- a/simpleperf/event_selection_set.cpp
+++ b/simpleperf/event_selection_set.cpp
@@ -233,6 +233,8 @@ bool EventSelectionSet::BuildAndCheckEventSelection(const std::string& event_nam
// enabling/disabling etm devices. So don't adjust frequency by default.
selection->event_attr.freq = 0;
selection->event_attr.sample_period = 1;
+ // An ETM event can't be enabled without mmap aux buffer. So disable it by default.
+ selection->event_attr.disabled = 1;
} else {
selection->event_attr.freq = 1;
// Set default sample freq here may print msg "Adjust sample freq to max allowed sample
@@ -461,6 +463,17 @@ void EventSelectionSet::SetEnableCondition(bool enable_on_open, bool enable_on_e
}
}
+bool EventSelectionSet::IsEnabledOnExec() const {
+ for (const auto& group : groups_) {
+ for (const auto& selection : group.selections) {
+ if (!selection.event_attr.enable_on_exec) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
void EventSelectionSet::SampleIdAll() {
for (auto& group : groups_) {
for (auto& selection : group.selections) {
@@ -939,4 +952,36 @@ bool EventSelectionSet::SetEnableEvents(bool enable) {
return true;
}
+bool EventSelectionSet::EnableETMEvents() {
+ for (auto& group : groups_) {
+ for (auto& sel : group.selections) {
+ if (!sel.event_type_modifier.event_type.IsEtmEvent()) {
+ continue;
+ }
+ for (auto& fd : sel.event_fds) {
+ if (!fd->SetEnableEvent(true)) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+}
+
+bool EventSelectionSet::DisableETMEvents() {
+ for (auto& group : groups_) {
+ for (auto& sel : group.selections) {
+ if (!sel.event_type_modifier.event_type.IsEtmEvent()) {
+ continue;
+ }
+ for (auto& fd : sel.event_fds) {
+ if (!fd->SetEnableEvent(false)) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+}
+
} // namespace simpleperf
diff --git a/simpleperf/event_selection_set.h b/simpleperf/event_selection_set.h
index e046035b..1b3d6b4e 100644
--- a/simpleperf/event_selection_set.h
+++ b/simpleperf/event_selection_set.h
@@ -122,6 +122,7 @@ class EventSelectionSet {
std::map<int, size_t> GetHardwareCountersForCpus() const;
void SetEnableCondition(bool enable_on_open, bool enable_on_exec);
+ bool IsEnabledOnExec() const;
void SampleIdAll();
// Only set sample rate for events that haven't set sample rate.
void SetSampleRateForNewEvents(const SampleRate& rate);
@@ -179,6 +180,8 @@ class EventSelectionSet {
double check_interval_in_sec = DEFAULT_PERIOD_TO_CHECK_MONITORED_TARGETS_IN_SEC);
bool SetEnableEvents(bool enable);
+ bool EnableETMEvents();
+ bool DisableETMEvents();
private:
struct EventSelection {