From b641870342759be4684dcde61e9583917e69eef1 Mon Sep 17 00:00:00 2001 From: Yabin Cui Date: Thu, 7 Jun 2018 15:52:57 -0700 Subject: simpleperf: add whitelist to omit tests requiring hw counters. Some Socs like i.MX6 Quad doesn't support PMU, so omit tests requiring hw counters on them. Bug: 80501046 Test: run CtsSimpleperfTestCase on a device not having Test: hw counters. Change-Id: Ibbc0128846d014b47b3f0b36f42992523f8782cd (cherry picked from commit 8faa615e6ab0251c8372eaba32d26a6484ad28b5) --- simpleperf/cmd_record_test.cpp | 37 +++++++++++++++++++++++++++++++++++++ simpleperf/cmd_report_test.cpp | 1 + simpleperf/cmd_stat_test.cpp | 1 + simpleperf/environment.cpp | 13 +++++++++++++ simpleperf/environment.h | 2 ++ simpleperf/environment_test.cpp | 7 +++++++ simpleperf/test_util.h | 9 +++++++++ 7 files changed, 70 insertions(+) diff --git a/simpleperf/cmd_record_test.cpp b/simpleperf/cmd_record_test.cpp index 8780cfcc..21eb8846 100644 --- a/simpleperf/cmd_record_test.cpp +++ b/simpleperf/cmd_record_test.cpp @@ -16,10 +16,12 @@ #include +#include #include #include #include +#include #include "command.h" #include "environment.h" @@ -49,16 +51,19 @@ static bool RunRecordCmd(std::vector v, const char* output_file = n } TEST(record_cmd, no_options) { + TEST_REQUIRE_HW_COUNTER(); ASSERT_TRUE(RunRecordCmd({})); } TEST(record_cmd, system_wide_option) { + TEST_REQUIRE_HW_COUNTER(); if (IsRoot()) { ASSERT_TRUE(RunRecordCmd({"-a"})); } } TEST(record_cmd, sample_period_option) { + TEST_REQUIRE_HW_COUNTER(); ASSERT_TRUE(RunRecordCmd({"-c", "100000"})); } @@ -67,16 +72,19 @@ TEST(record_cmd, event_option) { } TEST(record_cmd, freq_option) { + TEST_REQUIRE_HW_COUNTER(); ASSERT_TRUE(RunRecordCmd({"-f", "99"})); ASSERT_TRUE(RunRecordCmd({"-F", "99"})); } TEST(record_cmd, output_file_option) { + TEST_REQUIRE_HW_COUNTER(); TemporaryFile tmpfile; ASSERT_TRUE(RecordCmd()->Run({"-o", tmpfile.path, "sleep", SLEEP_SEC})); } TEST(record_cmd, dump_kernel_mmap) { + TEST_REQUIRE_HW_COUNTER(); TemporaryFile tmpfile; ASSERT_TRUE(RunRecordCmd({}, tmpfile.path)); std::unique_ptr reader = RecordFileReader::CreateInstance(tmpfile.path); @@ -97,6 +105,7 @@ TEST(record_cmd, dump_kernel_mmap) { } TEST(record_cmd, dump_build_id_feature) { + TEST_REQUIRE_HW_COUNTER(); TemporaryFile tmpfile; ASSERT_TRUE(RunRecordCmd({}, tmpfile.path)); std::unique_ptr reader = RecordFileReader::CreateInstance(tmpfile.path); @@ -113,6 +122,7 @@ TEST(record_cmd, tracepoint_event) { } TEST(record_cmd, branch_sampling) { + TEST_REQUIRE_HW_COUNTER(); if (IsBranchSamplingSupported()) { ASSERT_TRUE(RunRecordCmd({"-b"})); ASSERT_TRUE(RunRecordCmd({"-j", "any,any_call,any_ret,ind_call"})); @@ -126,14 +136,34 @@ TEST(record_cmd, branch_sampling) { } TEST(record_cmd, event_modifier) { + TEST_REQUIRE_HW_COUNTER(); ASSERT_TRUE(RunRecordCmd({"-e", "cpu-cycles:u"})); } TEST(record_cmd, fp_callchain_sampling) { + TEST_REQUIRE_HW_COUNTER(); ASSERT_TRUE(RunRecordCmd({"--call-graph", "fp"})); } +bool HasHardwareCounter() { + static int has_hw_counter = -1; + if (has_hw_counter == -1) { + has_hw_counter = 1; +#if defined(__arm__) + std::string cpu_info; + if (android::base::ReadFileToString("/proc/cpuinfo", &cpu_info)) { + std::string hardware = GetHardwareFromCpuInfo(cpu_info); + if (std::regex_search(hardware, std::regex(R"(i\.MX6.*Quad)"))) { + has_hw_counter = 0; + } + } +#endif + } + return has_hw_counter == 1; +} + TEST(record_cmd, dwarf_callchain_sampling) { + TEST_REQUIRE_HW_COUNTER(); if (IsDwarfCallChainSamplingSupported()) { ASSERT_TRUE(RunRecordCmd({"--call-graph", "dwarf"})); ASSERT_TRUE(RunRecordCmd({"--call-graph", "dwarf,16384"})); @@ -145,6 +175,7 @@ TEST(record_cmd, dwarf_callchain_sampling) { } TEST(record_cmd, no_unwind_option) { + TEST_REQUIRE_HW_COUNTER(); if (IsDwarfCallChainSamplingSupported()) { ASSERT_TRUE(RunRecordCmd({"--call-graph", "dwarf", "--no-unwind"})); } else { @@ -155,6 +186,7 @@ TEST(record_cmd, no_unwind_option) { } TEST(record_cmd, post_unwind_option) { + TEST_REQUIRE_HW_COUNTER(); if (IsDwarfCallChainSamplingSupported()) { ASSERT_TRUE(RunRecordCmd({"--call-graph", "dwarf", "--post-unwind"})); } else { @@ -167,6 +199,7 @@ TEST(record_cmd, post_unwind_option) { } TEST(record_cmd, existing_processes) { + TEST_REQUIRE_HW_COUNTER(); std::vector> workloads; CreateProcesses(2, &workloads); std::string pid_list = @@ -175,6 +208,7 @@ TEST(record_cmd, existing_processes) { } TEST(record_cmd, existing_threads) { + TEST_REQUIRE_HW_COUNTER(); std::vector> workloads; CreateProcesses(2, &workloads); // Process id can also be used as thread id in linux. @@ -185,15 +219,18 @@ TEST(record_cmd, existing_threads) { } TEST(record_cmd, no_monitored_threads) { + TEST_REQUIRE_HW_COUNTER(); ASSERT_FALSE(RecordCmd()->Run({""})); } TEST(record_cmd, more_than_one_event_types) { + TEST_REQUIRE_HW_COUNTER(); ASSERT_TRUE(RunRecordCmd({"-e", "cpu-cycles,cpu-clock"})); ASSERT_TRUE(RunRecordCmd({"-e", "cpu-cycles", "-e", "cpu-clock"})); } TEST(record_cmd, mmap_page_option) { + TEST_REQUIRE_HW_COUNTER(); ASSERT_TRUE(RunRecordCmd({"-m", "1"})); ASSERT_FALSE(RunRecordCmd({"-m", "0"})); ASSERT_FALSE(RunRecordCmd({"-m", "7"})); diff --git a/simpleperf/cmd_report_test.cpp b/simpleperf/cmd_report_test.cpp index bcf8b6e0..a98b75f3 100644 --- a/simpleperf/cmd_report_test.cpp +++ b/simpleperf/cmd_report_test.cpp @@ -268,6 +268,7 @@ static std::unique_ptr RecordCmd() { } TEST_F(ReportCommandTest, dwarf_callgraph) { + TEST_REQUIRE_HW_COUNTER(); if (IsDwarfCallChainSamplingSupported()) { TemporaryFile tmp_file; ASSERT_TRUE(RecordCmd()->Run({"-g", "-o", tmp_file.path, "sleep", SLEEP_SEC})); diff --git a/simpleperf/cmd_stat_test.cpp b/simpleperf/cmd_stat_test.cpp index 8786d8d3..6bf57ddb 100644 --- a/simpleperf/cmd_stat_test.cpp +++ b/simpleperf/cmd_stat_test.cpp @@ -51,6 +51,7 @@ TEST(stat_cmd, tracepoint_event) { } TEST(stat_cmd, event_modifier) { + TEST_REQUIRE_HW_COUNTER(); ASSERT_TRUE(StatCmd()->Run({"-e", "cpu-cycles:u,cpu-cycles:k", "sleep", "1"})); } diff --git a/simpleperf/environment.cpp b/simpleperf/environment.cpp index a73aa1cc..4266932e 100644 --- a/simpleperf/environment.cpp +++ b/simpleperf/environment.cpp @@ -491,3 +491,16 @@ bool GetMaxSampleFrequency(uint64_t* max_sample_freq) { } return true; } + +std::string GetHardwareFromCpuInfo(const std::string& cpu_info) { + for (auto& line : android::base::Split(cpu_info, "\n")) { + size_t pos = line.find(':'); + if (pos != std::string::npos) { + std::string key = android::base::Trim(line.substr(0, pos)); + if (key == "Hardware") { + return android::base::Trim(line.substr(pos + 1)); + } + } + } + return ""; +} diff --git a/simpleperf/environment.h b/simpleperf/environment.h index 0b565ea4..241619e0 100644 --- a/simpleperf/environment.h +++ b/simpleperf/environment.h @@ -82,4 +82,6 @@ bool ProcessKernelSymbols(const std::string& symbol_file, bool CheckPerfEventLimit(); bool GetMaxSampleFrequency(uint64_t* max_sample_freq); +std::string GetHardwareFromCpuInfo(const std::string& cpu_info); + #endif // SIMPLE_PERF_ENVIRONMENT_H_ diff --git a/simpleperf/environment_test.cpp b/simpleperf/environment_test.cpp index 6bca7b8d..ea59ee5b 100644 --- a/simpleperf/environment_test.cpp +++ b/simpleperf/environment_test.cpp @@ -72,3 +72,10 @@ TEST(environment, ProcessKernelSymbols) { ASSERT_FALSE(ProcessKernelSymbols( tempfile.path, std::bind(&KernelSymbolsMatch, std::placeholders::_1, expected_symbol))); } + +TEST(environment, GetHardwareFromCpuInfo) { + std::string cpu_info = "CPU revision : 10\n\n" + "Hardware : Symbol i.MX6 Freeport_Plat Quad/DualLite (Device Tree)\n"; + ASSERT_EQ("Symbol i.MX6 Freeport_Plat Quad/DualLite (Device Tree)", + GetHardwareFromCpuInfo(cpu_info)); +} diff --git a/simpleperf/test_util.h b/simpleperf/test_util.h index cfbe493a..64d3922d 100644 --- a/simpleperf/test_util.h +++ b/simpleperf/test_util.h @@ -26,3 +26,12 @@ void CreateProcesses(size_t count, std::vector>* workl void ParseSymbol(const ElfFileSymbol& symbol, std::map* symbols); void CheckElfFileSymbols(const std::map& symbols); + +bool HasHardwareCounter(); +#define TEST_REQUIRE_HW_COUNTER() \ + do { \ + if (!HasHardwareCounter()) { \ + GTEST_LOG_(INFO) << "Skip this test as the machine doesn't have hardware PMU counters."; \ + return; \ + } \ + } while (0) -- cgit v1.2.3