aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2013-08-27 04:23:11 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-08-29 15:14:20 -0400
commitd03f2170546d2f0c236a42706d211e15ffb64184 (patch)
tree575f7a3475ea9d1486e59f1aaf918e554757552f
parent5b95a4a3b52a1de84022dfaf580df4b5251f4a15 (diff)
perf tools: Expand perf_event__synthesize_sample()
Expand perf_event__synthesize_sample() to handle all sample format bits. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1377591794-30553-10-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/builtin-inject.c4
-rw-r--r--tools/perf/util/event.h1
-rw-r--r--tools/perf/util/evsel.c95
3 files changed, 97 insertions, 3 deletions
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index ffacd464f9f6..9b336fdb6f71 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -301,7 +301,9 @@ found:
301 sample_sw.period = sample->period; 301 sample_sw.period = sample->period;
302 sample_sw.time = sample->time; 302 sample_sw.time = sample->time;
303 perf_event__synthesize_sample(event_sw, evsel->attr.sample_type, 303 perf_event__synthesize_sample(event_sw, evsel->attr.sample_type,
304 &sample_sw, false); 304 evsel->attr.sample_regs_user,
305 evsel->attr.read_format, &sample_sw,
306 false);
305 build_id__mark_dso_hit(tool, event_sw, &sample_sw, evsel, machine); 307 build_id__mark_dso_hit(tool, event_sw, &sample_sw, evsel, machine);
306 return perf_event__repipe(tool, event_sw, &sample_sw, machine); 308 return perf_event__repipe(tool, event_sw, &sample_sw, machine);
307} 309}
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index f959801ac9e4..1c80e1304e48 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -230,6 +230,7 @@ int perf_event__preprocess_sample(const union perf_event *self,
230const char *perf_event__name(unsigned int id); 230const char *perf_event__name(unsigned int id);
231 231
232int perf_event__synthesize_sample(union perf_event *event, u64 type, 232int perf_event__synthesize_sample(union perf_event *event, u64 type,
233 u64 sample_regs_user, u64 read_format,
233 const struct perf_sample *sample, 234 const struct perf_sample *sample,
234 bool swapped); 235 bool swapped);
235 236
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 11841881cef9..7d62373e0b6f 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1416,7 +1416,6 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
1416 } 1416 }
1417 1417
1418 if (type & PERF_SAMPLE_REGS_USER) { 1418 if (type & PERF_SAMPLE_REGS_USER) {
1419 /* First u64 tells us if we have any regs in sample. */
1420 OVERFLOW_CHECK_u64(array); 1419 OVERFLOW_CHECK_u64(array);
1421 data->user_regs.abi = *array; 1420 data->user_regs.abi = *array;
1422 array++; 1421 array++;
@@ -1467,11 +1466,12 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
1467} 1466}
1468 1467
1469int perf_event__synthesize_sample(union perf_event *event, u64 type, 1468int perf_event__synthesize_sample(union perf_event *event, u64 type,
1469 u64 sample_regs_user, u64 read_format,
1470 const struct perf_sample *sample, 1470 const struct perf_sample *sample,
1471 bool swapped) 1471 bool swapped)
1472{ 1472{
1473 u64 *array; 1473 u64 *array;
1474 1474 size_t sz;
1475 /* 1475 /*
1476 * used for cross-endian analysis. See git commit 65014ab3 1476 * used for cross-endian analysis. See git commit 65014ab3
1477 * for why this goofiness is needed. 1477 * for why this goofiness is needed.
@@ -1544,6 +1544,97 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type,
1544 array++; 1544 array++;
1545 } 1545 }
1546 1546
1547 if (type & PERF_SAMPLE_READ) {
1548 if (read_format & PERF_FORMAT_GROUP)
1549 *array = sample->read.group.nr;
1550 else
1551 *array = sample->read.one.value;
1552 array++;
1553
1554 if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
1555 *array = sample->read.time_enabled;
1556 array++;
1557 }
1558
1559 if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
1560 *array = sample->read.time_running;
1561 array++;
1562 }
1563
1564 /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
1565 if (read_format & PERF_FORMAT_GROUP) {
1566 sz = sample->read.group.nr *
1567 sizeof(struct sample_read_value);
1568 memcpy(array, sample->read.group.values, sz);
1569 array = (void *)array + sz;
1570 } else {
1571 *array = sample->read.one.id;
1572 array++;
1573 }
1574 }
1575
1576 if (type & PERF_SAMPLE_CALLCHAIN) {
1577 sz = (sample->callchain->nr + 1) * sizeof(u64);
1578 memcpy(array, sample->callchain, sz);
1579 array = (void *)array + sz;
1580 }
1581
1582 if (type & PERF_SAMPLE_RAW) {
1583 u.val32[0] = sample->raw_size;
1584 if (WARN_ONCE(swapped,
1585 "Endianness of raw data not corrected!\n")) {
1586 /*
1587 * Inverse of what is done in perf_evsel__parse_sample
1588 */
1589 u.val32[0] = bswap_32(u.val32[0]);
1590 u.val32[1] = bswap_32(u.val32[1]);
1591 u.val64 = bswap_64(u.val64);
1592 }
1593 *array = u.val64;
1594 array = (void *)array + sizeof(u32);
1595
1596 memcpy(array, sample->raw_data, sample->raw_size);
1597 array = (void *)array + sample->raw_size;
1598 }
1599
1600 if (type & PERF_SAMPLE_BRANCH_STACK) {
1601 sz = sample->branch_stack->nr * sizeof(struct branch_entry);
1602 sz += sizeof(u64);
1603 memcpy(array, sample->branch_stack, sz);
1604 array = (void *)array + sz;
1605 }
1606
1607 if (type & PERF_SAMPLE_REGS_USER) {
1608 if (sample->user_regs.abi) {
1609 *array++ = sample->user_regs.abi;
1610 sz = hweight_long(sample_regs_user) * sizeof(u64);
1611 memcpy(array, sample->user_regs.regs, sz);
1612 array = (void *)array + sz;
1613 } else {
1614 *array++ = 0;
1615 }
1616 }
1617
1618 if (type & PERF_SAMPLE_STACK_USER) {
1619 sz = sample->user_stack.size;
1620 *array++ = sz;
1621 if (sz) {
1622 memcpy(array, sample->user_stack.data, sz);
1623 array = (void *)array + sz;
1624 *array++ = sz;
1625 }
1626 }
1627
1628 if (type & PERF_SAMPLE_WEIGHT) {
1629 *array = sample->weight;
1630 array++;
1631 }
1632
1633 if (type & PERF_SAMPLE_DATA_SRC) {
1634 *array = sample->data_src;
1635 array++;
1636 }
1637
1547 return 0; 1638 return 0;
1548} 1639}
1549 1640