LLDB  mainline
Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | List of all members
lldb_private::process_linux::PerfEvent Class Reference

Thin wrapper of the perf_event_open API. More...

#include <Perf.h>

Collaboration diagram for lldb_private::process_linux::PerfEvent:
Collaboration graph
[legend]

Public Member Functions

llvm::Error MmapMetadataAndBuffers (size_t num_data_pages, size_t num_aux_pages, bool data_buffer_write)
 Mmap the metadata page and the data and aux buffers of the perf event and expose them through PerfEvent::GetMetadataPage() , PerfEvent::GetDataBuffer() and PerfEvent::GetAuxBuffer(). More...
 
long GetFd () const
 Get the file descriptor associated with the perf event. More...
 
perf_event_mmap_page & GetMetadataPage () const
 Get the metadata page from the data section's mmap buffer. More...
 
llvm::ArrayRef< uint8_t > GetDataBuffer () const
 Get the data buffer from the data section's mmap buffer. More...
 
llvm::ArrayRef< uint8_t > GetAuxBuffer () const
 Get the AUX buffer. More...
 
llvm::Expected< std::vector< uint8_t > > GetReadOnlyAuxBuffer ()
 Read the aux buffer managed by this perf event assuming it was configured with PROT_READ permissions only, which indicates that the buffer is automatically wrapped and overwritten by the kernel or hardware. More...
 
llvm::Expected< std::vector< uint8_t > > GetReadOnlyDataBuffer ()
 Read the data buffer managed by this perf even assuming it was configured with PROT_READ permissions only, which indicates that the buffer is automatically wrapped and overwritten by the kernel or hardware. More...
 
llvm::Error DisableWithIoctl ()
 Use the ioctl API to disable the perf event and all the events in its group. More...
 
llvm::Error EnableWithIoctl ()
 Use the ioctl API to enable the perf event and all the events in its group. More...
 
size_t GetEffectiveDataBufferSize () const
 
bool IsEnabled () const
 

Static Public Member Functions

static llvm::Expected< PerfEventInit (perf_event_attr &attr, llvm::Optional< lldb::pid_t > pid, llvm::Optional< lldb::cpu_id_t > cpu, llvm::Optional< long > group_fd, unsigned long flags)
 Create a new performance monitoring event via the perf_event_open syscall. More...
 
static llvm::Expected< PerfEventInit (perf_event_attr &attr, llvm::Optional< lldb::pid_t > pid, llvm::Optional< lldb::cpu_id_t > core=llvm::None)
 Create a new performance monitoring event via the perf_event_open syscall with "default" values for the cpu, group_fd and flags arguments. More...
 

Private Member Functions

 PerfEvent (long fd, bool enabled)
 Create new PerfEvent. More...
 
llvm::Expected< resource_handle::MmapUPDoMmap (void *addr, size_t length, int prot, int flags, long int offset, llvm::StringRef buffer_name)
 Wrapper for mmap to provide custom error messages. More...
 
llvm::Error MmapMetadataAndDataBuffer (size_t num_data_pages, bool data_buffer_write)
 Mmap the data buffer of the perf event. More...
 
llvm::Error MmapAuxBuffer (size_t num_aux_pages)
 Mmap the aux buffer of the perf event. More...
 

Private Attributes

resource_handle::FileDescriptorUP m_fd
 The file descriptor representing the perf event. More...
 
resource_handle::MmapUP m_metadata_data_base
 Metadata page and data section where perf samples are stored. More...
 
resource_handle::MmapUP m_aux_base
 AUX buffer is a separate region for high-bandwidth data streams such as IntelPT. More...
 
bool m_enabled
 The state of the underlying perf_event. More...
 

Detailed Description

Thin wrapper of the perf_event_open API.

Exposes the metadata page and data and aux buffers of a perf event. Handles the management of the event's file descriptor and mmap'ed regions.

Definition at line 80 of file Perf.h.

Constructor & Destructor Documentation

◆ PerfEvent()

lldb_private::process_linux::PerfEvent::PerfEvent ( long  fd,
bool  enabled 
)
inlineprivate

Create new PerfEvent.

Parameters
[in]fdFile descriptor of the perf event.
[in]enabledInitial collection state configured for this perf_event.

Definition at line 260 of file Perf.h.

Member Function Documentation

◆ DisableWithIoctl()

Error PerfEvent::DisableWithIoctl ( )

Use the ioctl API to disable the perf event and all the events in its group.

This doesn't terminate the perf event.

This is no-op if the perf event is already disabled.

Returns
An Error if the perf event couldn't be disabled.

Definition at line 269 of file Perf.cpp.

◆ DoMmap()

llvm::Expected< resource_handle::MmapUP > PerfEvent::DoMmap ( void *  addr,
size_t  length,
int  prot,
int  flags,
long int  offset,
llvm::StringRef  buffer_name 
)
private

