Merge "trace_to_text: Add summary mode"
diff --git a/include/perfetto/base/logging.h b/include/perfetto/base/logging.h
index ce4a656..c15597a 100644
--- a/include/perfetto/base/logging.h
+++ b/include/perfetto/base/logging.h
@@ -100,22 +100,22 @@
PERFETTO_IMMEDIATE_CRASH(); \
} while (0)
-#define PERFETTO_PLOG(x) \
- PERFETTO_ELOG("%s (errno: %d, %s)", (x), errno, strerror(errno))
+#define PERFETTO_PLOG(x, ...) \
+ PERFETTO_ELOG(x " (errno: %d, %s)", ##__VA_ARGS__, errno, strerror(errno))
#if PERFETTO_DCHECK_IS_ON()
#define PERFETTO_DLOG(fmt, ...) PERFETTO_XLOG(kLogDebug, fmt, ##__VA_ARGS__)
-#define PERFETTO_DPLOG(x) \
- PERFETTO_DLOG("%s (errno: %d, %s)", (x), errno, strerror(errno))
+#define PERFETTO_DPLOG(x, ...) \
+ PERFETTO_DLOG(x " (errno: %d, %s)", ##__VA_ARGS__, errno, strerror(errno))
-#define PERFETTO_DCHECK(x) \
- do { \
- if (PERFETTO_UNLIKELY(!(x))) { \
- PERFETTO_DPLOG("PERFETTO_CHECK(" #x ")"); \
- PERFETTO_IMMEDIATE_CRASH(); \
- } \
+#define PERFETTO_DCHECK(x) \
+ do { \
+ if (PERFETTO_UNLIKELY(!(x))) { \
+ PERFETTO_DPLOG("%s", "PERFETTO_CHECK(" #x ")"); \
+ PERFETTO_IMMEDIATE_CRASH(); \
+ } \
} while (0)
#else
diff --git a/src/ftrace_reader/cpu_reader_unittest.cc b/src/ftrace_reader/cpu_reader_unittest.cc
index 1a7795c..b4a12c1 100644
--- a/src/ftrace_reader/cpu_reader_unittest.cc
+++ b/src/ftrace_reader/cpu_reader_unittest.cc
@@ -206,6 +206,7 @@
{
Event event;
event.name = "foo";
+ event.group = "foo_group";
event.ftrace_event_id = 1;
events.push_back(event);
}
@@ -213,6 +214,7 @@
{
Event event;
event.name = "bar";
+ event.group = "bar_group";
event.ftrace_event_id = 10;
events.push_back(event);
}
diff --git a/src/ftrace_reader/ftrace_config_muxer.cc b/src/ftrace_reader/ftrace_config_muxer.cc
index 0d2e1ef..3642b24 100644
--- a/src/ftrace_reader/ftrace_config_muxer.cc
+++ b/src/ftrace_reader/ftrace_config_muxer.cc
@@ -45,13 +45,159 @@
return result;
}
+void AddEventGroup(const ProtoTranslationTable* table,
+ const std::string& group,
+ std::set<std::string>* to) {
+ const std::vector<const Event*>* events = table->GetEventsByGroup(group);
+ if (!events)
+ return;
+ for (const Event* event : *events)
+ to->insert(event->name);
+}
+
} // namespace
-std::set<std::string> GetFtraceEvents(const FtraceConfig& request) {
+std::set<std::string> GetFtraceEvents(const FtraceConfig& request,
+ const ProtoTranslationTable* table) {
std::set<std::string> events;
events.insert(request.ftrace_events().begin(), request.ftrace_events().end());
if (RequiresAtrace(request)) {
events.insert("print");
+
+ // Ideally we should keep this code in sync with:
+ // platform/frameworks/native/cmds/atrace/atrace.cpp
+ // It's not a disaster if they go out of sync, we can always add the ftrace
+ // categories manually server side but this is user friendly and reduces the
+ // size of the configs.
+ for (const std::string& category : request.atrace_categories()) {
+ if (category == "gfx") {
+ AddEventGroup(table, "mdss", &events);
+ AddEventGroup(table, "sde", &events);
+ continue;
+ }
+
+ if (category == "sched") {
+ events.insert("sched_switch");
+ events.insert("sched_wakeup");
+ events.insert("sched_waking");
+ events.insert("sched_blocked_reason");
+ events.insert("sched_cpu_hotplug");
+ AddEventGroup(table, "cgroup", &events);
+ continue;
+ }
+
+ if (category == "irq") {
+ AddEventGroup(table, "irq", &events);
+ AddEventGroup(table, "ipi", &events);
+ continue;
+ }
+
+ if (category == "irqoff") {
+ events.insert("irq_enable");
+ events.insert("irq_disable");
+ continue;
+ }
+
+ if (category == "preemptoff") {
+ events.insert("preempt_enable");
+ events.insert("preempt_disable");
+ continue;
+ }
+
+ if (category == "i2c") {
+ AddEventGroup(table, "i2c", &events);
+ continue;
+ }
+
+ if (category == "freq") {
+ events.insert("cpu_frequency");
+ events.insert("clock_set_rate");
+ events.insert("clock_disable");
+ events.insert("clock_enable");
+ events.insert("clk_set_rate");
+ events.insert("clk_disable");
+ events.insert("clk_enable");
+ events.insert("cpu_frequency_limits");
+ continue;
+ }
+
+ if (category == "membus") {
+ AddEventGroup(table, "memory_bus", &events);
+ continue;
+ }
+
+ if (category == "idle") {
+ events.insert("cpu_idle");
+ continue;
+ }
+
+ if (category == "disk") {
+ events.insert("f2fs_sync_file_enter");
+ events.insert("f2fs_sync_file_exit");
+ events.insert("f2fs_write_begin");
+ events.insert("f2fs_write_end");
+ events.insert("ext4_da_write_begin");
+ events.insert("ext4_da_write_end");
+ events.insert("ext4_sync_file_enter");
+ events.insert("ext4_sync_file_exit");
+ events.insert("block_rq_issue");
+ events.insert("block_rq_complete");
+ continue;
+ }
+
+ if (category == "mmc") {
+ AddEventGroup(table, "mmc", &events);
+ continue;
+ }
+
+ if (category == "load") {
+ AddEventGroup(table, "cpufreq_interactive", &events);
+ continue;
+ }
+
+ if (category == "sync") {
+ AddEventGroup(table, "sync", &events);
+ continue;
+ }
+
+ if (category == "workq") {
+ AddEventGroup(table, "workqueue", &events);
+ continue;
+ }
+
+ if (category == "memreclaim") {
+ events.insert("mm_vmscan_direct_reclaim_begin");
+ events.insert("mm_vmscan_direct_reclaim_end");
+ events.insert("mm_vmscan_kswapd_wake");
+ events.insert("mm_vmscan_kswapd_sleep");
+ AddEventGroup(table, "lowmemorykiller", &events);
+ continue;
+ }
+
+ if (category == "regulators") {
+ AddEventGroup(table, "regulator", &events);
+ continue;
+ }
+
+ if (category == "binder_driver") {
+ events.insert("binder_transaction");
+ events.insert("binder_transaction_received");
+ events.insert("binder_set_priority");
+ continue;
+ }
+
+ if (category == "binder_lock") {
+ events.insert("binder_lock");
+ events.insert("binder_locked");
+ events.insert("binder_unlock");
+ continue;
+ }
+
+ if (category == "pagecache") {
+ AddEventGroup(table, "pagecache", &events);
+ continue;
+ }
+ }
}
return events;
}
@@ -100,7 +246,7 @@
return 0;
}
- std::set<std::string> events = GetFtraceEvents(request);
+ std::set<std::string> events = GetFtraceEvents(request, table_);
for (auto& name : events) {
const Event* event = table_->GetEventByName(name);
diff --git a/src/ftrace_reader/ftrace_config_muxer.h b/src/ftrace_reader/ftrace_config_muxer.h
index ce4edb4..de2a7b0 100644
--- a/src/ftrace_reader/ftrace_config_muxer.h
+++ b/src/ftrace_reader/ftrace_config_muxer.h
@@ -93,7 +93,8 @@
std::map<FtraceConfigId, FtraceConfig> configs_;
};
-std::set<std::string> GetFtraceEvents(const FtraceConfig& request);
+std::set<std::string> GetFtraceEvents(const FtraceConfig& request,
+ const ProtoTranslationTable*);
size_t ComputeCpuBufferSizeInPages(size_t requested_buffer_size_kb);
} // namespace perfetto
diff --git a/src/ftrace_reader/ftrace_config_muxer_unittest.cc b/src/ftrace_reader/ftrace_config_muxer_unittest.cc
index 9a88bae..e3be7aa 100644
--- a/src/ftrace_reader/ftrace_config_muxer_unittest.cc
+++ b/src/ftrace_reader/ftrace_config_muxer_unittest.cc
@@ -94,7 +94,31 @@
Event event;
event.name = "sched_new";
event.group = "sched";
- event.ftrace_event_id = 20;
+ event.ftrace_event_id = 11;
+ events.push_back(event);
+ }
+
+ {
+ Event event;
+ event.name = "cgroup_mkdir";
+ event.group = "cgroup";
+ event.ftrace_event_id = 12;
+ events.push_back(event);
+ }
+
+ {
+ Event event;
+ event.name = "mm_vmscan_direct_reclaim_begin";
+ event.group = "vmscan";
+ event.ftrace_event_id = 13;
+ events.push_back(event);
+ }
+
+ {
+ Event event;
+ event.name = "lowmemory_kill";
+ event.group = "lowmemorykiller";
+ event.ftrace_event_id = 14;
events.push_back(event);
}
@@ -234,19 +258,37 @@
}
TEST(FtraceConfigMuxerTest, GetFtraceEvents) {
+ std::unique_ptr<ProtoTranslationTable> table = CreateFakeTable();
FtraceConfig config = CreateFtraceConfig({"sched_switch"});
- std::set<std::string> events = GetFtraceEvents(config);
+ std::set<std::string> events = GetFtraceEvents(config, table.get());
EXPECT_THAT(events, Contains("sched_switch"));
EXPECT_THAT(events, Not(Contains("print")));
}
TEST(FtraceConfigMuxerTest, GetFtraceEventsAtrace) {
- FtraceConfig config = CreateFtraceConfig({"sched_switch"});
+ std::unique_ptr<ProtoTranslationTable> table = CreateFakeTable();
+ FtraceConfig config = CreateFtraceConfig({});
*config.add_atrace_categories() = "sched";
- std::set<std::string> events = GetFtraceEvents(config);
+ std::set<std::string> events = GetFtraceEvents(config, table.get());
EXPECT_THAT(events, Contains("sched_switch"));
+ EXPECT_THAT(events, Contains("sched_cpu_hotplug"));
+ EXPECT_THAT(events, Contains("print"));
+}
+
+TEST(FtraceConfigMuxerTest, GetFtraceEventsAtraceCategories) {
+ std::unique_ptr<ProtoTranslationTable> table = CreateFakeTable();
+ FtraceConfig config = CreateFtraceConfig({});
+ *config.add_atrace_categories() = "sched";
+ *config.add_atrace_categories() = "memreclaim";
+ std::set<std::string> events = GetFtraceEvents(config, table.get());
+
+ EXPECT_THAT(events, Contains("sched_switch"));
+ EXPECT_THAT(events, Contains("sched_cpu_hotplug"));
+ EXPECT_THAT(events, Contains("cgroup_mkdir"));
+ EXPECT_THAT(events, Contains("mm_vmscan_direct_reclaim_begin"));
+ EXPECT_THAT(events, Contains("lowmemory_kill"));
EXPECT_THAT(events, Contains("print"));
}
diff --git a/src/ftrace_reader/proto_translation_table.cc b/src/ftrace_reader/proto_translation_table.cc
index f32813b..485c601 100644
--- a/src/ftrace_reader/proto_translation_table.cc
+++ b/src/ftrace_reader/proto_translation_table.cc
@@ -306,6 +306,7 @@
common_fields_(std::move(common_fields)) {
for (const Event& event : events) {
name_to_event_[event.name] = &events_.at(event.ftrace_event_id);
+ group_to_events_[event.group].push_back(&events_.at(event.ftrace_event_id));
}
}
diff --git a/src/ftrace_reader/proto_translation_table.h b/src/ftrace_reader/proto_translation_table.h
index 53a4fc1..b08cc36 100644
--- a/src/ftrace_reader/proto_translation_table.h
+++ b/src/ftrace_reader/proto_translation_table.h
@@ -67,6 +67,13 @@
return name_to_event_.at(name);
}
+ const std::vector<const Event*>* GetEventsByGroup(
+ const std::string& group) const {
+ if (!group_to_events_.count(group))
+ return nullptr;
+ return &group_to_events_.at(group);
+ }
+
const Event* GetEventById(size_t id) const {
if (id == 0 || id > largest_id_)
return nullptr;
@@ -90,6 +97,7 @@
const std::vector<Event> events_;
size_t largest_id_;
std::map<std::string, const Event*> name_to_event_;
+ std::map<std::string, std::vector<const Event*>> group_to_events_;
std::vector<Field> common_fields_;
};
diff --git a/src/ftrace_reader/proto_translation_table_unittest.cc b/src/ftrace_reader/proto_translation_table_unittest.cc
index ce75cba..0a144c9 100644
--- a/src/ftrace_reader/proto_translation_table_unittest.cc
+++ b/src/ftrace_reader/proto_translation_table_unittest.cc
@@ -26,6 +26,10 @@
using testing::TestWithParam;
using testing::Return;
using testing::AnyNumber;
+using testing::IsNull;
+using testing::Contains;
+using testing::Eq;
+using testing::Pointee;
namespace perfetto {
namespace {
@@ -299,6 +303,7 @@
{
Event event;
event.name = "foo";
+ event.group = "group_one";
event.ftrace_event_id = 1;
events.push_back(event);
}
@@ -306,6 +311,7 @@
{
Event event;
event.name = "bar";
+ event.group = "group_one";
event.ftrace_event_id = 2;
events.push_back(event);
}
@@ -313,6 +319,7 @@
{
Event event;
event.name = "baz";
+ event.group = "group_two";
event.ftrace_event_id = 100;
events.push_back(event);
}
@@ -326,6 +333,14 @@
EXPECT_EQ(table.GetEventById(3), nullptr);
EXPECT_EQ(table.GetEventById(200), nullptr);
EXPECT_EQ(table.GetEventById(0), nullptr);
+ EXPECT_EQ(table.GetEventByName("foo")->ftrace_event_id, 1u);
+ EXPECT_THAT(*table.GetEventsByGroup("group_one"),
+ Contains(testing::Field(&Event::name, "foo")));
+ EXPECT_THAT(*table.GetEventsByGroup("group_one"),
+ Contains(testing::Field(&Event::name, "bar")));
+ EXPECT_THAT(*table.GetEventsByGroup("group_two"),
+ Contains(testing::Field(&Event::name, "baz")));
+ EXPECT_THAT(table.GetEventsByGroup("group_three"), IsNull());
}
} // namespace
diff --git a/src/perfetto_cmd/perfetto_cmd.cc b/src/perfetto_cmd/perfetto_cmd.cc
index 3c2bacd..144b008 100644
--- a/src/perfetto_cmd/perfetto_cmd.cc
+++ b/src/perfetto_cmd/perfetto_cmd.cc
@@ -138,7 +138,7 @@
test_config.SerializeToString(&trace_config_raw);
} else {
if (!base::ReadFile(optarg, &trace_config_raw)) {
- PERFETTO_ELOG("Could not open %s", optarg);
+ PERFETTO_PLOG("Could not open %s", optarg);
return 1;
}
}
diff --git a/src/traced/probes/filesystem/fs_mount.cc b/src/traced/probes/filesystem/fs_mount.cc
index 1db29ba..da2030e 100644
--- a/src/traced/probes/filesystem/fs_mount.cc
+++ b/src/traced/probes/filesystem/fs_mount.cc
@@ -44,7 +44,7 @@
const char* mountpoint = words.cur_token();
struct stat buf {};
if (stat(mountpoint, &buf) == -1) {
- PERFETTO_PLOG("stat");
+ PERFETTO_PLOG("stat %s", mountpoint);
continue;
}
device_to_mountpoints.emplace(buf.st_dev, mountpoint);