Skip to content

Commit

Permalink
Adjust the way we encode the dynamic size of allocation events
Browse files Browse the repository at this point in the history
  • Loading branch information
r1viollet committed Jul 5, 2023
1 parent b683df9 commit fb7350d
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 6 deletions.
11 changes: 10 additions & 1 deletion include/lib/allocation_event.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

namespace ddprof {

// AllocationEvent
// This represent a sampled allocation.
// We Keep the same layout as a perf event to unify the code paths.
struct AllocationEvent {
perf_event_header hdr;
struct sample_id sample_id;
Expand All @@ -19,6 +22,12 @@ struct AllocationEvent {
uint64_t size; /* if PERF_SAMPLE_STACK_USER */
std::byte data[1]; /* if PERF_SAMPLE_STACK_USER, the actual size will be
determined at runtime */
uint64_t dyn_size; /* if PERF_SAMPLE_STACK_USER && size != 0 */
// uint64_t dyn_size; /* added after the buffer */
};

static inline size_t SizeOfAllocationEvent(uint32_t stack_sample_user) {
// stack_sample_user is 8 byte aligned
// (Size of the event) + (stack size - 1) + sizeof(dyn_size field)
return sizeof(AllocationEvent) + stack_sample_user - 1 + sizeof(uint64_t);
}
} // namespace ddprof
14 changes: 9 additions & 5 deletions src/lib/allocation_tracker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -364,8 +364,8 @@ DDRes AllocationTracker::push_alloc_sample(uintptr_t addr,
DDRES_CHECK_FWD(push_lost_sample(writer, notify_consumer));
}

auto buffer = writer.reserve(sizeof(AllocationEvent) + _sample_stack_user - 1,
&timeout);
auto buffer =
writer.reserve(SizeOfAllocationEvent(_sample_stack_user), &timeout);

if (buffer.empty()) {
// ring buffer is full, increase lost count
Expand All @@ -381,7 +381,7 @@ DDRes AllocationTracker::push_alloc_sample(uintptr_t addr,

AllocationEvent *event = reinterpret_cast<AllocationEvent *>(buffer.data());
event->hdr.misc = 0;
event->hdr.size = sizeof(AllocationEvent);
event->hdr.size = SizeOfAllocationEvent(_sample_stack_user);
event->hdr.type = PERF_RECORD_SAMPLE;
event->abi = PERF_SAMPLE_REGS_ABI_64;
event->sample_id.time = 0;
Expand All @@ -406,8 +406,12 @@ DDRes AllocationTracker::push_alloc_sample(uintptr_t addr,
event->period = allocated_size;
event->size = _sample_stack_user;

event->dyn_size = save_context(tl_state.stack_bounds, event->regs,
ddprof::Buffer{event->data, event->size});
std::byte *dyn_size_pos = event->data + _sample_stack_user;
uint64_t *dyn_size = reinterpret_cast<uint64_t *>(dyn_size_pos);
assert(reinterpret_cast<uintptr_t>(dyn_size) % alignof(uint64_t) == 0);

(*dyn_size) = save_context(tl_state.stack_bounds, event->regs,
ddprof::Buffer{event->data, event->size});
// Even if dyn_size == 0, we keep the sample
// This way, the overall accounting is correct (even with empty stacks)
if (writer.commit(buffer) || notify_consumer) {
Expand Down

0 comments on commit fb7350d

Please sign in to comment.