aboutsummaryrefslogtreecommitdiff
path: root/src/traced/probes/ftrace/compact_sched.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/traced/probes/ftrace/compact_sched.cc')
-rw-r--r--src/traced/probes/ftrace/compact_sched.cc283
1 files changed, 0 insertions, 283 deletions
diff --git a/src/traced/probes/ftrace/compact_sched.cc b/src/traced/probes/ftrace/compact_sched.cc
deleted file mode 100644
index 7ca8526f2..000000000
--- a/src/traced/probes/ftrace/compact_sched.cc
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/traced/probes/ftrace/compact_sched.h"
-
-#include <stdint.h>
-
-#include "perfetto/ext/base/optional.h"
-#include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
-#include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
-#include "protos/perfetto/trace/ftrace/sched.pbzero.h"
-#include "src/traced/probes/ftrace/event_info_constants.h"
-
-namespace perfetto {
-
-namespace {
-
-// Pre-parse the format of sched_switch, checking if our simplifying
-// assumptions about possible widths/signedness hold, and record the subset
-// of the format that will be used during parsing.
-base::Optional<CompactSchedSwitchFormat> ValidateSchedSwitchFormat(
- const Event& event) {
- using protos::pbzero::SchedSwitchFtraceEvent;
-
- CompactSchedSwitchFormat switch_format;
- switch_format.event_id = event.ftrace_event_id;
- switch_format.size = event.size;
-
- bool prev_state_valid = false;
- bool next_pid_valid = false;
- bool next_prio_valid = false;
- bool next_comm_valid = false;
- for (const auto& field : event.fields) {
- switch (field.proto_field_id) {
- case SchedSwitchFtraceEvent::kPrevStateFieldNumber:
- switch_format.prev_state_offset = field.ftrace_offset;
- switch_format.prev_state_type = field.ftrace_type;
-
- // kernel type: long
- prev_state_valid = (field.ftrace_type == kFtraceInt32 ||
- field.ftrace_type == kFtraceInt64);
- break;
-
- case SchedSwitchFtraceEvent::kNextPidFieldNumber:
- switch_format.next_pid_offset = field.ftrace_offset;
- switch_format.next_pid_type = field.ftrace_type;
-
- // kernel type: pid_t
- next_pid_valid = (field.ftrace_type == kFtracePid32);
- break;
-
- case SchedSwitchFtraceEvent::kNextPrioFieldNumber:
- switch_format.next_prio_offset = field.ftrace_offset;
- switch_format.next_prio_type = field.ftrace_type;
-
- // kernel type: int
- next_prio_valid = (field.ftrace_type == kFtraceInt32);
- break;
-
- case SchedSwitchFtraceEvent::kNextCommFieldNumber:
- switch_format.next_comm_offset = field.ftrace_offset;
-
- next_comm_valid =
- (field.ftrace_type == kFtraceFixedCString &&
- field.ftrace_size == CommInterner::kExpectedCommLength);
- break;
- default:
- break;
- }
- }
-
- if (!prev_state_valid || !next_pid_valid || !next_prio_valid ||
- !next_comm_valid) {
- return base::nullopt;
- }
- return base::make_optional(switch_format);
-}
-
-// Pre-parse the format of sched_waking, checking if our simplifying
-// assumptions about possible widths/signedness hold, and record the subset
-// of the format that will be used during parsing.
-base::Optional<CompactSchedWakingFormat> ValidateSchedWakingFormat(
- const Event& event) {
- using protos::pbzero::SchedWakingFtraceEvent;
-
- CompactSchedWakingFormat waking_format;
- waking_format.event_id = event.ftrace_event_id;
- waking_format.size = event.size;
-
- bool pid_valid = false;
- bool target_cpu_valid = false;
- bool prio_valid = false;
- bool comm_valid = false;
- for (const auto& field : event.fields) {
- switch (field.proto_field_id) {
- case SchedWakingFtraceEvent::kPidFieldNumber:
- waking_format.pid_offset = field.ftrace_offset;
- waking_format.pid_type = field.ftrace_type;
-
- // kernel type: pid_t
- pid_valid = (field.ftrace_type == kFtracePid32);
- break;
-
- case SchedWakingFtraceEvent::kTargetCpuFieldNumber:
- waking_format.target_cpu_offset = field.ftrace_offset;
- waking_format.target_cpu_type = field.ftrace_type;
-
- // kernel type: int
- target_cpu_valid = (field.ftrace_type == kFtraceInt32);
- break;
-
- case SchedWakingFtraceEvent::kPrioFieldNumber:
- waking_format.prio_offset = field.ftrace_offset;
- waking_format.prio_type = field.ftrace_type;
-
- // kernel type: int
- prio_valid = (field.ftrace_type == kFtraceInt32);
- break;
-
- case SchedWakingFtraceEvent::kCommFieldNumber:
- waking_format.comm_offset = field.ftrace_offset;
-
- comm_valid = (field.ftrace_type == kFtraceFixedCString &&
- field.ftrace_size == CommInterner::kExpectedCommLength);
- break;
- default:
- break;
- }
- }
-
- if (!pid_valid || !target_cpu_valid || !prio_valid || !comm_valid) {
- return base::nullopt;
- }
- return base::make_optional(waking_format);
-}
-
-} // namespace
-
-// TODO(rsavitski): could avoid looping over all events if the caller did the
-// work to remember the relevant events (translation table construction already
-// loops over them).
-CompactSchedEventFormat ValidateFormatForCompactSched(
- const std::vector<Event>& events) {
- using protos::pbzero::FtraceEvent;
-
- base::Optional<CompactSchedSwitchFormat> switch_format;
- base::Optional<CompactSchedWakingFormat> waking_format;
- for (const Event& event : events) {
- if (event.proto_field_id == FtraceEvent::kSchedSwitchFieldNumber) {
- switch_format = ValidateSchedSwitchFormat(event);
- }
- if (event.proto_field_id == FtraceEvent::kSchedWakingFieldNumber) {
- waking_format = ValidateSchedWakingFormat(event);
- }
- }
-
- if (switch_format.has_value() && waking_format.has_value()) {
- return CompactSchedEventFormat{/*format_valid=*/true, switch_format.value(),
- waking_format.value()};
- } else {
- PERFETTO_ELOG("Unexpected sched_switch or sched_waking format.");
- return CompactSchedEventFormat{/*format_valid=*/false,
- CompactSchedSwitchFormat{},
- CompactSchedWakingFormat{}};
- }
-}
-
-CompactSchedEventFormat InvalidCompactSchedEventFormatForTesting() {
- return CompactSchedEventFormat{/*format_valid=*/false,
- CompactSchedSwitchFormat{},
- CompactSchedWakingFormat{}};
-}
-
-// TODO(rsavitski): find the correct place in the trace for, and method of,
-// reporting rejection of compact_sched due to compile-time assumptions not
-// holding at runtime.
-CompactSchedConfig CreateCompactSchedConfig(
- const FtraceConfig& request,
- const CompactSchedEventFormat& compact_format) {
- if (!request.compact_sched().enabled())
- return CompactSchedConfig{/*enabled=*/false};
-
- if (!compact_format.format_valid)
- return CompactSchedConfig{/*enabled=*/false};
-
- return CompactSchedConfig{/*enabled=*/true};
-}
-
-CompactSchedConfig EnabledCompactSchedConfigForTesting() {
- return CompactSchedConfig{/*enabled=*/true};
-}
-
-CompactSchedConfig DisabledCompactSchedConfigForTesting() {
- return CompactSchedConfig{/*enabled=*/false};
-}
-
-// Sanity check size of stack-allocated bundle state.
-static_assert(sizeof(CompactSchedBuffer) <= 1 << 18,
- "CompactSchedBuffer's on-stack size excessively large.");
-
-void CompactSchedSwitchBuffer::Write(
- protos::pbzero::FtraceEventBundle::CompactSched* compact_out) const {
- compact_out->set_switch_timestamp(timestamp_);
- compact_out->set_switch_next_pid(next_pid_);
- compact_out->set_switch_prev_state(prev_state_);
- compact_out->set_switch_next_prio(next_prio_);
- compact_out->set_switch_next_comm_index(next_comm_index_);
-}
-
-void CompactSchedSwitchBuffer::Reset() {
- last_timestamp_ = 0;
- timestamp_.Reset();
- next_pid_.Reset();
- prev_state_.Reset();
- next_prio_.Reset();
- next_comm_index_.Reset();
-}
-
-void CompactSchedWakingBuffer::Write(
- protos::pbzero::FtraceEventBundle::CompactSched* compact_out) const {
- compact_out->set_waking_timestamp(timestamp_);
- compact_out->set_waking_pid(pid_);
- compact_out->set_waking_target_cpu(target_cpu_);
- compact_out->set_waking_prio(prio_);
- compact_out->set_waking_comm_index(comm_index_);
-}
-
-void CompactSchedWakingBuffer::Reset() {
- last_timestamp_ = 0;
- timestamp_.Reset();
- pid_.Reset();
- target_cpu_.Reset();
- prio_.Reset();
- comm_index_.Reset();
-}
-
-void CommInterner::Write(
- protos::pbzero::FtraceEventBundle::CompactSched* compact_out) const {
- for (size_t i = 0; i < interned_comms_size_; i++) {
- compact_out->add_intern_table(interned_comms_[i].data(),
- interned_comms_[i].size());
- }
-}
-
-void CommInterner::Reset() {
- intern_buf_write_pos_ = 0;
- interned_comms_size_ = 0;
-}
-
-void CompactSchedBuffer::WriteAndReset(
- protos::pbzero::FtraceEventBundle* bundle) {
- if (switch_.size() > 0 || waking_.size() > 0) {
- auto* compact_out = bundle->set_compact_sched();
-
- PERFETTO_DCHECK(interner_.interned_comms_size() > 0);
- interner_.Write(compact_out);
-
- if (switch_.size() > 0)
- switch_.Write(compact_out);
-
- if (waking_.size() > 0)
- waking_.Write(compact_out);
- }
-
- interner_.Reset();
- switch_.Reset();
- waking_.Reset();
-}
-
-} // namespace perfetto