summaryrefslogtreecommitdiff
path: root/simpleperf/cmd_record.cpp
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2018-08-13 15:58:25 -0700
committerYabin Cui <yabinc@google.com>2018-08-14 11:10:08 -0700
commit6e173a4bf8ea66718c7fc9053cd9d2e3f79aa341 (patch)
tree7efe0585463aa46e86aa76f7fecd51694eddf09d /simpleperf/cmd_record.cpp
parent9d3d54a4642c0b7047fda7555d1eec164b0fd052 (diff)
downloadextras-6e173a4bf8ea66718c7fc9053cd9d2e3f79aa341.tar.gz
simpleperf: set kernel resources used for profiling on Android >=Q.
On Android >=Q, some debug system properties are used to set max sample freq, cpu percentage and kernel buffer size used for recording. This patches uses these debug properties to set needed kernel resources. To set cpu percentage used for recording, add --cpu-percent option. Bug: 110706031 Test: run simpleperf_unit_test. Change-Id: I532ce417099c5a39ae89bdadfe76e512241904dd
Diffstat (limited to 'simpleperf/cmd_record.cpp')
-rw-r--r--simpleperf/cmd_record.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp
index 7b928e5f..60307b83 100644
--- a/simpleperf/cmd_record.cpp
+++ b/simpleperf/cmd_record.cpp
@@ -179,6 +179,8 @@ class RecordCommand : public Command {
" the kernel. It should be a power of 2. If not set, the max\n"
" possible value <= 1024 will be used.\n"
"--no-inherit Don't record created child threads/processes.\n"
+"--cpu-percent <percent> Set the max percent of cpu time used for recording.\n"
+" percent is in range [1-100], default is 25.\n"
"\n"
"Dwarf unwinding options:\n"
"--post-unwind=(yes|no) If `--call-graph dwarf` option is used, then the user's\n"
@@ -256,6 +258,7 @@ class RecordCommand : public Command {
private:
bool ParseOptions(const std::vector<std::string>& args,
std::vector<std::string>* non_option_args);
+ bool AdjustPerfEventLimit();
bool PrepareRecording(Workload* workload);
bool DoRecording(Workload* workload);
bool PostProcessRecording(const std::vector<std::string>& args);
@@ -319,6 +322,8 @@ class RecordCommand : public Command {
bool trace_offcpu_;
bool exclude_kernel_callchain_;
uint64_t size_limit_in_bytes_ = 0;
+ uint64_t max_sample_freq_ = DEFAULT_SAMPLE_FREQ_FOR_NONTRACEPOINT_EVENT;
+ size_t cpu_time_max_percent_ = 25;
// For CallChainJoiner
bool allow_callchain_joiner_;
@@ -344,6 +349,9 @@ bool RecordCommand::Run(const std::vector<std::string>& args) {
if (!ParseOptions(args, &workload_args)) {
return false;
}
+ if (!AdjustPerfEventLimit()) {
+ return false;
+ }
ScopedTempFiles scoped_temp_files(android::base::Dirname(record_filename_));
if (!app_package_name_.empty() && !in_app_context_) {
// Some users want to profile non debuggable apps on rooted devices. If we use run-as,
@@ -622,7 +630,12 @@ bool RecordCommand::ParseOptions(const std::vector<std::string>& args,
if (args[i-1] == "-c") {
sample_speed_.reset(new SampleSpeed(0, value));
} else {
+ if (value >= INT_MAX) {
+ LOG(ERROR) << "sample freq can't be bigger than INT_MAX.";
+ return false;
+ }
sample_speed_.reset(new SampleSpeed(value, 0));
+ max_sample_freq_ = std::max(max_sample_freq_, value);
}
for (auto group_id : wait_setting_speed_event_groups_) {
event_selection_set_.SetSampleSpeed(group_id, *sample_speed_);
@@ -684,6 +697,10 @@ bool RecordCommand::ParseOptions(const std::vector<std::string>& args,
return false;
}
cpus_ = GetCpusFromString(args[i]);
+ } else if (args[i] == "--cpu-percent") {
+ if (!GetUintOption(args, &i, &cpu_time_max_percent_, 1, 100)) {
+ return false;
+ }
} else if (args[i] == "--duration") {
if (!GetDoubleOption(args, &i, &duration_in_sec_, 1e-9)) {
return false;
@@ -873,6 +890,35 @@ bool RecordCommand::ParseOptions(const std::vector<std::string>& args,
return true;
}
+bool RecordCommand::AdjustPerfEventLimit() {
+ bool set_prop = false;
+ // 1. Adjust max_sample_rate.
+ uint64_t cur_max_freq;
+ if (GetMaxSampleFrequency(&cur_max_freq) && cur_max_freq < max_sample_freq_ &&
+ !SetMaxSampleFrequency(max_sample_freq_)) {
+ set_prop = true;
+ }
+ // 2. Adjust perf_cpu_time_max_percent.
+ size_t cur_percent;
+ if (GetCpuTimeMaxPercent(&cur_percent) && cur_percent != cpu_time_max_percent_ &&
+ !SetCpuTimeMaxPercent(cpu_time_max_percent_)) {
+ set_prop = true;
+ }
+ // 3. Adjust perf_event_mlock_kb.
+ uint64_t mlock_kb = sysconf(_SC_NPROCESSORS_CONF) * (mmap_page_range_.second + 1) * 4;
+ uint64_t cur_mlock_kb;
+ if (GetPerfEventMlockKb(&cur_mlock_kb) && cur_mlock_kb < mlock_kb &&
+ !SetPerfEventMlockKb(mlock_kb)) {
+ set_prop = true;
+ }
+
+ if (GetAndroidVersion() >= kAndroidVersionP + 1 && set_prop) {
+ return SetPerfEventLimits(std::max(max_sample_freq_, cur_max_freq), cpu_time_max_percent_,
+ std::max(mlock_kb, cur_mlock_kb));
+ }
+ return true;
+}
+
bool RecordCommand::TraceOffCpu() {
if (FindEventTypeByName("sched:sched_switch") == nullptr) {
LOG(ERROR) << "Can't trace off cpu because sched:sched_switch event is not available";