Files
clang-p2996/lldb/source/Plugins/Process/Linux/IntelPTSingleBufferTrace.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

120 lines
3.9 KiB
C++

//===-- IntelPTSingleBufferTrace.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_IntelPTSingleBufferTrace_H_
#define liblldb_IntelPTSingleBufferTrace_H_
#include "Perf.h"
#include "lldb/Utility/TraceIntelPTGDBRemotePackets.h"
#include "lldb/lldb-types.h"
#include "llvm/Support/Error.h"
#include <memory>
namespace lldb_private {
namespace process_linux {
llvm::Expected<uint32_t> GetIntelPTOSEventType();
/// This class wraps a single perf event collecting intel pt data in a single
/// buffer.
class IntelPTSingleBufferTrace {
public:
/// Start tracing using a single Intel PT trace buffer.
///
/// \param[in] request
/// Intel PT configuration parameters.
///
/// \param[in] tid
/// The tid of the thread to be traced. If \b None, then this traces all
/// threads of all processes.
///
/// \param[in] cpu_id
/// The CPU core id where to trace. If \b None, then this traces all CPUs.
///
/// \param[in] disabled
/// If \b true, then no data is collected until \a Resume is invoked.
/// Similarly, if \b false, data is collected right away until \a Pause is
/// invoked.
///
/// \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
/// A \a IntelPTSingleBufferTrace instance if tracing was successful, or
/// an \a llvm::Error otherwise.
static llvm::Expected<IntelPTSingleBufferTrace>
Start(const TraceIntelPTStartRequest &request,
llvm::Optional<lldb::tid_t> tid,
llvm::Optional<lldb::cpu_id_t> cpu_id = llvm::None,
bool disabled = false, llvm::Optional<int> cgroup_fd = llvm::None);
/// \return
/// The bytes requested by a jLLDBTraceGetBinaryData packet that was routed
/// to this trace instace.
llvm::Expected<std::vector<uint8_t>>
GetBinaryData(const TraceGetBinaryDataRequest &request) const;
/// Read the intel pt trace buffer managed by this trace instance. To ensure
/// that the data is up-to-date and is not corrupted by read-write race
/// conditions, the underlying perf_event is paused during read, and later
/// it's returned to its initial state.
///
/// \return
/// A vector with the requested binary data.
llvm::Expected<std::vector<uint8_t>> GetIptTrace();
/// \return
/// The total the size in bytes used by the intel pt trace buffer managed
/// by this trace instance.
size_t GetIptTraceSize() const;
/// Resume the collection of this trace.
///
/// \return
/// An error if the trace couldn't be resumed. If the trace is already
/// running, this returns \a Error::success().
llvm::Error Resume();
/// Pause the collection of this trace.
///
/// \return
/// An error if the trace couldn't be paused. If the trace is already
/// paused, this returns \a Error::success().
llvm::Error Pause();
/// \return
/// The underlying PerfEvent for this trace.
const PerfEvent &GetPerfEvent() const;
private:
/// Construct new \a IntelPTSingleBufferThreadTrace. Users are supposed to
/// create instances of this class via the \a Start() method and not invoke
/// this one directly.
///
/// \param[in] perf_event
/// perf event configured for IntelPT.
///
/// \param[in] collection_state
/// The initial collection state for the provided perf_event.
IntelPTSingleBufferTrace(PerfEvent &&perf_event)
: m_perf_event(std::move(perf_event)) {}
/// perf event configured for IntelPT.
PerfEvent m_perf_event;
};
} // namespace process_linux
} // namespace lldb_private
#endif // liblldb_IntelPTSingleBufferTrace_H_