Commit 75562573bab35b129cfd342fc2bcf89da84a6644

Authored by Adrian Hunter
Committed by Arnaldo Carvalho de Melo
1 parent faf967068e

perf tools: Add support for PERF_SAMPLE_IDENTIFIER

Enable parsing of samples with sample format bit PERF_SAMPLE_IDENTIFIER.
In addition, if the kernel supports it, prefer it to selecting
PERF_SAMPLE_ID thereby allowing non-matching sample types.

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-8-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

Showing 9 changed files with 310 additions and 22 deletions Side-by-side Diff

tools/perf/builtin-report.c
... ... @@ -365,7 +365,7 @@
365 365 static int perf_report__setup_sample_type(struct perf_report *rep)
366 366 {
367 367 struct perf_session *self = rep->session;
368   - u64 sample_type = perf_evlist__sample_type(self->evlist);
  368 + u64 sample_type = perf_evlist__combined_sample_type(self->evlist);
369 369  
370 370 if (!self->fd_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
371 371 if (sort__has_parent) {
tools/perf/tests/mmap-basic.c
... ... @@ -72,7 +72,7 @@
72 72 }
73 73  
74 74 evsels[i]->attr.wakeup_events = 1;
75   - perf_evsel__set_sample_id(evsels[i]);
  75 + perf_evsel__set_sample_id(evsels[i], false);
76 76  
77 77 perf_evlist__add(evlist, evsels[i]);
78 78  
tools/perf/util/event.h
... ... @@ -53,7 +53,8 @@
53 53 (PERF_SAMPLE_IP | PERF_SAMPLE_TID | \
54 54 PERF_SAMPLE_TIME | PERF_SAMPLE_ADDR | \
55 55 PERF_SAMPLE_ID | PERF_SAMPLE_STREAM_ID | \
56   - PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD)
  56 + PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD | \
  57 + PERF_SAMPLE_IDENTIFIER)
57 58  
58 59 struct sample_event {
59 60 struct perf_event_header header;
tools/perf/util/evlist.c
... ... @@ -49,6 +49,21 @@
49 49 return evlist;
50 50 }
51 51  
  52 +/**
  53 + * perf_evlist__set_id_pos - set the positions of event ids.
  54 + * @evlist: selected event list
  55 + *
  56 + * Events with compatible sample types all have the same id_pos
  57 + * and is_pos. For convenience, put a copy on evlist.
  58 + */
  59 +void perf_evlist__set_id_pos(struct perf_evlist *evlist)
  60 +{
  61 + struct perf_evsel *first = perf_evlist__first(evlist);
  62 +
  63 + evlist->id_pos = first->id_pos;
  64 + evlist->is_pos = first->is_pos;
  65 +}
  66 +
52 67 static void perf_evlist__purge(struct perf_evlist *evlist)
53 68 {
54 69 struct perf_evsel *pos, *n;
55 70  
56 71  
... ... @@ -79,15 +94,20 @@
79 94 void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry)
80 95 {
81 96 list_add_tail(&entry->node, &evlist->entries);
82   - ++evlist->nr_entries;
  97 + if (!evlist->nr_entries++)
  98 + perf_evlist__set_id_pos(evlist);
83 99 }
84 100  
85 101 void perf_evlist__splice_list_tail(struct perf_evlist *evlist,
86 102 struct list_head *list,
87 103 int nr_entries)
88 104 {
  105 + bool set_id_pos = !evlist->nr_entries;
  106 +
89 107 list_splice_tail(list, &evlist->entries);
90 108 evlist->nr_entries += nr_entries;
  109 + if (set_id_pos)
  110 + perf_evlist__set_id_pos(evlist);
91 111 }
92 112  
93 113 void __perf_evlist__set_leader(struct list_head *list)
... ... @@ -349,6 +369,55 @@
349 369 return NULL;
350 370 }
351 371  
  372 +static int perf_evlist__event2id(struct perf_evlist *evlist,
  373 + union perf_event *event, u64 *id)
  374 +{
  375 + const u64 *array = event->sample.array;
  376 + ssize_t n;
  377 +
  378 + n = (event->header.size - sizeof(event->header)) >> 3;
  379 +
  380 + if (event->header.type == PERF_RECORD_SAMPLE) {
  381 + if (evlist->id_pos >= n)
  382 + return -1;
  383 + *id = array[evlist->id_pos];
  384 + } else {
  385 + if (evlist->is_pos > n)
  386 + return -1;
  387 + n -= evlist->is_pos;
  388 + *id = array[n];
  389 + }
  390 + return 0;
  391 +}
  392 +
  393 +static struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist,
  394 + union perf_event *event)
  395 +{
  396 + struct hlist_head *head;
  397 + struct perf_sample_id *sid;
  398 + int hash;
  399 + u64 id;
  400 +
  401 + if (evlist->nr_entries == 1)
  402 + return perf_evlist__first(evlist);
  403 +
  404 + if (perf_evlist__event2id(evlist, event, &id))
  405 + return NULL;
  406 +
  407 + /* Synthesized events have an id of zero */
  408 + if (!id)
  409 + return perf_evlist__first(evlist);
  410 +
  411 + hash = hash_64(id, PERF_EVLIST__HLIST_BITS);
  412 + head = &evlist->heads[hash];
  413 +
  414 + hlist_for_each_entry(sid, head, node) {
  415 + if (sid->id == id)
  416 + return sid->evsel;
  417 + }
  418 + return NULL;
  419 +}
  420 +
