diff options
author | Yabin Cui <yabinc@google.com> | 2024-05-07 16:53:57 -0700 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2024-05-07 16:53:57 -0700 |
commit | eb98a8b5a1259ccf37bb194a28012d72c873103c (patch) | |
tree | 41868aea3b2eb7ee2398121e0f4566b14062976a | |
parent | a7f60820125555a439b953ac7651f9e2d894e981 (diff) | |
download | extras-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
-rw-r--r-- | simpleperf/cmd_record.cpp | 11 | ||||
-rw-r--r-- | simpleperf/event_selection_set.cpp | 45 | ||||
-rw-r--r-- | simpleperf/event_selection_set.h | 3 |
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 { |