Commit 0a9081cf authored by Namhyung Kim's avatar Namhyung Kim Committed by Ingo Molnar
Browse files

perf/core: Add perf_sample_save_raw_data() helper



When we save the raw_data to the perf sample data, we need to update
the sample flags and the dynamic size.  To make sure this is done
consistently, add the perf_sample_save_raw_data() helper and convert
all call sites.

Suggested-by: default avatarPeter Zijlstra <peterz@infradead.org>
Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
Tested-by: default avatarJiri Olsa <jolsa@kernel.org>
Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
Acked-by: default avatarPeter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20230118060559.615653-4-namhyung@kernel.org
parent 31046500
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -662,9 +662,7 @@ static int cfdiag_push_sample(struct perf_event *event,
	if (event->attr.sample_type & PERF_SAMPLE_RAW) {
		raw.frag.size = cpuhw->usedss;
		raw.frag.data = cpuhw->stop;
		raw.size = raw.frag.size;
		data.raw = &raw;
		data.sample_flags |= PERF_SAMPLE_RAW;
		perf_sample_save_raw_data(&data, &raw);
	}

	overflow = perf_event_overflow(event, &data, &regs);
+1 −3
Original line number Diff line number Diff line
@@ -362,9 +362,7 @@ static int paicrypt_push_sample(void)
	if (event->attr.sample_type & PERF_SAMPLE_RAW) {
		raw.frag.size = rawsize;
		raw.frag.data = cpump->save;
		raw.size = raw.frag.size;
		data.raw = &raw;
		data.sample_flags |= PERF_SAMPLE_RAW;
		perf_sample_save_raw_data(&data, &raw);
	}

	overflow = perf_event_overflow(event, &data, &regs);
+1 −3
Original line number Diff line number Diff line
@@ -451,9 +451,7 @@ static int paiext_push_sample(void)
	if (event->attr.sample_type & PERF_SAMPLE_RAW) {
		raw.frag.size = rawsize;
		raw.frag.data = cpump->save;
		raw.size = raw.frag.size;
		data.raw = &raw;
		data.sample_flags |= PERF_SAMPLE_RAW;
		perf_sample_save_raw_data(&data, &raw);
	}

	overflow = perf_event_overflow(event, &data, &regs);
+1 −2
Original line number Diff line number Diff line
@@ -1110,8 +1110,7 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
				.data = ibs_data.data,
			},
		};
		data.raw = &raw;
		data.sample_flags |= PERF_SAMPLE_RAW;
		perf_sample_save_raw_data(&data, &raw);
	}

	if (perf_ibs == &perf_ibs_op)
+28 −5
Original line number Diff line number Diff line
@@ -95,6 +95,11 @@ struct perf_raw_record {
	u32				size;
};

static __always_inline bool perf_raw_frag_last(const struct perf_raw_frag *frag)
{
	return frag->pad < sizeof(u64);
}

/*
 * branch stack layout:
 *  nr: number of taken branches stored in entries[]
@@ -1182,6 +1187,29 @@ static inline void perf_sample_save_callchain(struct perf_sample_data *data,
	data->sample_flags |= PERF_SAMPLE_CALLCHAIN;
}

static inline void perf_sample_save_raw_data(struct perf_sample_data *data,
					     struct perf_raw_record *raw)
{
	struct perf_raw_frag *frag = &raw->frag;
	u32 sum = 0;
	int size;

	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;

	data->raw = raw;
	data->dyn_size += size;
	data->sample_flags |= PERF_SAMPLE_RAW;
}

/*
 * Clear all bitfields in the perf_branch_entry.
 * The to and from fields are not cleared because they are
@@ -1690,11 +1718,6 @@ extern void perf_restore_debug_store(void);
static inline void perf_restore_debug_store(void)			{ }
#endif

static __always_inline bool perf_raw_frag_last(const struct perf_raw_frag *frag)
{
	return frag->pad < sizeof(u64);
}

#define perf_output_put(handle, x) perf_output_copy((handle), &(x), sizeof(x))

struct perf_pmu_events_attr {
Loading