|
@@ -5553,16 +5553,26 @@ void perf_output_sample(struct perf_output_handle *handle,
|
|
|
}
|
|
|
|
|
|
if (sample_type & PERF_SAMPLE_RAW) {
|
|
|
- if (data->raw) {
|
|
|
- u32 raw_size = data->raw->size;
|
|
|
- u32 real_size = round_up(raw_size + sizeof(u32),
|
|
|
- sizeof(u64)) - sizeof(u32);
|
|
|
- u64 zero = 0;
|
|
|
-
|
|
|
- perf_output_put(handle, real_size);
|
|
|
- __output_copy(handle, data->raw->data, raw_size);
|
|
|
- if (real_size - raw_size)
|
|
|
- __output_copy(handle, &zero, real_size - raw_size);
|
|
|
+ struct perf_raw_record *raw = data->raw;
|
|
|
+
|
|
|
+ if (raw) {
|
|
|
+ struct perf_raw_frag *frag = &raw->frag;
|
|
|
+
|
|
|
+ perf_output_put(handle, raw->size);
|
|
|
+ do {
|
|
|
+ if (frag->copy) {
|
|
|
+ __output_custom(handle, frag->copy,
|
|
|
+ frag->data, frag->size);
|
|
|
+ } else {
|
|
|
+ __output_copy(handle, frag->data,
|
|
|
+ frag->size);
|
|
|
+ }
|
|
|
+ if (perf_raw_frag_last(frag))
|
|
|
+ break;
|
|
|
+ frag = frag->next;
|
|
|
+ } while (1);
|
|
|
+ if (frag->pad)
|
|
|
+ __output_skip(handle, NULL, frag->pad);
|
|
|
} else {
|
|
|
struct {
|
|
|
u32 size;
|
|
@@ -5687,14 +5697,28 @@ void perf_prepare_sample(struct perf_event_header *header,
|
|
|
}
|
|
|
|
|
|
if (sample_type & PERF_SAMPLE_RAW) {
|
|
|
- int size = sizeof(u32);
|
|
|
-
|
|
|
- if (data->raw)
|
|
|
- size += data->raw->size;
|
|
|
- else
|
|
|
- size += sizeof(u32);
|
|
|
+ struct perf_raw_record *raw = data->raw;
|
|
|
+ int size;
|
|
|
+
|
|
|
+ if (raw) {
|
|
|
+ struct perf_raw_frag *frag = &raw->frag;
|
|
|
+ u32 sum = 0;
|
|
|
+
|
|
|
+ do {
|
|
|
+ sum += frag->size;
|
|
|
+ if (perf_raw_frag_last(frag))
|
|
|
+ break;
|
|
|
+ frag = frag->next;
|
|
|
+ } while (1);
|
|
|
+
|
|
|
+ size = round_up(sum + sizeof(u32), sizeof(u64));
|
|
|
+ raw->size = size - sizeof(u32);
|
|
|
+ frag->pad = raw->size - sum;
|
|
|
+ } else {
|
|
|
+ size = sizeof(u64);
|
|
|
+ }
|
|
|
|
|
|
- header->size += round_up(size, sizeof(u64));
|
|
|
+ header->size += size;
|
|
|
}
|
|
|
|
|
|
if (sample_type & PERF_SAMPLE_BRANCH_STACK) {
|
|
@@ -7331,7 +7355,7 @@ static struct pmu perf_swevent = {
|
|
|
static int perf_tp_filter_match(struct perf_event *event,
|
|
|
struct perf_sample_data *data)
|
|
|
{
|
|
|
- void *record = data->raw->data;
|
|
|
+ void *record = data->raw->frag.data;
|
|
|
|
|
|
/* only top level events have filters set */
|
|
|
if (event->parent)
|
|
@@ -7387,8 +7411,10 @@ void perf_tp_event(u16 event_type, u64 count, void *record, int entry_size,
|
|
|
struct perf_event *event;
|
|
|
|
|
|
struct perf_raw_record raw = {
|
|
|
- .size = entry_size,
|
|
|
- .data = record,
|
|
|
+ .frag = {
|
|
|
+ .size = entry_size,
|
|
|
+ .data = record,
|
|
|
+ },
|
|
|
};
|
|
|
|
|
|
perf_sample_data_init(&data, 0, 0);
|