aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-07-11 19:28:22 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-07-11 19:28:22 +0000
commitc72d9c89312e0f28f0ca25e415c2748005aec1ec (patch)
treee452a0715a179a89ff350983509d755af4920f8d
parent07a960b25cefa3b5a1a3eb8ff99285b7ff7d40ac (diff)
parent613884e78e5284bab871e0468341a813f8955217 (diff)
downloadperfetto-android13-mainline-go-art-release.tar.gz
Snap for 8817865 from 613884e78e5284bab871e0468341a813f8955217 to mainline-go-art-releaseaml_go_art_330913000android13-mainline-go-art-release
Change-Id: I0c8246cf403a713160dbb3eba484bd9115f4b895
-rw-r--r--src/profiling/common/producer_support.cc21
-rw-r--r--src/traced/probes/ftrace/ftrace_config_muxer.cc10
-rw-r--r--src/traced/probes/ftrace/ftrace_procfs.cc132
-rw-r--r--src/traced/probes/ftrace/ftrace_procfs.h31
-rw-r--r--test/configs/rss_stat.cfg17
5 files changed, 179 insertions, 32 deletions
diff --git a/src/profiling/common/producer_support.cc b/src/profiling/common/producer_support.cc
index 544d3c5a2..8ab0b42a6 100644
--- a/src/profiling/common/producer_support.cc
+++ b/src/profiling/common/producer_support.cc
@@ -98,25 +98,18 @@ bool CanProfileAndroid(const DataSourceConfig& ds_config,
const std::string& packages_list_path) {
// These constants are replicated from libcutils android_filesystem_config.h,
// to allow for building and testing the profilers outside the android tree.
- constexpr auto kAidSystem = 1000; // AID_SYSTEM
- constexpr auto kAidUserOffset = 100000; // AID_USER_OFFSET
- constexpr auto kAidAppStart = 10000; // AID_APP_START
- constexpr auto kAidAppEnd = 19999; // AID_APP_END
- constexpr auto kAidSdkSandboxStart = 20000; // AID_SDK_SANDBOX_PROCESS_START
- constexpr auto kAidSdkSandboxEnd = 29999; // AID_SDK_SANDBOX_PROCESS_END
- constexpr auto kAidIsolatedStart = 90000; // AID_ISOLATED_START
- constexpr auto kAidIsolatedEnd = 99999; // AID_ISOLATED_END
+ constexpr auto kAidUserOffset = 100000; // AID_USER_OFFSET
+ constexpr auto kAidAppStart = 10000; // AID_APP_START
+ constexpr auto kAidAppEnd = 19999; // AID_APP_END
+ constexpr auto kAidSdkSandboxStart = 20000; // AID_SDK_SANDBOX_PROCESS_START
+ constexpr auto kAidSdkSandboxEnd = 29999; // AID_SDK_SANDBOX_PROCESS_END
+ constexpr auto kAidIsolatedStart = 90000; // AID_ISOLATED_START
+ constexpr auto kAidIsolatedEnd = 99999; // AID_ISOLATED_END
if (!build_type.empty() && build_type != "user") {
return true;
}
- // TODO(b/217368496): remove this.
- if (uid == kAidSystem) {
- return ds_config.session_initiator() ==
- DataSourceConfig::SESSION_INITIATOR_TRUSTED_SYSTEM;
- }
-
uint64_t uid_without_profile = uid % kAidUserOffset;
uint64_t uid_for_lookup = 0;
if (uid_without_profile >= kAidAppStart &&
diff --git a/src/traced/probes/ftrace/ftrace_config_muxer.cc b/src/traced/probes/ftrace/ftrace_config_muxer.cc
index 6d3a54651..69c4176f3 100644
--- a/src/traced/probes/ftrace/ftrace_config_muxer.cc
+++ b/src/traced/probes/ftrace/ftrace_config_muxer.cc
@@ -95,12 +95,6 @@ void IntersectInPlace(const std::vector<std::string>& unsorted_a,
*out = std::move(v);
}
-bool SupportsRssStatThrottled(const FtraceProcfs& ftrace_procfs) {
- const auto trigger_info = ftrace_procfs.ReadEventTrigger("kmem", "rss_stat");
-
- return trigger_info.find("rss_stat_throttled") != std::string::npos;
-}
-
// This is just to reduce binary size and stack frame size of the insertions.
// It effectively undoes STL's set::insert inlining.
void PERFETTO_NO_INLINE InsertEvent(const char* group,
@@ -416,7 +410,7 @@ std::set<GroupAndName> FtraceConfigMuxer::GetFtraceEvents(
if (category == "memory") {
// Use rss_stat_throttled if supported
- if (SupportsRssStatThrottled(*ftrace_)) {
+ if (ftrace_->SupportsRssStatThrottled()) {
InsertEvent("synthetic", "rss_stat_throttled", &events);
} else {
InsertEvent("kmem", "rss_stat", &events);
@@ -440,7 +434,7 @@ std::set<GroupAndName> FtraceConfigMuxer::GetFtraceEvents(
}
// If throttle_rss_stat: true, use the rss_stat_throttled event if supported
- if (request.throttle_rss_stat() && SupportsRssStatThrottled(*ftrace_)) {
+ if (request.throttle_rss_stat() && ftrace_->SupportsRssStatThrottled()) {
auto it = std::find_if(
events.begin(), events.end(), [](const GroupAndName& event) {
return event.group() == "kmem" && event.name() == "rss_stat";
diff --git a/src/traced/probes/ftrace/ftrace_procfs.cc b/src/traced/probes/ftrace/ftrace_procfs.cc
index e3936488c..55b81b4a4 100644
--- a/src/traced/probes/ftrace/ftrace_procfs.cc
+++ b/src/traced/probes/ftrace/ftrace_procfs.cc
@@ -45,6 +45,12 @@ namespace perfetto {
namespace {
+namespace {
+constexpr char kRssStatThrottledTrigger[] =
+ "hist:keys=mm_id,member:bucket=size/0x80000"
+ ":onchange($bucket).rss_stat_throttled(mm_id,curr,member,size)";
+}
+
void KernelLogWrite(const char* s) {
PERFETTO_DCHECK(*s && s[strlen(s) - 1] == '\n');
if (FtraceProcfs::g_kmesg_fd != -1)
@@ -104,6 +110,11 @@ FtraceProcfs::~FtraceProcfs() = default;
bool FtraceProcfs::EnableEvent(const std::string& group,
const std::string& name) {
std::string path = root_ + "events/" + group + "/" + name + "/enable";
+
+ // Create any required triggers for the ftrace event being enabled.
+ // Some ftrace events (synthetic events) need to set up an event trigger
+ MaybeSetUpEventTriggers(group, name);
+
if (WriteToFile(path, "1"))
return true;
path = root_ + "set_event";
@@ -113,10 +124,17 @@ bool FtraceProcfs::EnableEvent(const std::string& group,
bool FtraceProcfs::DisableEvent(const std::string& group,
const std::string& name) {
std::string path = root_ + "events/" + group + "/" + name + "/enable";
- if (WriteToFile(path, "0"))
- return true;
- path = root_ + "set_event";
- return AppendToFile(path, "!" + group + ":" + name);
+
+ bool ret = WriteToFile(path, "0");
+ if (!ret) {
+ path = root_ + "set_event";
+ ret = AppendToFile(path, "!" + group + ":" + name);
+ }
+
+ // Remove any associated event triggers after disabling the event
+ MaybeTearDownEventTriggers(group, name);
+
+ return ret;
}
bool FtraceProcfs::DisableAllEvents() {
@@ -130,10 +148,110 @@ std::string FtraceProcfs::ReadEventFormat(const std::string& group,
return ReadFileIntoString(path);
}
-std::string FtraceProcfs::ReadEventTrigger(const std::string& group,
- const std::string& name) const {
+std::vector<std::string> FtraceProcfs::ReadEventTriggers(
+ const std::string& group,
+ const std::string& name) const {
std::string path = root_ + "events/" + group + "/" + name + "/trigger";
- return ReadFileIntoString(path);
+ std::string s = ReadFileIntoString(path);
+ std::vector<std::string> triggers;
+
+ for (base::StringSplitter ss(s, '\n'); ss.Next();) {
+ std::string trigger = ss.cur_token();
+ if (trigger.empty() || trigger[0] == '#')
+ continue;
+
+ base::StringSplitter ts(trigger, ' ');
+ PERFETTO_CHECK(ts.Next());
+ triggers.push_back(ts.cur_token());
+ }
+
+ return triggers;
+}
+
+bool FtraceProcfs::CreateEventTrigger(const std::string& group,
+ const std::string& name,
+ const std::string& trigger) {
+ std::string path = root_ + "events/" + group + "/" + name + "/trigger";
+ return WriteToFile(path, trigger);
+}
+
+bool FtraceProcfs::RemoveEventTrigger(const std::string& group,
+ const std::string& name,
+ const std::string& trigger) {
+ std::string path = root_ + "events/" + group + "/" + name + "/trigger";
+ return WriteToFile(path, "!" + trigger);
+}
+
+bool FtraceProcfs::RemoveAllEventTriggers(const std::string& group,
+ const std::string& name) {
+ std::vector<std::string> triggers = ReadEventTriggers(group, name);
+
+ // Remove the triggers in reverse order since a trigger can depend
+ // on another trigger created earlier.
+ for (auto it = triggers.rbegin(); it != triggers.rend(); ++it)
+ if (!RemoveEventTrigger(group, name, *it))
+ return false;
+ return true;
+}
+
+bool FtraceProcfs::MaybeSetUpEventTriggers(const std::string& group,
+ const std::string& name) {
+ bool ret = true;
+
+ if (group == "synthetic" && name == "rss_stat_throttled") {
+ ret = RemoveAllEventTriggers("kmem", "rss_stat") &&
+ CreateEventTrigger("kmem", "rss_stat", kRssStatThrottledTrigger);
+ }
+
+ if (!ret) {
+ PERFETTO_PLOG("Failed to setup event triggers for %s:%s", group.c_str(),
+ name.c_str());
+ }
+
+ return ret;
+}
+
+bool FtraceProcfs::MaybeTearDownEventTriggers(const std::string& group,
+ const std::string& name) {
+ bool ret = true;
+
+ if (group == "synthetic" && name == "rss_stat_throttled")
+ ret = RemoveAllEventTriggers("kmem", "rss_stat");
+
+ if (!ret) {
+ PERFETTO_PLOG("Failed to tear down event triggers for: %s:%s",
+ group.c_str(), name.c_str());
+ }
+
+ return ret;
+}
+
+bool FtraceProcfs::SupportsRssStatThrottled() {
+ std::string group = "synthetic";
+ std::string name = "rss_stat_throttled";
+
+ // Check if the trigger already exists. Don't try recreating
+ // or removing the trigger if it is already in use.
+ auto triggers = ReadEventTriggers("kmem", "rss_stat");
+ for (const auto& trigger : triggers) {
+ // The kernel shows all the default values of a trigger
+ // when read from and trace event 'trigger' file.
+ //
+ // Trying to match the complete trigger string is prone
+ // to fail if, in the future, the kernel changes default
+ // fields or values for event triggers.
+ //
+ // Do a partial match on the generated event name
+ // (rss_stat_throttled) to detect if the trigger
+ // is already created.
+ if (trigger.find(name) != std::string::npos)
+ return true;
+ }
+
+ // Attempt to create rss_stat_throttled hist trigger */
+ bool ret = MaybeSetUpEventTriggers(group, name);
+
+ return ret && MaybeTearDownEventTriggers(group, name);
}
std::string FtraceProcfs::ReadPrintkFormats() const {
diff --git a/src/traced/probes/ftrace/ftrace_procfs.h b/src/traced/probes/ftrace/ftrace_procfs.h
index 6e0791b84..b7ddf990b 100644
--- a/src/traced/probes/ftrace/ftrace_procfs.h
+++ b/src/traced/probes/ftrace/ftrace_procfs.h
@@ -58,9 +58,34 @@ class FtraceProcfs {
virtual std::string ReadPageHeaderFormat() const;
- // Read the triggers for event with the given |group| and |name|.
- std::string ReadEventTrigger(const std::string& group,
- const std::string& name) const;
+ // Get all triggers for event with the given |group| and |name|.
+ std::vector<std::string> ReadEventTriggers(const std::string& group,
+ const std::string& name) const;
+
+ // Create an event trigger for the given |group| and |name|.
+ bool CreateEventTrigger(const std::string& group,
+ const std::string& name,
+ const std::string& trigger);
+
+ // Remove an event trigger for the given |group| and |name|.
+ bool RemoveEventTrigger(const std::string& group,
+ const std::string& name,
+ const std::string& trigger);
+
+ // Remove all event trigger for the given |group| and |name|.
+ bool RemoveAllEventTriggers(const std::string& group,
+ const std::string& name);
+
+ // Sets up any associated event trigger before enabling the event
+ bool MaybeSetUpEventTriggers(const std::string& group,
+ const std::string& name);
+
+ // Tears down any associated event trigger after disabling the event
+ bool MaybeTearDownEventTriggers(const std::string& group,
+ const std::string& name);
+
+ // Returns true if rss_stat_throttled synthetic event is supported
+ bool SupportsRssStatThrottled();
// Read the printk formats file.
std::string ReadPrintkFormats() const;
diff --git a/test/configs/rss_stat.cfg b/test/configs/rss_stat.cfg
new file mode 100644
index 000000000..010aa9746
--- /dev/null
+++ b/test/configs/rss_stat.cfg
@@ -0,0 +1,17 @@
+buffers: {
+ size_kb: 512
+ fill_policy: DISCARD
+}
+
+data_sources: {
+ config {
+ name: "linux.ftrace"
+ ftrace_config {
+ ftrace_events: "sched_switch"
+ ftrace_events: "kmem/rss_stat"
+ throttle_rss_stat: true
+ }
+ }
+}
+
+duration_ms: 10000