Wrapper for mmap to provide custom error messages.

The parameters are directly forwarded to a mmap syscall, for information on the parameters visit https://man7.org/linux/man-pages/man2/mmap.2.html.

The value of GetFd() is passed as the fd argument to mmap.

Definition at line 101 of file Perf.cpp.

References string().

◆ EnableWithIoctl()

Error PerfEvent::EnableWithIoctl ( )

Use the ioctl API to enable the perf event and all the events in its group.

This is no-op if the perf event is already enabled.

Returns
An Error if the perf event couldn't be enabled.

Definition at line 284 of file Perf.cpp.

◆ GetAuxBuffer()

ArrayRef< uint8_t > PerfEvent::GetAuxBuffer ( ) const

Get the AUX buffer.

AUX buffer is a region for high-bandwidth data streams such as IntelPT. This is separate from the metadata and data buffer.

This should be called only after PerfEvent::MmapMetadataAndBuffers, otherwise a failure might happen.

Returns
ArrayRef<uint8_t> extending aux_size bytes from aux_offset.

Definition at line 179 of file Perf.cpp.

◆ GetDataBuffer()

ArrayRef< uint8_t > PerfEvent::GetDataBuffer ( ) const

Get the data buffer from the data section's mmap buffer.

The data buffer is the region of the data section's mmap buffer where perf sample data is located.

This should be called only after PerfEvent::MmapMetadataAndBuffers, otherwise a failure might happen.

Returns
ArrayRef<uint8_t> extending data_size bytes from data_offset.

Definition at line 172 of file Perf.cpp.

◆ GetEffectiveDataBufferSize()

size_t PerfEvent::GetEffectiveDataBufferSize ( ) const
Returns
The size in bytes of the section of the data buffer that has effective data.

Definition at line 297 of file Perf.cpp.

Referenced by lldb_private::process_linux::IntelPTMultiCoreTrace::GetState().

◆ GetFd()

long PerfEvent::GetFd ( ) const

Get the file descriptor associated with the perf event.

Definition at line 166 of file Perf.cpp.

Referenced by lldb_private::process_linux::CreateContextSwitchTracePerfEvent().

◆ GetMetadataPage()

perf_event_mmap_page & PerfEvent::GetMetadataPage ( ) const

Get the metadata page from the data section's mmap buffer.

The metadata page is always mmap'ed, even when num_data_pages is 0.

This should be called only after PerfEvent::MmapMetadataAndBuffers, otherwise a failure might happen.

Returns
The data section's perf_event_mmap_page.

Definition at line 168 of file Perf.cpp.

◆ GetReadOnlyAuxBuffer()

Expected< std::vector< uint8_t > > PerfEvent::GetReadOnlyAuxBuffer ( )

Read the aux buffer managed by this perf event assuming it was configured with PROT_READ permissions only, which indicates that the buffer is automatically wrapped and overwritten by the kernel or hardware.

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. The returned data will be linear, i.e. it will fix the circular wrapping the might exist in the buffer.

Returns
A vector with the requested binary data.

When configured as ring buffer, the aux buffer keeps wrapping around the buffer and its not possible to detect how many times the buffer wrapped. Initially the buffer is filled with zeros,as shown below so in order to get complete buffer we first copy firstpartsize, followed by any left over part from beginning to aux_head

aux_offset [d,d,d,d,d,d,d,d,0,0,0,0,0,0,0,0,0,0,0] aux_size aux_head->||<- firstpartsize ->|

Definition at line 229 of file Perf.cpp.

◆ GetReadOnlyDataBuffer()

Expected< std::vector< uint8_t > > PerfEvent::GetReadOnlyDataBuffer ( )

Read the data buffer managed by this perf even assuming it was configured with PROT_READ permissions only, which indicates that the buffer is automatically wrapped and overwritten by the kernel or hardware.

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. The returned data will be linear, i.e. it will fix the circular wrapping the might exist int he buffer.

Returns
A vector with the requested binary data.

The data buffer and aux buffer have different implementations with respect to their definition of head pointer when using PROD_READ only. In the case of Aux data buffer the head always wraps around the aux buffer and we don't need to care about it, whereas the data_head keeps increasing and needs to be wrapped by modulus operator

Definition at line 185 of file Perf.cpp.

◆ Init() [1/2]

static llvm::Expected<PerfEvent> lldb_private::process_linux::PerfEvent::Init ( perf_event_attr &  attr,
llvm::Optional< lldb::pid_t pid,
llvm::Optional< lldb::cpu_id_t core = llvm::None 
)
static

Create a new performance monitoring event via the perf_event_open syscall with "default" values for the cpu, group_fd and flags arguments.

Convenience method to be used when the perf event requires minimal configuration. It handles the default values of all other arguments.

Parameters
[in]attrConfiguration information for the event.
[in]pidThe process or thread to be monitored by the event. If None, then all threads and processes are monitored.

