Files
clang-p2996/lldb/source/Plugins/Process/Linux/IntelPTMultiCoreTrace.h
Gaurav Gaur d30fd5c3a1 [trace][intel pt] Add a cgroup filter
It turns out that cgroup filtering is relatively trivial and works
really nicely. Thid diffs adds automatic cgroup filtering when in
per-cpu mode, unless a new --disable-cgroup-filtering flag is passed in
the start command. At least on Meta machines, all processes are spawned
inside a cgroup by default, which comes super handy, because per cpu
tracing is now much more precise.

A manual test gave me this result

- Without filtering:
    Total number of trace items: 36083
    Total number of continuous executions found: 229
    Number of continuous executions for this thread: 2
    Total number of PSB blocks found: 98
    Number of PSB blocks for this thread 2
    Total number of unattributed PSB blocks found: 38

- With filtering:
    Total number of trace items: 87756
    Total number of continuous executions found: 123
    Number of continuous executions for this thread: 2
    Total number of PSB blocks found: 10
    Number of PSB blocks for this thread 3
    Total number of unattributed PSB blocks found: 2

Filtering gives us great results. The number of instructions collected
more than double (probalby because we have less noise in the trace), and
we have much less unattributed PSBs blocks and unrelated PSBs in
general. The ones that are unrelated probably belong to other processes
in the same cgroup.

Differential Revision: https://reviews.llvm.org/D129257
2022-07-13 12:26:11 -07:00

116 lines
3.8 KiB
C++

//===-- IntelPTMultiCoreTrace.h ------------------------------- -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef liblldb_IntelPTMultiCoreTrace_H_
#define liblldb_IntelPTMultiCoreTrace_H_
#include "IntelPTProcessTrace.h"
#include "IntelPTSingleBufferTrace.h"
#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/Utility/TraceIntelPTGDBRemotePackets.h"
#include "lldb/lldb-types.h"
#include "llvm/Support/Error.h"
#include <memory>
namespace lldb_private {
namespace process_linux {
class IntelPTMultiCoreTrace : public IntelPTProcessTrace {
using ContextSwitchTrace = PerfEvent;
public:
/// Start tracing all CPU cores.
///
/// \param[in] request
/// Intel PT configuration parameters.
///
/// \param[in] process
/// The process being debugged.
///
/// \param[in] cgroup_fd
/// A file descriptor in /sys/fs associated with the cgroup of the process to
/// trace. If not \a llvm::None, then the trace sesion will use cgroup
/// filtering.
///
/// \return
/// An \a IntelPTMultiCoreTrace instance if tracing was successful, or
/// an \a llvm::Error otherwise.
static llvm::Expected<std::unique_ptr<IntelPTMultiCoreTrace>>
StartOnAllCores(const TraceIntelPTStartRequest &request,
NativeProcessProtocol &process,
llvm::Optional<int> cgroup_fd = llvm::None);
/// Execute the provided callback on each core that is being traced.
///
/// \param[in] callback.cpu_id
/// The core id that is being traced.
///
/// \param[in] callback.core_trace
/// The single-buffer trace instance for the given core.
void ForEachCore(std::function<void(lldb::cpu_id_t cpu_id,
IntelPTSingleBufferTrace &core_trace)>
callback);
/// Execute the provided callback on each core that is being traced.
///
/// \param[in] callback.cpu_id
/// The core id that is being traced.
///
/// \param[in] callback.intelpt_trace
/// The single-buffer intel pt trace instance for the given core.
///
/// \param[in] callback.context_switch_trace
/// The perf event collecting context switches for the given core.
void ForEachCore(std::function<void(lldb::cpu_id_t cpu_id,
IntelPTSingleBufferTrace &intelpt_trace,
ContextSwitchTrace &context_switch_trace)>
callback);
void ProcessDidStop() override;
void ProcessWillResume() override;
TraceIntelPTGetStateResponse GetState() override;
bool TracesThread(lldb::tid_t tid) const override;
llvm::Error TraceStart(lldb::tid_t tid) override;
llvm::Error TraceStop(lldb::tid_t tid) override;
llvm::Expected<llvm::Optional<std::vector<uint8_t>>>
TryGetBinaryData(const TraceGetBinaryDataRequest &request) override;
private:
/// This assumes that all underlying perf_events for each core are part of the
/// same perf event group.
IntelPTMultiCoreTrace(
llvm::DenseMap<lldb::cpu_id_t,
std::pair<IntelPTSingleBufferTrace, ContextSwitchTrace>>
&&traces_per_core,
NativeProcessProtocol &process, bool using_cgroup_filtering)
: m_traces_per_core(std::move(traces_per_core)), m_process(process),
m_using_cgroup_filtering(using_cgroup_filtering) {}
llvm::DenseMap<lldb::cpu_id_t,
std::pair<IntelPTSingleBufferTrace, ContextSwitchTrace>>
m_traces_per_core;
/// The target process.
NativeProcessProtocol &m_process;
bool m_using_cgroup_filtering;
};
} // namespace process_linux
} // namespace lldb_private
#endif // liblldb_IntelPTMultiCoreTrace_H_