352 421 union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
353 422 {
354 423 struct perf_mmap *md = &evlist->mmap[idx];
355 424  
356 425  
357 426  
358 427  
... ... @@ -659,22 +728,42 @@
659 728  
660 729 bool perf_evlist__valid_sample_type(struct perf_evlist *evlist)
661 730 {
662   - struct perf_evsel *first = perf_evlist__first(evlist), *pos = first;
  731 + struct perf_evsel *pos;
663 732  
664   - list_for_each_entry_continue(pos, &evlist->entries, node) {
665   - if (first->attr.sample_type != pos->attr.sample_type)
  733 + if (evlist->nr_entries == 1)
  734 + return true;
  735 +
  736 + if (evlist->id_pos < 0 || evlist->is_pos < 0)
  737 + return false;
  738 +
  739 + list_for_each_entry(pos, &evlist->entries, node) {
  740 + if (pos->id_pos != evlist->id_pos ||
  741 + pos->is_pos != evlist->is_pos)
666 742 return false;
667 743 }
668 744  
669 745 return true;
670 746 }
671 747  
672   -u64 perf_evlist__sample_type(struct perf_evlist *evlist)
  748 +u64 __perf_evlist__combined_sample_type(struct perf_evlist *evlist)
673 749 {
674   - struct perf_evsel *first = perf_evlist__first(evlist);
675   - return first->attr.sample_type;
  750 + struct perf_evsel *evsel;
  751 +
  752 + if (evlist->combined_sample_type)
  753 + return evlist->combined_sample_type;
  754 +
  755 + list_for_each_entry(evsel, &evlist->entries, node)
  756 + evlist->combined_sample_type |= evsel->attr.sample_type;
  757 +
  758 + return evlist->combined_sample_type;
676 759 }
677 760  
  761 +u64 perf_evlist__combined_sample_type(struct perf_evlist *evlist)
  762 +{
  763 + evlist->combined_sample_type = 0;
  764 + return __perf_evlist__combined_sample_type(evlist);
  765 +}
  766 +
678 767 bool perf_evlist__valid_read_format(struct perf_evlist *evlist)
679 768 {
680 769 struct perf_evsel *first = perf_evlist__first(evlist), *pos = first;
... ... @@ -727,6 +816,9 @@
727 816  
728 817 if (sample_type & PERF_SAMPLE_CPU)
729 818 size += sizeof(data->cpu) * 2;
  819 +
  820 + if (sample_type & PERF_SAMPLE_IDENTIFIER)
  821 + size += sizeof(data->id);
730 822 out:
731 823 return size;
732 824 }
... ... @@ -885,7 +977,10 @@
885 977 int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event,
886 978 struct perf_sample *sample)
887 979 {
888   - struct perf_evsel *evsel = perf_evlist__first(evlist);
  980 + struct perf_evsel *evsel = perf_evlist__event2evsel(evlist, event);
  981 +
  982 + if (!evsel)
  983 + return -EFAULT;
889 984 return perf_evsel__parse_sample(evsel, event, sample);
890 985 }
891 986  
tools/perf/util/evlist.h
... ... @@ -32,6 +32,9 @@
32 32 int nr_fds;
33 33 int nr_mmaps;
34 34 int mmap_len;
  35 + int id_pos;
  36 + int is_pos;
  37 + u64 combined_sample_type;
35 38 struct {
36 39 int cork_fd;
37 40 pid_t pid;
... ... @@ -85,6 +88,8 @@
85 88 int perf_evlist__open(struct perf_evlist *evlist);
86 89 void perf_evlist__close(struct perf_evlist *evlist);
87 90  
  91 +void perf_evlist__set_id_pos(struct perf_evlist *evlist);
  92 +bool perf_can_sample_identifier(void);
88 93 void perf_evlist__config(struct perf_evlist *evlist,
89 94 struct perf_record_opts *opts);
90 95  
... ... @@ -121,7 +126,8 @@
121 126 void perf_evlist__set_leader(struct perf_evlist *evlist);
122 127  
123 128 u64 perf_evlist__read_format(struct perf_evlist *evlist);
124   -u64 perf_evlist__sample_type(struct perf_evlist *evlist);
  129 +u64 __perf_evlist__combined_sample_type(struct perf_evlist *evlist);
  130 +u64 perf_evlist__combined_sample_type(struct perf_evlist *evlist);
125 131 bool perf_evlist__sample_id_all(struct perf_evlist *evlist);
126 132 u16 perf_evlist__id_hdr_size(struct perf_evlist *evlist);
127 133  
tools/perf/util/evsel.c
... ... @@ -31,7 +31,7 @@
31 31  
32 32 #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
33 33  
34   -static int __perf_evsel__sample_size(u64 sample_type)
  34 +int __perf_evsel__sample_size(u64 sample_type)
35 35 {
36 36 u64 mask = sample_type & PERF_SAMPLE_MASK;
37 37 int size = 0;
... ... @@ -47,6 +47,72 @@
47 47 return size;
48 48 }
49 49  
  50 +/**
  51 + * __perf_evsel__calc_id_pos - calculate id_pos.
  52 + * @sample_type: sample type
  53 + *
  54 + * This function returns the position of the event id (PERF_SAMPLE_ID or
  55 + * PERF_SAMPLE_IDENTIFIER) in a sample event i.e. in the array of struct
  56 + * sample_event.
  57 + */
  58 +static int __perf_evsel__calc_id_pos(u64 sample_type)
  59 +{
  60 + int idx = 0;
  61 +
  62 + if (sample_type & PERF_SAMPLE_IDENTIFIER)
  63 + return 0;
  64 +
  65 + if (!(sample_type & PERF_SAMPLE_ID))
  66 + return -1;
  67 +
  68 + if (sample_type & PERF_SAMPLE_IP)
  69 + idx += 1;
  70 +
  71 + if (sample_type & PERF_SAMPLE_TID)
  72 + idx += 1;
  73 +
  74 + if (sample_type & PERF_SAMPLE_TIME)
  75 + idx += 1;
  76 +
  77 + if (sample_type & PERF_SAMPLE_ADDR)
  78 + idx += 1;
  79 +
  80 + return idx;
  81 +}
  82 +
  83 +/**
  84 + * __perf_evsel__calc_is_pos - calculate is_pos.
  85 + * @sample_type: sample type
  86 + *
  87 + * This function returns the position (counting backwards) of the event id
  88 + * (PERF_SAMPLE_ID or PERF_SAMPLE_IDENTIFIER) in a non-sample event i.e. if
  89 + * sample_id_all is used there is an id sample appended to non-sample events.
  90 + */
  91 +static int __perf_evsel__calc_is_pos(u64 sample_type)
  92 +{
  93 + int idx = 1;
  94 +
  95 + if (sample_type & PERF_SAMPLE_IDENTIFIER)
  96 + return 1;
  97 +
  98 + if (!(sample_type & PERF_SAMPLE_ID))
  99 + return -1;
  100 +
  101 + if (sample_type & PERF_SAMPLE_CPU)
  102 + idx += 1;
  103 +
  104 + if (sample_type & PERF_SAMPLE_STREAM_ID)
  105 + idx += 1;
  106 +
  107 + return idx;
  108 +}
  109 +
  110 +void perf_evsel__calc_id_pos(struct perf_evsel *evsel)
  111 +{
  112 + evsel->id_pos = __perf_evsel__calc_id_pos(evsel->attr.sample_type);
  113 + evsel->is_pos = __perf_evsel__calc_is_pos(evsel->attr.sample_type);
  114 +}
  115 +
50 116 void hists__init(struct hists *hists)
51 117 {
52 118 memset(hists, 0, sizeof(*hists));
... ... @@ -63,6 +129,7 @@
63 129 if (!(evsel->attr.sample_type & bit)) {
64 130 evsel->attr.sample_type |= bit;
65 131 evsel->sample_size += sizeof(u64);
  132 + perf_evsel__calc_id_pos(evsel);
66 133 }
67 134 }
68 135  
69 136  
70 137  
... ... @@ -72,12 +139,19 @@
72 139 if (evsel->attr.sample_type & bit) {
73 140 evsel->attr.sample_type &= ~bit;
74 141 evsel->sample_size -= sizeof(u64);
  142 + perf_evsel__calc_id_pos(evsel);
75 143 }
76 144 }
77 145  
78   -void perf_evsel__set_sample_id(struct perf_evsel *evsel)
  146 +void perf_evsel__set_sample_id(struct perf_evsel *evsel,
  147 + bool can_sample_identifier)
79 148 {
80   - perf_evsel__set_sample_bit(evsel, ID);
  149 + if (can_sample_identifier) {
  150 + perf_evsel__reset_sample_bit(evsel, ID);
  151 + perf_evsel__set_sample_bit(evsel, IDENTIFIER);
  152 + } else {
  153 + perf_evsel__set_sample_bit(evsel, ID);
  154 + }
81 155 evsel->attr.read_format |= PERF_FORMAT_ID;
82 156 }
83 157  
... ... @@ -90,6 +164,7 @@
90 164 INIT_LIST_HEAD(&evsel->node);
91 165 hists__init(&evsel->hists);
92 166 evsel->sample_size = __perf_evsel__sample_size(attr->sample_type);
  167 + perf_evsel__calc_id_pos(evsel);
93 168 }
94 169  
95 170 struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx)
... ... @@ -509,7 +584,7 @@
509 584 * We need ID even in case of single event, because
510 585 * PERF_SAMPLE_READ process ID specific data.
511 586 */
512   - perf_evsel__set_sample_id(evsel);
  587 + perf_evsel__set_sample_id(evsel, false);
513 588  
514 589 /*
515 590 * Apply group format only if we belong to group
... ... @@ -1088,6 +1163,11 @@
1088 1163 array += ((event->header.size -
1089 1164 sizeof(event->header)) / sizeof(u64)) - 1;
1090 1165  
  1166 + if (type & PERF_SAMPLE_IDENTIFIER) {
  1167 + sample->id = *array;
  1168 + array--;
  1169 + }
  1170 +
1091 1171 if (type & PERF_SAMPLE_CPU) {
1092 1172 u.val64 = *array;
1093 1173 if (swapped) {
... ... @@ -1184,6 +1264,12 @@
1184 1264 if (evsel->sample_size + sizeof(event->header) > event->header.size)
1185 1265 return -EFAULT;
1186 1266  
  1267 + data->id = -1ULL;
  1268 + if (type & PERF_SAMPLE_IDENTIFIER) {
  1269 + data->id = *array;
  1270 + array++;
  1271 + }
  1272 +
1187 1273 if (type & PERF_SAMPLE_IP) {
1188 1274 data->ip = *array;
1189 1275 array++;
... ... @@ -1214,7 +1300,6 @@
1214 1300 array++;
1215 1301 }
1216 1302  
1217   - data->id = -1ULL;
1218 1303 if (type & PERF_SAMPLE_ID) {
1219 1304 data->id = *array;
1220 1305 array++;
... ... @@ -1396,6 +1481,11 @@
1396 1481  
1397 1482 array = event->sample.array;
1398 1483  
  1484 + if (type & PERF_SAMPLE_IDENTIFIER) {
  1485 + *array = sample->id;
  1486 + array++;
  1487 + }
  1488 +
1399 1489 if (type & PERF_SAMPLE_IP) {
1400 1490 *array = sample->ip;
1401 1491 array++;
... ... @@ -1584,6 +1674,7 @@
1584 1674 bit_name(READ), bit_name(CALLCHAIN), bit_name(ID), bit_name(CPU),
1585 1675 bit_name(PERIOD), bit_name(STREAM_ID), bit_name(RAW),
1586 1676 bit_name(BRANCH_STACK), bit_name(REGS_USER), bit_name(STACK_USER),
  1677 + bit_name(IDENTIFIER),
1587 1678 { .name = NULL, }
1588 1679 };
1589 1680 #undef bit_name
tools/perf/util/evsel.h
... ... @@ -48,6 +48,12 @@
48 48 * @name - Can be set to retain the original event name passed by the user,
49 49 * so that when showing results in tools such as 'perf stat', we
50 50 * show the name used, not some alias.
  51 + * @id_pos: the position of the event id (PERF_SAMPLE_ID or
  52 + * PERF_SAMPLE_IDENTIFIER) in a sample event i.e. in the array of
  53 + * struct sample_event
  54 + * @is_pos: the position (counting backwards) of the event id (PERF_SAMPLE_ID or
  55 + * PERF_SAMPLE_IDENTIFIER) in a non-sample event i.e. if sample_id_all
  56 + * is used there is an id sample appended to non-sample events
51 57 */
52 58 struct perf_evsel {
53 59 struct list_head node;
... ... @@ -74,6 +80,8 @@
74 80 } handler;
75 81 struct cpu_map *cpus;
76 82 unsigned int sample_size;
  83 + int id_pos;
  84 + int is_pos;
77 85 bool supported;
78 86 bool needs_swap;
79 87 /* parse modifier helper */
... ... @@ -104,6 +112,9 @@
104 112 void perf_evsel__config(struct perf_evsel *evsel,
105 113 struct perf_record_opts *opts);
106 114  
  115 +int __perf_evsel__sample_size(u64 sample_type);
  116 +void perf_evsel__calc_id_pos(struct perf_evsel *evsel);
  117 +
107 118 bool perf_evsel__is_cache_op_valid(u8 type, u8 op);
108 119  
109 120 #define PERF_EVSEL__MAX_ALIASES 8
... ... @@ -142,7 +153,8 @@
142 153 #define perf_evsel__reset_sample_bit(evsel, bit) \
143 154 __perf_evsel__reset_sample_bit(evsel, PERF_SAMPLE_##bit)
144 155  
145   -void perf_evsel__set_sample_id(struct perf_evsel *evsel);
  156 +void perf_evsel__set_sample_id(struct perf_evsel *evsel,
  157 + bool use_sample_identifier);
146 158  
147 159 int perf_evsel__set_filter(struct perf_evsel *evsel, int ncpus, int nthreads,
148 160 const char *filter);
tools/perf/util/record.c
1 1 #include "evlist.h"
2 2 #include "evsel.h"
3 3 #include "cpumap.h"
  4 +#include "parse-events.h"
4 5  
  6 +typedef void (*setup_probe_fn_t)(struct perf_evsel *evsel);
  7 +
  8 +static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str)
  9 +{
  10 + struct perf_evlist *evlist;
  11 + struct perf_evsel *evsel;
  12 + int err = -EAGAIN, fd;
  13 +
  14 + evlist = perf_evlist__new();
  15 + if (!evlist)
  16 + return -ENOMEM;
  17 +
  18 + if (parse_events(evlist, str))
  19 + goto out_delete;
  20 +
  21 + evsel = perf_evlist__first(evlist);
  22 +
  23 + fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, 0);
  24 + if (fd < 0)
  25 + goto out_delete;
  26 + close(fd);
  27 +
  28 + fn(evsel);
  29 +
  30 + fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, 0);
  31 + if (fd < 0) {
  32 + if (errno == EINVAL)
  33 + err = -EINVAL;
  34 + goto out_delete;
  35 + }
  36 + close(fd);
  37 + err = 0;
  38 +
  39 +out_delete:
  40 + perf_evlist__delete(evlist);
  41 + return err;
  42 +}
  43 +
  44 +static bool perf_probe_api(setup_probe_fn_t fn)
  45 +{
  46 + const char *try[] = {"cycles:u", "instructions:u", "cpu-clock", NULL};
  47 + struct cpu_map *cpus;
  48 + int cpu, ret, i = 0;
  49 +
  50 + cpus = cpu_map__new(NULL);
  51 + if (!cpus)
  52 + return false;
  53 + cpu = cpus->map[0];
  54 + cpu_map__delete(cpus);
  55 +
  56 + do {
  57 + ret = perf_do_probe_api(fn, cpu, try[i++]);
  58 + if (!ret)
  59 + return true;
  60 + } while (ret == -EAGAIN && try[i]);
  61 +
  62 + return false;
  63 +}
  64 +
  65 +static void perf_probe_sample_identifier(struct perf_evsel *evsel)
  66 +{
  67 + evsel->attr.sample_type |= PERF_SAMPLE_IDENTIFIER;
  68 +}
  69 +
  70 +bool perf_can_sample_identifier(void)
  71 +{
  72 + return perf_probe_api(perf_probe_sample_identifier);
  73 +}
  74 +