◆ Init() [2/2]

static llvm::Expected<PerfEvent> lldb_private::process_linux::PerfEvent::Init ( perf_event_attr &  attr,
llvm::Optional< lldb::pid_t pid,
llvm::Optional< lldb::cpu_id_t cpu,
llvm::Optional< long >  group_fd,
unsigned long  flags 
)
static

Create a new performance monitoring event via the perf_event_open syscall.

The parameters are directly forwarded to a perf_event_open syscall, for additional information on the parameters visit https://man7.org/linux/man-pages/man2/perf_event_open.2.html.

Parameters
[in]attrConfiguration information for the event.
[in]pidThe process or thread to be monitored by the event. If None, then all processes and threads are monitored.
[in]cpuThe cpu to be monitored by the event. If None, then all cpus are monitored.
[in]group_fdFile descriptor of the group leader. If None, then this perf_event doesn't belong to a preexisting group.
[in]flagsBitmask of additional configuration flags.
Returns
If the perf_event_open syscall was successful, a minimal PerfEvent instance, or an llvm::Error otherwise.

Referenced by lldb_private::process_linux::CreateContextSwitchTracePerfEvent(), and lldb_private::process_linux::LoadPerfTscConversionParameters().

◆ IsEnabled()

bool PerfEvent::IsEnabled ( ) const
Returns
true if and only the perf event is enabled and collecting.

Definition at line 282 of file Perf.cpp.

Referenced by lldb_private::process_linux::CreateContextSwitchTracePerfEvent().

◆ MmapAuxBuffer()

llvm::Error PerfEvent::MmapAuxBuffer ( size_t  num_aux_pages)
private

Mmap the aux buffer of the perf event.

Parameters
[in]num_aux_pagesNumber of pages in the aux buffer to mmap, must be a power of 2. A value of 0 effectively is a no-op and no data is mmap'ed for this buffer.

Definition at line 127 of file Perf.cpp.

References PROT_READ.

◆ MmapMetadataAndBuffers()

llvm::Error PerfEvent::MmapMetadataAndBuffers ( size_t  num_data_pages,
size_t  num_aux_pages,
bool  data_buffer_write 
)

Mmap the metadata page and the data and aux buffers of the perf event and expose them through PerfEvent::GetMetadataPage() , PerfEvent::GetDataBuffer() and PerfEvent::GetAuxBuffer().

This uses mmap underneath, which means that the number of pages mmap'ed must be less than the actual data available by the kernel. The metadata page is always mmap'ed.

Mmap is needed because the underlying data might be changed by the kernel dynamically.

Parameters
[in]num_data_pagesNumber of pages in the data buffer to mmap, must be a power of 2. A value of 0 is useful for "dummy" events that only want to access the metadata, perf_event_mmap_page, or the aux buffer.
[in]num_aux_pagesNumber of pages in the aux buffer to mmap, must be a power of 2. A value of 0 effectively is a no-op and no data is mmap'ed for this buffer.
[in]data_buffer_writeWhether to mmap the data buffer with WRITE permissions. This changes the behavior of how the kernel writes to the data buffer.
Returns
llvm::Error::success if the mmap operations succeeded, or an llvm::Error otherwise.

Definition at line 146 of file Perf.cpp.

◆ MmapMetadataAndDataBuffer()

llvm::Error PerfEvent::MmapMetadataAndDataBuffer ( size_t  num_data_pages,
bool  data_buffer_write 
)
private

Mmap the data buffer of the perf event.

Parameters
[in]num_data_pagesNumber of pages in the data buffer to mmap, must be a power of 2. A value of 0 is useful for "dummy" events that only want to access the metadata, perf_event_mmap_page, or the aux buffer.
[in]data_buffer_writeWhether to mmap the data buffer with WRITE permissions. This changes the behavior of how the kernel writes to the data buffer.

Definition at line 115 of file Perf.cpp.

References PROT_READ, and PROT_WRITE.

Member Data Documentation

◆ m_aux_base

resource_handle::MmapUP lldb_private::process_linux::PerfEvent::m_aux_base
private

AUX buffer is a separate region for high-bandwidth data streams such as IntelPT.

Definition at line 303 of file Perf.h.

◆ m_enabled

bool lldb_private::process_linux::PerfEvent::m_enabled
private

The state of the underlying perf_event.

Definition at line 305 of file Perf.h.

◆ m_fd

resource_handle::FileDescriptorUP lldb_private::process_linux::PerfEvent::m_fd
private

The file descriptor representing the perf event.

Definition at line 298 of file Perf.h.

◆ m_metadata_data_base

resource_handle::MmapUP lldb_private::process_linux::PerfEvent::m_metadata_data_base
private

Metadata page and data section where perf samples are stored.

Definition at line 300 of file Perf.h.


The documentation for this class was generated from the following files: