diff options
author | Yabin Cui <yabinc@google.com> | 2016-08-19 17:24:37 -0700 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2016-08-19 17:32:10 -0700 |
commit | 994cb626a9b0ad6cb723a9dfa7c5e05849647c87 (patch) | |
tree | 29d9f84cc135da3194ec3d244b64d1803c51ca83 | |
parent | cb0112fe640d7b8a9668f91d2cad7234bd63f880 (diff) | |
download | extras-994cb626a9b0ad6cb723a9dfa7c5e05849647c87.tar.gz |
simpleperf: monitor cpu hotplug in stat cmd.
Move code used to monitor cpu hotplug events
from cmd_record.cpp to event_selection_set.cpp,
so it can also be used by stat cmd.
Bug: http://b/29245608
Change-Id: I1f5f3268192aa5c98c0be9fc1de763352c08eab6
Test: run simpleperf stat, and online/offline a cpu.
-rw-r--r-- | simpleperf/cmd_record.cpp | 31 | ||||
-rw-r--r-- | simpleperf/cmd_stat.cpp | 13 | ||||
-rw-r--r-- | simpleperf/event_selection_set.cpp | 36 | ||||
-rw-r--r-- | simpleperf/event_selection_set.h | 14 |
4 files changed, 61 insertions, 33 deletions
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp index 7d653411..5527e68b 100644 --- a/simpleperf/cmd_record.cpp +++ b/simpleperf/cmd_record.cpp @@ -67,8 +67,6 @@ constexpr uint32_t MAX_DUMP_STACK_SIZE = 65528; // successfully, the buffer size = 1024 * 4K (page size) = 4M. constexpr size_t DESIRED_PAGES_IN_MAPPED_BUFFER = 1024; -constexpr double PERIOD_TO_DETECT_CPU_HOTPLUG_EVENTS_IN_SEC = 0.5; - class RecordCommand : public Command { public: RecordCommand() @@ -192,7 +190,6 @@ class RecordCommand : public Command { bool DumpAdditionalFeatures(const std::vector<std::string>& args); bool DumpBuildIdFeature(); void CollectHitFileInfo(Record* record); - bool DetectCpuHotplugEvents(); bool use_sample_freq_; uint64_t sample_freq_; // Sample 'sample_freq_' times per second. @@ -225,8 +222,6 @@ class RecordCommand : public Command { uint64_t sample_record_count_; uint64_t lost_record_count_; - - std::vector<int> online_cpus_; }; bool RecordCommand::Run(const std::vector<std::string>& args) { @@ -295,6 +290,9 @@ bool RecordCommand::Run(const std::vector<std::string>& args) { if (!event_selection_set_.PrepareToReadMmapEventData(loop, callback)) { return false; } + if (!event_selection_set_.HandleCpuHotplugEvents(loop, cpus_)) { + return false; + } if (!loop.AddSignalEvents({SIGCHLD, SIGINT, SIGTERM}, [&]() { return loop.ExitLoop(); })) { return false; @@ -305,12 +303,6 @@ bool RecordCommand::Run(const std::vector<std::string>& args) { return false; } } - online_cpus_ = GetOnlineCpus(); - if (!loop.AddPeriodicEvent( - SecondToTimeval(PERIOD_TO_DETECT_CPU_HOTPLUG_EVENTS_IN_SEC), - [&]() { return DetectCpuHotplugEvents(); })) { - return false; - } // 6. Write records in mapped buffers of perf_event_files to output file while // workload is running. @@ -1098,23 +1090,6 @@ void RecordCommand::CollectHitFileInfo(Record* record) { } } -bool RecordCommand::DetectCpuHotplugEvents() { - std::vector<int> new_cpus = GetOnlineCpus(); - for (auto& cpu : online_cpus_) { - if (std::find(new_cpus.begin(), new_cpus.end(), cpu) == new_cpus.end()) { - LOG(INFO) << "Cpu " << cpu << " is offlined"; - } - } - for (auto& cpu : new_cpus) { - if (std::find(online_cpus_.begin(), online_cpus_.end(), cpu) == - online_cpus_.end()) { - LOG(INFO) << "Cpu " << cpu << " is onlined"; - } - } - online_cpus_ = new_cpus; - return true; -} - void RegisterRecordCommand() { RegisterCommand("record", [] { return std::unique_ptr<Command>(new RecordCommand()); }); diff --git a/simpleperf/cmd_stat.cpp b/simpleperf/cmd_stat.cpp index 5a0694e7..41992939 100644 --- a/simpleperf/cmd_stat.cpp +++ b/simpleperf/cmd_stat.cpp @@ -360,17 +360,20 @@ bool StatCommand::Run(const std::vector<std::string>& args) { return false; } } else { - if (cpus_.empty()) { - cpus_ = {-1}; - } - if (!event_selection_set_.OpenEventFilesForThreadsOnCpus(monitored_threads_, - cpus_)) { + std::vector<int> all_cpus = {-1}; + if (!event_selection_set_.OpenEventFilesForThreadsOnCpus( + monitored_threads_, cpus_.empty() ? all_cpus : cpus_)) { return false; } } // 4. Create IOEventLoop and add signal/periodic Events. IOEventLoop loop; + if (system_wide_collection_ || !cpus_.empty()) { + if (!event_selection_set_.HandleCpuHotplugEvents(loop, cpus_)) { + return false; + } + } if (!loop.AddSignalEvents({SIGCHLD, SIGINT, SIGTERM}, [&]() { return loop.ExitLoop(); })) { return false; diff --git a/simpleperf/event_selection_set.cpp b/simpleperf/event_selection_set.cpp index 6235e32b..edff1749 100644 --- a/simpleperf/event_selection_set.cpp +++ b/simpleperf/event_selection_set.cpp @@ -24,6 +24,7 @@ #include "event_type.h" #include "IOEventLoop.h" #include "perf_regs.h" +#include "utils.h" bool IsBranchSamplingSupported() { const EventType* type = FindEventTypeByName("cpu-cycles"); @@ -439,3 +440,38 @@ bool EventSelectionSet::FinishReadMmapEventData() { } return true; } + +bool EventSelectionSet::HandleCpuHotplugEvents( + IOEventLoop& loop, const std::vector<int>& monitored_cpus, + double check_interval_in_sec) { + monitored_cpus_.insert(monitored_cpus.begin(), monitored_cpus.end()); + online_cpus_ = GetOnlineCpus(); + if (!loop.AddPeriodicEvent(SecondToTimeval(check_interval_in_sec), + [&]() { return DetectCpuHotplugEvents(); })) { + return false; + } + return true; +} + +bool EventSelectionSet::DetectCpuHotplugEvents() { + std::vector<int> new_cpus = GetOnlineCpus(); + for (const auto& cpu : online_cpus_) { + if (std::find(new_cpus.begin(), new_cpus.end(), cpu) == new_cpus.end()) { + if (monitored_cpus_.empty() || + monitored_cpus_.find(cpu) != monitored_cpus_.end()) { + LOG(INFO) << "Cpu " << cpu << " is offlined"; + } + } + } + for (const auto& cpu : new_cpus) { + if (std::find(online_cpus_.begin(), online_cpus_.end(), cpu) == + online_cpus_.end()) { + if (monitored_cpus_.empty() || + monitored_cpus_.find(cpu) != monitored_cpus_.end()) { + LOG(INFO) << "Cpu " << cpu << " is onlined"; + } + } + } + online_cpus_ = new_cpus; + return true; +} diff --git a/simpleperf/event_selection_set.h b/simpleperf/event_selection_set.h index a947320f..c24dad4c 100644 --- a/simpleperf/event_selection_set.h +++ b/simpleperf/event_selection_set.h @@ -19,6 +19,7 @@ #include <functional> #include <map> +#include <set> #include <unordered_map> #include <vector> @@ -29,6 +30,8 @@ #include "perf_event.h" #include "record.h" +constexpr double DEFAULT_PERIOD_TO_DETECT_CPU_HOTPLUG_EVENTS_IN_SEC = 0.5; + struct EventSelection { uint32_t group_id; uint32_t selection_id; @@ -96,6 +99,12 @@ class EventSelectionSet { const std::function<bool(Record*)>& callback); bool FinishReadMmapEventData(); + // If monitored_cpus is empty, monitor all cpus. + bool HandleCpuHotplugEvents( + IOEventLoop& loop, const std::vector<int>& monitored_cpus, + double check_interval_in_sec = + DEFAULT_PERIOD_TO_DETECT_CPU_HOTPLUG_EVENTS_IN_SEC); + private: bool BuildAndCheckEventSelection(const std::string& event_name, EventSelection* selection); @@ -105,10 +114,15 @@ class EventSelectionSet { bool MmapEventFiles(size_t mmap_pages, bool report_error); bool ReadMmapEventDataForFd(std::unique_ptr<EventFd>& event_fd); + bool DetectCpuHotplugEvents(); + std::vector<EventSelectionGroup> groups_; std::function<bool(Record*)> record_callback_; + std::set<int> monitored_cpus_; + std::vector<int> online_cpus_; + DISALLOW_COPY_AND_ASSIGN(EventSelectionSet); }; |