5 75 void perf_evlist__config(struct perf_evlist *evlist,
6 76 struct perf_record_opts *opts)
7 77 {
8 78 struct perf_evsel *evsel;
  79 + bool use_sample_identifier = false;
  80 +
9 81 /*
10 82 * Set the evsel leader links before we configure attributes,
11 83 * since some might depend on this info.
12 84  
13 85  
... ... @@ -16,11 +88,22 @@
16 88 if (evlist->cpus->map[0] < 0)
17 89 opts->no_inherit = true;
18 90  
19   - list_for_each_entry(evsel, &evlist->entries, node) {
  91 + list_for_each_entry(evsel, &evlist->entries, node)
20 92 perf_evsel__config(evsel, opts);
21 93  
22   - if (evlist->nr_entries > 1)
23   - perf_evsel__set_sample_id(evsel);
  94 + if (evlist->nr_entries > 1) {
  95 + struct perf_evsel *first = perf_evlist__first(evlist);
  96 +
  97 + list_for_each_entry(evsel, &evlist->entries, node) {
  98 + if (evsel->attr.sample_type == first->attr.sample_type)
  99 + continue;
  100 + use_sample_identifier = perf_can_sample_identifier();
  101 + break;
  102 + }
  103 + list_for_each_entry(evsel, &evlist->entries, node)
  104 + perf_evsel__set_sample_id(evsel, use_sample_identifier);
24 105 }
  106 +
  107 + perf_evlist__set_id_pos(evlist);
25 108 }
tools/perf/util/session.c
... ... @@ -739,7 +739,7 @@
739 739 union perf_event *event,
740 740 struct perf_sample *sample)
741 741 {
742   - u64 sample_type = perf_evlist__sample_type(session->evlist);
  742 + u64 sample_type = __perf_evlist__combined_sample_type(session->evlist);
743 743  
744 744 if (event->header.type != PERF_RECORD_SAMPLE &&
745 745 !perf_evlist__sample_id_all(session->evlist)) {