Add SysStats data source (/proc/{meminfo,stat,vmstat})
Adds a new data source for polling /proc counters.
The polling rate and the counters can be individually
set in the trace config.
The cost (CPU time) of polling and parsing these files,
measured on a Pixel 2, running on little core, is:
- /proc/meminfo: 0.3 ms [read] + 0.07 ms [parse + trace injection]
- /proc/vmstat: 0.2 ms [read] + 0.3 ms [parse + trace injection]
- /proc/stat: 4.1 ms [read] + 1.9 ms [parse + trace injection]
SELinux: aosp/759260
Bug: b/115956288
Test: perfetto_unittests --gtest_filter=SysStatsDataSourceTest.*
Change-Id: I2805f713d418ba6bda9550f11bfce137b378bc1b
diff --git a/src/traced/probes/probes_producer.cc b/src/traced/probes/probes_producer.cc
index e56eb73..cc90242 100644
--- a/src/traced/probes/probes_producer.cc
+++ b/src/traced/probes/probes_producer.cc
@@ -50,6 +50,7 @@
constexpr char kFtraceSourceName[] = "linux.ftrace";
constexpr char kProcessStatsSourceName[] = "linux.process_stats";
constexpr char kInodeMapSourceName[] = "linux.inode_file_map";
+constexpr char kSysStatsSourceName[] = "linux.sys_stats";
} // namespace.
@@ -74,17 +75,29 @@
ResetConnectionBackoff();
PERFETTO_LOG("Connected to the service");
- DataSourceDescriptor ftrace_descriptor;
- ftrace_descriptor.set_name(kFtraceSourceName);
- endpoint_->RegisterDataSource(ftrace_descriptor);
+ {
+ DataSourceDescriptor desc;
+ desc.set_name(kFtraceSourceName);
+ endpoint_->RegisterDataSource(desc);
+ }
- DataSourceDescriptor process_stats_descriptor;
- process_stats_descriptor.set_name(kProcessStatsSourceName);
- endpoint_->RegisterDataSource(process_stats_descriptor);
+ {
+ DataSourceDescriptor desc;
+ desc.set_name(kProcessStatsSourceName);
+ endpoint_->RegisterDataSource(desc);
+ }
- DataSourceDescriptor inode_map_descriptor;
- inode_map_descriptor.set_name(kInodeMapSourceName);
- endpoint_->RegisterDataSource(inode_map_descriptor);
+ {
+ DataSourceDescriptor desc;
+ desc.set_name(kInodeMapSourceName);
+ endpoint_->RegisterDataSource(desc);
+ }
+
+ {
+ DataSourceDescriptor desc;
+ desc.set_name(kSysStatsSourceName);
+ endpoint_->RegisterDataSource(desc);
+ }
}
void ProbesProducer::OnDisconnect() {
@@ -129,6 +142,8 @@
data_source = CreateInodeFileDataSource(session_id, instance_id, config);
} else if (config.name() == kProcessStatsSourceName) {
data_source = CreateProcessStatsDataSource(session_id, instance_id, config);
+ } else if (config.name() == kSysStatsSourceName) {
+ data_source = CreateSysStatsDataSource(session_id, instance_id, config);
}
if (!data_source) {
@@ -214,6 +229,18 @@
return std::move(data_source);
}
+std::unique_ptr<SysStatsDataSource> ProbesProducer::CreateSysStatsDataSource(
+ TracingSessionID session_id,
+ DataSourceInstanceID id,
+ const DataSourceConfig& config) {
+ base::ignore_result(id);
+ auto buffer_id = static_cast<BufferID>(config.target_buffer());
+ auto data_source = std::unique_ptr<SysStatsDataSource>(
+ new SysStatsDataSource(task_runner_, session_id,
+ endpoint_->CreateTraceWriter(buffer_id), config));
+ return data_source;
+}
+
void ProbesProducer::TearDownDataSourceInstance(DataSourceInstanceID id) {
PERFETTO_LOG("Producer stop (id=%" PRIu64 ")", id);
auto it = data_sources_.find(id);
@@ -290,6 +317,8 @@
case ProcessStatsDataSource::kTypeId:
ps_data_source = static_cast<ProcessStatsDataSource*>(ds);
break;
+ case SysStatsDataSource::kTypeId:
+ break;
default:
PERFETTO_DCHECK(false);
} // switch (type_id)