Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf tools: Add ability to synthesize event according to a sample

It's the counterpart of perf_session__parse_sample.

v2: fixed mistakes found by David Ahern.
v3: s/data/sample/
s/perf_event__change_sample/perf_event__synthesize_sample

Reviewed-by: David Ahern <dsahern@gmail.com>
Cc: Arun Sharma <asharma@fb.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: devel@openvz.org
Link: http://lkml.kernel.org/r/1323266161-394927-3-git-send-email-avagin@openvz.org
Signed-off-by: Andrew Vagin <avagin@openvz.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Andrew Vagin and committed by
Arnaldo Carvalho de Melo
74eec26f 317df650

+90
+3
tools/perf/util/event.h
··· 199 199 int perf_event__parse_sample(const union perf_event *event, u64 type, 200 200 int sample_size, bool sample_id_all, 201 201 struct perf_sample *sample, bool swapped); 202 + int perf_event__synthesize_sample(union perf_event *event, u64 type, 203 + const struct perf_sample *sample, 204 + bool swapped); 202 205 203 206 size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp); 204 207 size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp);
+79
tools/perf/util/evsel.c
··· 574 574 575 575 return 0; 576 576 } 577 + 578 + int perf_event__synthesize_sample(union perf_event *event, u64 type, 579 + const struct perf_sample *sample, 580 + bool swapped) 581 + { 582 + u64 *array; 583 + 584 + /* 585 + * used for cross-endian analysis. See git commit 65014ab3 586 + * for why this goofiness is needed. 587 + */ 588 + union { 589 + u64 val64; 590 + u32 val32[2]; 591 + } u; 592 + 593 + array = event->sample.array; 594 + 595 + if (type & PERF_SAMPLE_IP) { 596 + event->ip.ip = sample->ip; 597 + array++; 598 + } 599 + 600 + if (type & PERF_SAMPLE_TID) { 601 + u.val32[0] = sample->pid; 602 + u.val32[1] = sample->tid; 603 + if (swapped) { 604 + /* 605 + * Inverse of what is done in perf_event__parse_sample 606 + */ 607 + u.val32[0] = bswap_32(u.val32[0]); 608 + u.val32[1] = bswap_32(u.val32[1]); 609 + u.val64 = bswap_64(u.val64); 610 + } 611 + 612 + *array = u.val64; 613 + array++; 614 + } 615 + 616 + if (type & PERF_SAMPLE_TIME) { 617 + *array = sample->time; 618 + array++; 619 + } 620 + 621 + if (type & PERF_SAMPLE_ADDR) { 622 + *array = sample->addr; 623 + array++; 624 + } 625 + 626 + if (type & PERF_SAMPLE_ID) { 627 + *array = sample->id; 628 + array++; 629 + } 630 + 631 + if (type & PERF_SAMPLE_STREAM_ID) { 632 + *array = sample->stream_id; 633 + array++; 634 + } 635 + 636 + if (type & PERF_SAMPLE_CPU) { 637 + u.val32[0] = sample->cpu; 638 + if (swapped) { 639 + /* 640 + * Inverse of what is done in perf_event__parse_sample 641 + */ 642 + u.val32[0] = bswap_32(u.val32[0]); 643 + u.val64 = bswap_64(u.val64); 644 + } 645 + *array = u.val64; 646 + array++; 647 + } 648 + 649 + if (type & PERF_SAMPLE_PERIOD) { 650 + *array = sample->period; 651 + array++; 652 + } 653 + 654 + return 0; 655 + }
+8
tools/perf/util/session.h
··· 134 134 session->header.needs_swap); 135 135 } 136 136 137 + static inline int perf_session__synthesize_sample(struct perf_session *session, 138 + union perf_event *event, 139 + const struct perf_sample *sample) 140 + { 141 + return perf_event__synthesize_sample(event, session->sample_type, 142 + sample, session->header.needs_swap); 143 + } 144 + 137 145 struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, 138 146 unsigned int type); 139 147