Loading include/linux/perf_event.h +12 −1 Original line number Diff line number Diff line Loading @@ -215,8 +215,9 @@ struct perf_event_attr { */ precise_ip : 2, /* skid constraint */ mmap_data : 1, /* non-exec mmap data */ sample_id_all : 1, /* sample_type all events */ __reserved_1 : 46; __reserved_1 : 45; union { __u32 wakeup_events; /* wakeup every n events */ Loading Loading @@ -327,6 +328,15 @@ struct perf_event_header { enum perf_event_type { /* * If perf_event_attr.sample_id_all is set then all event types will * have the sample_type selected fields related to where/when * (identity) an event took place (TID, TIME, ID, CPU, STREAM_ID) * described in PERF_RECORD_SAMPLE below, it will be stashed just after * the perf_event_header and the fields already present for the existing * fields, i.e. at the end of the payload. That way a newer perf.data * file will be supported by older perf tools, with these new optional * fields being ignored. * * The MMAP events record the PROT_EXEC mappings so that we can * correlate userspace IPs to code. They have the following structure: * Loading Loading @@ -759,6 +769,7 @@ struct perf_event { struct perf_event_attr attr; u16 header_size; u16 id_header_size; u16 read_size; struct hw_perf_event hw; Loading kernel/perf_event.c +167 −67 Original line number Diff line number Diff line Loading @@ -133,6 +133,28 @@ static void unclone_ctx(struct perf_event_context *ctx) } } static u32 perf_event_pid(struct perf_event *event, struct task_struct *p) { /* * only top level events have the pid namespace they were created in */ if (event->parent) event = event->parent; return task_tgid_nr_ns(p, event->ns); } static u32 perf_event_tid(struct perf_event *event, struct task_struct *p) { /* * only top level events have the pid namespace they were created in */ if (event->parent) event = event->parent; return task_pid_nr_ns(p, event->ns); } /* * If we inherit events we want to return the parent event id * to userspace. Loading Loading @@ -351,15 +373,30 @@ static void perf_event__header_size(struct perf_event *event) if (sample_type & PERF_SAMPLE_IP) size += sizeof(data->ip); if (sample_type & PERF_SAMPLE_ADDR) size += sizeof(data->addr); if (sample_type & PERF_SAMPLE_PERIOD) size += sizeof(data->period); if (sample_type & PERF_SAMPLE_READ) size += event->read_size; event->header_size = size; } static void perf_event__id_header_size(struct perf_event *event) { struct perf_sample_data *data; u64 sample_type = event->attr.sample_type; u16 size = 0; if (sample_type & PERF_SAMPLE_TID) size += sizeof(data->tid_entry); if (sample_type & PERF_SAMPLE_TIME) size += sizeof(data->time); if (sample_type & PERF_SAMPLE_ADDR) size += sizeof(data->addr); if (sample_type & PERF_SAMPLE_ID) size += sizeof(data->id); Loading @@ -369,13 +406,7 @@ static void perf_event__header_size(struct perf_event *event) if (sample_type & PERF_SAMPLE_CPU) size += sizeof(data->cpu_entry); if (sample_type & PERF_SAMPLE_PERIOD) size += sizeof(data->period); if (sample_type & PERF_SAMPLE_READ) size += event->read_size; event->header_size = size; event->id_header_size = size; } static void perf_group_attach(struct perf_event *event) Loading Loading @@ -3357,6 +3388,73 @@ __always_inline void perf_output_copy(struct perf_output_handle *handle, } while (len); } static void __perf_event_header__init_id(struct perf_event_header *header, struct perf_sample_data *data, struct perf_event *event) { u64 sample_type = event->attr.sample_type; data->type = sample_type; header->size += event->id_header_size; if (sample_type & PERF_SAMPLE_TID) { /* namespace issues */ data->tid_entry.pid = perf_event_pid(event, current); data->tid_entry.tid = perf_event_tid(event, current); } if (sample_type & PERF_SAMPLE_TIME) data->time = perf_clock(); if (sample_type & PERF_SAMPLE_ID) data->id = primary_event_id(event); if (sample_type & PERF_SAMPLE_STREAM_ID) data->stream_id = event->id; if (sample_type & PERF_SAMPLE_CPU) { data->cpu_entry.cpu = raw_smp_processor_id(); data->cpu_entry.reserved = 0; } } static void perf_event_header__init_id(struct perf_event_header *header, struct perf_sample_data *data, struct perf_event *event) { if (event->attr.sample_id_all) __perf_event_header__init_id(header, data, event); } static void __perf_event__output_id_sample(struct perf_output_handle *handle, struct perf_sample_data *data) { u64 sample_type = data->type; if (sample_type & PERF_SAMPLE_TID) perf_output_put(handle, data->tid_entry); if (sample_type & PERF_SAMPLE_TIME) perf_output_put(handle, data->time); if (sample_type & PERF_SAMPLE_ID) perf_output_put(handle, data->id); if (sample_type & PERF_SAMPLE_STREAM_ID) perf_output_put(handle, data->stream_id); if (sample_type & PERF_SAMPLE_CPU) perf_output_put(handle, data->cpu_entry); } static void perf_event__output_id_sample(struct perf_event *event, struct perf_output_handle *handle, struct perf_sample_data *sample) { if (event->attr.sample_id_all) __perf_event__output_id_sample(handle, sample); } int perf_output_begin(struct perf_output_handle *handle, struct perf_event *event, unsigned int size, int nmi, int sample) Loading @@ -3364,6 +3462,7 @@ int perf_output_begin(struct perf_output_handle *handle, struct perf_buffer *buffer; unsigned long tail, offset, head; int have_lost; struct perf_sample_data sample_data; struct { struct perf_event_header header; u64 id; Loading @@ -3390,8 +3489,12 @@ int perf_output_begin(struct perf_output_handle *handle, goto out; have_lost = local_read(&buffer->lost); if (have_lost) size += sizeof(lost_event); if (have_lost) { lost_event.header.size = sizeof(lost_event); perf_event_header__init_id(&lost_event.header, &sample_data, event); size += lost_event.header.size; } perf_output_get_handle(handle); Loading Loading @@ -3422,11 +3525,11 @@ int perf_output_begin(struct perf_output_handle *handle, if (have_lost) { lost_event.header.type = PERF_RECORD_LOST; lost_event.header.misc = 0; lost_event.header.size = sizeof(lost_event); lost_event.id = event->id; lost_event.lost = local_xchg(&buffer->lost, 0); perf_output_put(handle, lost_event); perf_event__output_id_sample(event, handle, &sample_data); } return 0; Loading Loading @@ -3459,28 +3562,6 @@ void perf_output_end(struct perf_output_handle *handle) rcu_read_unlock(); } static u32 perf_event_pid(struct perf_event *event, struct task_struct *p) { /* * only top level events have the pid namespace they were created in */ if (event->parent) event = event->parent; return task_tgid_nr_ns(p, event->ns); } static u32 perf_event_tid(struct perf_event *event, struct task_struct *p) { /* * only top level events have the pid namespace they were created in */ if (event->parent) event = event->parent; return task_pid_nr_ns(p, event->ns); } static void perf_output_read_one(struct perf_output_handle *handle, struct perf_event *event, u64 enabled, u64 running) Loading Loading @@ -3655,37 +3736,17 @@ void perf_prepare_sample(struct perf_event_header *header, { u64 sample_type = event->attr.sample_type; data->type = sample_type; header->type = PERF_RECORD_SAMPLE; header->size = sizeof(*header) + event->header_size; header->misc = 0; header->misc |= perf_misc_flags(regs); __perf_event_header__init_id(header, data, event); if (sample_type & PERF_SAMPLE_IP) data->ip = perf_instruction_pointer(regs); if (sample_type & PERF_SAMPLE_TID) { /* namespace issues */ data->tid_entry.pid = perf_event_pid(event, current); data->tid_entry.tid = perf_event_tid(event, current); } if (sample_type & PERF_SAMPLE_TIME) data->time = perf_clock(); if (sample_type & PERF_SAMPLE_ID) data->id = primary_event_id(event); if (sample_type & PERF_SAMPLE_STREAM_ID) data->stream_id = event->id; if (sample_type & PERF_SAMPLE_CPU) { data->cpu_entry.cpu = raw_smp_processor_id(); data->cpu_entry.reserved = 0; } if (sample_type & PERF_SAMPLE_CALLCHAIN) { int size = 1; Loading Loading @@ -3749,6 +3810,7 @@ perf_event_read_event(struct perf_event *event, struct task_struct *task) { struct perf_output_handle handle; struct perf_sample_data sample; struct perf_read_event read_event = { .header = { .type = PERF_RECORD_READ, Loading @@ -3760,12 +3822,14 @@ perf_event_read_event(struct perf_event *event, }; int ret; perf_event_header__init_id(&read_event.header, &sample, event); ret = perf_output_begin(&handle, event, read_event.header.size, 0, 0); if (ret) return; perf_output_put(&handle, read_event); perf_output_read(&handle, event); perf_event__output_id_sample(event, &handle, &sample); perf_output_end(&handle); } Loading Loading @@ -3795,14 +3859,16 @@ static void perf_event_task_output(struct perf_event *event, struct perf_task_event *task_event) { struct perf_output_handle handle; struct perf_sample_data sample; struct task_struct *task = task_event->task; int size, ret; int ret, size = task_event->event_id.header.size; size = task_event->event_id.header.size; ret = perf_output_begin(&handle, event, size, 0, 0); perf_event_header__init_id(&task_event->event_id.header, &sample, event); ret = perf_output_begin(&handle, event, task_event->event_id.header.size, 0, 0); if (ret) return; goto out; task_event->event_id.pid = perf_event_pid(event, task); task_event->event_id.ppid = perf_event_pid(event, current); Loading @@ -3812,7 +3878,11 @@ static void perf_event_task_output(struct perf_event *event, perf_output_put(&handle, task_event->event_id); perf_event__output_id_sample(event, &handle, &sample); perf_output_end(&handle); out: task_event->event_id.header.size = size; } static int perf_event_task_match(struct perf_event *event) Loading Loading @@ -3925,11 +3995,16 @@ static void perf_event_comm_output(struct perf_event *event, struct perf_comm_event *comm_event) { struct perf_output_handle handle; struct perf_sample_data sample; int size = comm_event->event_id.header.size; int ret = perf_output_begin(&handle, event, size, 0, 0); int ret; perf_event_header__init_id(&comm_event->event_id.header, &sample, event); ret = perf_output_begin(&handle, event, comm_event->event_id.header.size, 0, 0); if (ret) return; goto out; comm_event->event_id.pid = perf_event_pid(event, comm_event->task); comm_event->event_id.tid = perf_event_tid(event, comm_event->task); Loading @@ -3937,7 +4012,12 @@ static void perf_event_comm_output(struct perf_event *event, perf_output_put(&handle, comm_event->event_id); perf_output_copy(&handle, comm_event->comm, comm_event->comm_size); perf_event__output_id_sample(event, &handle, &sample); perf_output_end(&handle); out: comm_event->event_id.header.size = size; } static int perf_event_comm_match(struct perf_event *event) Loading Loading @@ -3982,7 +4062,6 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event) comm_event->comm_size = size; comm_event->event_id.header.size = sizeof(comm_event->event_id) + size; rcu_read_lock(); list_for_each_entry_rcu(pmu, &pmus, entry) { cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); Loading Loading @@ -4061,11 +4140,15 @@ static void perf_event_mmap_output(struct perf_event *event, struct perf_mmap_event *mmap_event) { struct perf_output_handle handle; struct perf_sample_data sample; int size = mmap_event->event_id.header.size; int ret = perf_output_begin(&handle, event, size, 0, 0); int ret; perf_event_header__init_id(&mmap_event->event_id.header, &sample, event); ret = perf_output_begin(&handle, event, mmap_event->event_id.header.size, 0, 0); if (ret) return; goto out; mmap_event->event_id.pid = perf_event_pid(event, current); mmap_event->event_id.tid = perf_event_tid(event, current); Loading @@ -4073,7 +4156,12 @@ static void perf_event_mmap_output(struct perf_event *event, perf_output_put(&handle, mmap_event->event_id); perf_output_copy(&handle, mmap_event->file_name, mmap_event->file_size); perf_event__output_id_sample(event, &handle, &sample); perf_output_end(&handle); out: mmap_event->event_id.header.size = size; } static int perf_event_mmap_match(struct perf_event *event, Loading Loading @@ -4226,6 +4314,7 @@ void perf_event_mmap(struct vm_area_struct *vma) static void perf_log_throttle(struct perf_event *event, int enable) { struct perf_output_handle handle; struct perf_sample_data sample; int ret; struct { Loading @@ -4247,11 +4336,15 @@ static void perf_log_throttle(struct perf_event *event, int enable) if (enable) throttle_event.header.type = PERF_RECORD_UNTHROTTLE; ret = perf_output_begin(&handle, event, sizeof(throttle_event), 1, 0); perf_event_header__init_id(&throttle_event.header, &sample, event); ret = perf_output_begin(&handle, event, throttle_event.header.size, 1, 0); if (ret) return; perf_output_put(&handle, throttle_event); perf_event__output_id_sample(event, &handle, &sample); perf_output_end(&handle); } Loading Loading @@ -5745,6 +5838,7 @@ SYSCALL_DEFINE5(perf_event_open, * Precalculate sample_data sizes */ perf_event__header_size(event); perf_event__id_header_size(event); /* * Drop the reference on the group_event after placing the Loading Loading @@ -6098,6 +6192,12 @@ inherit_event(struct perf_event *parent_event, child_event->ctx = child_ctx; child_event->overflow_handler = parent_event->overflow_handler; /* * Precalculate sample_data sizes */ perf_event__header_size(child_event); perf_event__id_header_size(child_event); /* * Link it up in the child's context: */ Loading tools/perf/Documentation/perf-record.txt +5 −0 Original line number Diff line number Diff line Loading @@ -108,6 +108,11 @@ OPTIONS --data:: Sample addresses. -T:: --timestamp:: Sample timestamps. Use it with 'perf report -D' to see the timestamps, for instance. -n:: --no-samples:: Don't sample. Loading tools/perf/builtin-annotate.c +3 −3 Original line number Diff line number Diff line Loading @@ -58,12 +58,12 @@ static int hists__add_entry(struct hists *self, struct addr_location *al) return hist_entry__inc_addr_samples(he, al->addr); } static int process_sample_event(event_t *event, struct perf_session *session) static int process_sample_event(event_t *event, struct sample_data *sample, struct perf_session *session) { struct addr_location al; struct sample_data data; if (event__preprocess_sample(event, session, &al, &data, NULL) < 0) { if (event__preprocess_sample(event, session, &al, sample, NULL) < 0) { pr_warning("problem processing %d event, skipping it.\n", event->header.type); return -1; Loading tools/perf/builtin-diff.c +6 −5 Original line number Diff line number Diff line Loading @@ -30,12 +30,13 @@ static int hists__add_entry(struct hists *self, return -ENOMEM; } static int diff__process_sample_event(event_t *event, struct perf_session *session) static int diff__process_sample_event(event_t *event, struct sample_data *sample, struct perf_session *session) { struct addr_location al; struct sample_data data = { .period = 1, }; if (event__preprocess_sample(event, session, &al, &data, NULL) < 0) { if (event__preprocess_sample(event, session, &al, sample, NULL) < 0) { pr_warning("problem processing %d event, skipping it.\n", event->header.type); return -1; Loading @@ -44,12 +45,12 @@ static int diff__process_sample_event(event_t *event, struct perf_session *sessi if (al.filtered || al.sym == NULL) return 0; if (hists__add_entry(&session->hists, &al, data.period)) { if (hists__add_entry(&session->hists, &al, sample->period)) { pr_warning("problem incrementing symbol period, skipping event\n"); return -1; } session->hists.stats.total_period += data.period; session->hists.stats.total_period += sample->period; return 0; } Loading Loading
include/linux/perf_event.h +12 −1 Original line number Diff line number Diff line Loading @@ -215,8 +215,9 @@ struct perf_event_attr { */ precise_ip : 2, /* skid constraint */ mmap_data : 1, /* non-exec mmap data */ sample_id_all : 1, /* sample_type all events */ __reserved_1 : 46; __reserved_1 : 45; union { __u32 wakeup_events; /* wakeup every n events */ Loading Loading @@ -327,6 +328,15 @@ struct perf_event_header { enum perf_event_type { /* * If perf_event_attr.sample_id_all is set then all event types will * have the sample_type selected fields related to where/when * (identity) an event took place (TID, TIME, ID, CPU, STREAM_ID) * described in PERF_RECORD_SAMPLE below, it will be stashed just after * the perf_event_header and the fields already present for the existing * fields, i.e. at the end of the payload. That way a newer perf.data * file will be supported by older perf tools, with these new optional * fields being ignored. * * The MMAP events record the PROT_EXEC mappings so that we can * correlate userspace IPs to code. They have the following structure: * Loading Loading @@ -759,6 +769,7 @@ struct perf_event { struct perf_event_attr attr; u16 header_size; u16 id_header_size; u16 read_size; struct hw_perf_event hw; Loading
kernel/perf_event.c +167 −67 Original line number Diff line number Diff line Loading @@ -133,6 +133,28 @@ static void unclone_ctx(struct perf_event_context *ctx) } } static u32 perf_event_pid(struct perf_event *event, struct task_struct *p) { /* * only top level events have the pid namespace they were created in */ if (event->parent) event = event->parent; return task_tgid_nr_ns(p, event->ns); } static u32 perf_event_tid(struct perf_event *event, struct task_struct *p) { /* * only top level events have the pid namespace they were created in */ if (event->parent) event = event->parent; return task_pid_nr_ns(p, event->ns); } /* * If we inherit events we want to return the parent event id * to userspace. Loading Loading @@ -351,15 +373,30 @@ static void perf_event__header_size(struct perf_event *event) if (sample_type & PERF_SAMPLE_IP) size += sizeof(data->ip); if (sample_type & PERF_SAMPLE_ADDR) size += sizeof(data->addr); if (sample_type & PERF_SAMPLE_PERIOD) size += sizeof(data->period); if (sample_type & PERF_SAMPLE_READ) size += event->read_size; event->header_size = size; } static void perf_event__id_header_size(struct perf_event *event) { struct perf_sample_data *data; u64 sample_type = event->attr.sample_type; u16 size = 0; if (sample_type & PERF_SAMPLE_TID) size += sizeof(data->tid_entry); if (sample_type & PERF_SAMPLE_TIME) size += sizeof(data->time); if (sample_type & PERF_SAMPLE_ADDR) size += sizeof(data->addr); if (sample_type & PERF_SAMPLE_ID) size += sizeof(data->id); Loading @@ -369,13 +406,7 @@ static void perf_event__header_size(struct perf_event *event) if (sample_type & PERF_SAMPLE_CPU) size += sizeof(data->cpu_entry); if (sample_type & PERF_SAMPLE_PERIOD) size += sizeof(data->period); if (sample_type & PERF_SAMPLE_READ) size += event->read_size; event->header_size = size; event->id_header_size = size; } static void perf_group_attach(struct perf_event *event) Loading Loading @@ -3357,6 +3388,73 @@ __always_inline void perf_output_copy(struct perf_output_handle *handle, } while (len); } static void __perf_event_header__init_id(struct perf_event_header *header, struct perf_sample_data *data, struct perf_event *event) { u64 sample_type = event->attr.sample_type; data->type = sample_type; header->size += event->id_header_size; if (sample_type & PERF_SAMPLE_TID) { /* namespace issues */ data->tid_entry.pid = perf_event_pid(event, current); data->tid_entry.tid = perf_event_tid(event, current); } if (sample_type & PERF_SAMPLE_TIME) data->time = perf_clock(); if (sample_type & PERF_SAMPLE_ID) data->id = primary_event_id(event); if (sample_type & PERF_SAMPLE_STREAM_ID) data->stream_id = event->id; if (sample_type & PERF_SAMPLE_CPU) { data->cpu_entry.cpu = raw_smp_processor_id(); data->cpu_entry.reserved = 0; } } static void perf_event_header__init_id(struct perf_event_header *header, struct perf_sample_data *data, struct perf_event *event) { if (event->attr.sample_id_all) __perf_event_header__init_id(header, data, event); } static void __perf_event__output_id_sample(struct perf_output_handle *handle, struct perf_sample_data *data) { u64 sample_type = data->type; if (sample_type & PERF_SAMPLE_TID) perf_output_put(handle, data->tid_entry); if (sample_type & PERF_SAMPLE_TIME) perf_output_put(handle, data->time); if (sample_type & PERF_SAMPLE_ID) perf_output_put(handle, data->id); if (sample_type & PERF_SAMPLE_STREAM_ID) perf_output_put(handle, data->stream_id); if (sample_type & PERF_SAMPLE_CPU) perf_output_put(handle, data->cpu_entry); } static void perf_event__output_id_sample(struct perf_event *event, struct perf_output_handle *handle, struct perf_sample_data *sample) { if (event->attr.sample_id_all) __perf_event__output_id_sample(handle, sample); } int perf_output_begin(struct perf_output_handle *handle, struct perf_event *event, unsigned int size, int nmi, int sample) Loading @@ -3364,6 +3462,7 @@ int perf_output_begin(struct perf_output_handle *handle, struct perf_buffer *buffer; unsigned long tail, offset, head; int have_lost; struct perf_sample_data sample_data; struct { struct perf_event_header header; u64 id; Loading @@ -3390,8 +3489,12 @@ int perf_output_begin(struct perf_output_handle *handle, goto out; have_lost = local_read(&buffer->lost); if (have_lost) size += sizeof(lost_event); if (have_lost) { lost_event.header.size = sizeof(lost_event); perf_event_header__init_id(&lost_event.header, &sample_data, event); size += lost_event.header.size; } perf_output_get_handle(handle); Loading Loading @@ -3422,11 +3525,11 @@ int perf_output_begin(struct perf_output_handle *handle, if (have_lost) { lost_event.header.type = PERF_RECORD_LOST; lost_event.header.misc = 0; lost_event.header.size = sizeof(lost_event); lost_event.id = event->id; lost_event.lost = local_xchg(&buffer->lost, 0); perf_output_put(handle, lost_event); perf_event__output_id_sample(event, handle, &sample_data); } return 0; Loading Loading @@ -3459,28 +3562,6 @@ void perf_output_end(struct perf_output_handle *handle) rcu_read_unlock(); } static u32 perf_event_pid(struct perf_event *event, struct task_struct *p) { /* * only top level events have the pid namespace they were created in */ if (event->parent) event = event->parent; return task_tgid_nr_ns(p, event->ns); } static u32 perf_event_tid(struct perf_event *event, struct task_struct *p) { /* * only top level events have the pid namespace they were created in */ if (event->parent) event = event->parent; return task_pid_nr_ns(p, event->ns); } static void perf_output_read_one(struct perf_output_handle *handle, struct perf_event *event, u64 enabled, u64 running) Loading Loading @@ -3655,37 +3736,17 @@ void perf_prepare_sample(struct perf_event_header *header, { u64 sample_type = event->attr.sample_type; data->type = sample_type; header->type = PERF_RECORD_SAMPLE; header->size = sizeof(*header) + event->header_size; header->misc = 0; header->misc |= perf_misc_flags(regs); __perf_event_header__init_id(header, data, event); if (sample_type & PERF_SAMPLE_IP) data->ip = perf_instruction_pointer(regs); if (sample_type & PERF_SAMPLE_TID) { /* namespace issues */ data->tid_entry.pid = perf_event_pid(event, current); data->tid_entry.tid = perf_event_tid(event, current); } if (sample_type & PERF_SAMPLE_TIME) data->time = perf_clock(); if (sample_type & PERF_SAMPLE_ID) data->id = primary_event_id(event); if (sample_type & PERF_SAMPLE_STREAM_ID) data->stream_id = event->id; if (sample_type & PERF_SAMPLE_CPU) { data->cpu_entry.cpu = raw_smp_processor_id(); data->cpu_entry.reserved = 0; } if (sample_type & PERF_SAMPLE_CALLCHAIN) { int size = 1; Loading Loading @@ -3749,6 +3810,7 @@ perf_event_read_event(struct perf_event *event, struct task_struct *task) { struct perf_output_handle handle; struct perf_sample_data sample; struct perf_read_event read_event = { .header = { .type = PERF_RECORD_READ, Loading @@ -3760,12 +3822,14 @@ perf_event_read_event(struct perf_event *event, }; int ret; perf_event_header__init_id(&read_event.header, &sample, event); ret = perf_output_begin(&handle, event, read_event.header.size, 0, 0); if (ret) return; perf_output_put(&handle, read_event); perf_output_read(&handle, event); perf_event__output_id_sample(event, &handle, &sample); perf_output_end(&handle); } Loading Loading @@ -3795,14 +3859,16 @@ static void perf_event_task_output(struct perf_event *event, struct perf_task_event *task_event) { struct perf_output_handle handle; struct perf_sample_data sample; struct task_struct *task = task_event->task; int size, ret; int ret, size = task_event->event_id.header.size; size = task_event->event_id.header.size; ret = perf_output_begin(&handle, event, size, 0, 0); perf_event_header__init_id(&task_event->event_id.header, &sample, event); ret = perf_output_begin(&handle, event, task_event->event_id.header.size, 0, 0); if (ret) return; goto out; task_event->event_id.pid = perf_event_pid(event, task); task_event->event_id.ppid = perf_event_pid(event, current); Loading @@ -3812,7 +3878,11 @@ static void perf_event_task_output(struct perf_event *event, perf_output_put(&handle, task_event->event_id); perf_event__output_id_sample(event, &handle, &sample); perf_output_end(&handle); out: task_event->event_id.header.size = size; } static int perf_event_task_match(struct perf_event *event) Loading Loading @@ -3925,11 +3995,16 @@ static void perf_event_comm_output(struct perf_event *event, struct perf_comm_event *comm_event) { struct perf_output_handle handle; struct perf_sample_data sample; int size = comm_event->event_id.header.size; int ret = perf_output_begin(&handle, event, size, 0, 0); int ret; perf_event_header__init_id(&comm_event->event_id.header, &sample, event); ret = perf_output_begin(&handle, event, comm_event->event_id.header.size, 0, 0); if (ret) return; goto out; comm_event->event_id.pid = perf_event_pid(event, comm_event->task); comm_event->event_id.tid = perf_event_tid(event, comm_event->task); Loading @@ -3937,7 +4012,12 @@ static void perf_event_comm_output(struct perf_event *event, perf_output_put(&handle, comm_event->event_id); perf_output_copy(&handle, comm_event->comm, comm_event->comm_size); perf_event__output_id_sample(event, &handle, &sample); perf_output_end(&handle); out: comm_event->event_id.header.size = size; } static int perf_event_comm_match(struct perf_event *event) Loading Loading @@ -3982,7 +4062,6 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event) comm_event->comm_size = size; comm_event->event_id.header.size = sizeof(comm_event->event_id) + size; rcu_read_lock(); list_for_each_entry_rcu(pmu, &pmus, entry) { cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); Loading Loading @@ -4061,11 +4140,15 @@ static void perf_event_mmap_output(struct perf_event *event, struct perf_mmap_event *mmap_event) { struct perf_output_handle handle; struct perf_sample_data sample; int size = mmap_event->event_id.header.size; int ret = perf_output_begin(&handle, event, size, 0, 0); int ret; perf_event_header__init_id(&mmap_event->event_id.header, &sample, event); ret = perf_output_begin(&handle, event, mmap_event->event_id.header.size, 0, 0); if (ret) return; goto out; mmap_event->event_id.pid = perf_event_pid(event, current); mmap_event->event_id.tid = perf_event_tid(event, current); Loading @@ -4073,7 +4156,12 @@ static void perf_event_mmap_output(struct perf_event *event, perf_output_put(&handle, mmap_event->event_id); perf_output_copy(&handle, mmap_event->file_name, mmap_event->file_size); perf_event__output_id_sample(event, &handle, &sample); perf_output_end(&handle); out: mmap_event->event_id.header.size = size; } static int perf_event_mmap_match(struct perf_event *event, Loading Loading @@ -4226,6 +4314,7 @@ void perf_event_mmap(struct vm_area_struct *vma) static void perf_log_throttle(struct perf_event *event, int enable) { struct perf_output_handle handle; struct perf_sample_data sample; int ret; struct { Loading @@ -4247,11 +4336,15 @@ static void perf_log_throttle(struct perf_event *event, int enable) if (enable) throttle_event.header.type = PERF_RECORD_UNTHROTTLE; ret = perf_output_begin(&handle, event, sizeof(throttle_event), 1, 0); perf_event_header__init_id(&throttle_event.header, &sample, event); ret = perf_output_begin(&handle, event, throttle_event.header.size, 1, 0); if (ret) return; perf_output_put(&handle, throttle_event); perf_event__output_id_sample(event, &handle, &sample); perf_output_end(&handle); } Loading Loading @@ -5745,6 +5838,7 @@ SYSCALL_DEFINE5(perf_event_open, * Precalculate sample_data sizes */ perf_event__header_size(event); perf_event__id_header_size(event); /* * Drop the reference on the group_event after placing the Loading Loading @@ -6098,6 +6192,12 @@ inherit_event(struct perf_event *parent_event, child_event->ctx = child_ctx; child_event->overflow_handler = parent_event->overflow_handler; /* * Precalculate sample_data sizes */ perf_event__header_size(child_event); perf_event__id_header_size(child_event); /* * Link it up in the child's context: */ Loading
tools/perf/Documentation/perf-record.txt +5 −0 Original line number Diff line number Diff line Loading @@ -108,6 +108,11 @@ OPTIONS --data:: Sample addresses. -T:: --timestamp:: Sample timestamps. Use it with 'perf report -D' to see the timestamps, for instance. -n:: --no-samples:: Don't sample. Loading
tools/perf/builtin-annotate.c +3 −3 Original line number Diff line number Diff line Loading @@ -58,12 +58,12 @@ static int hists__add_entry(struct hists *self, struct addr_location *al) return hist_entry__inc_addr_samples(he, al->addr); } static int process_sample_event(event_t *event, struct perf_session *session) static int process_sample_event(event_t *event, struct sample_data *sample, struct perf_session *session) { struct addr_location al; struct sample_data data; if (event__preprocess_sample(event, session, &al, &data, NULL) < 0) { if (event__preprocess_sample(event, session, &al, sample, NULL) < 0) { pr_warning("problem processing %d event, skipping it.\n", event->header.type); return -1; Loading
tools/perf/builtin-diff.c +6 −5 Original line number Diff line number Diff line Loading @@ -30,12 +30,13 @@ static int hists__add_entry(struct hists *self, return -ENOMEM; } static int diff__process_sample_event(event_t *event, struct perf_session *session) static int diff__process_sample_event(event_t *event, struct sample_data *sample, struct perf_session *session) { struct addr_location al; struct sample_data data = { .period = 1, }; if (event__preprocess_sample(event, session, &al, &data, NULL) < 0) { if (event__preprocess_sample(event, session, &al, sample, NULL) < 0) { pr_warning("problem processing %d event, skipping it.\n", event->header.type); return -1; Loading @@ -44,12 +45,12 @@ static int diff__process_sample_event(event_t *event, struct perf_session *sessi if (al.filtered || al.sym == NULL) return 0; if (hists__add_entry(&session->hists, &al, data.period)) { if (hists__add_entry(&session->hists, &al, sample->period)) { pr_warning("problem incrementing symbol period, skipping event\n"); return -1; } session->hists.stats.total_period += data.period; session->hists.stats.total_period += sample->period; return 0; } Loading