Skip to content

Commit eb55b45

Browse files
namhyungIngo Molnar
authored andcommitted
perf/core: Add perf_sample_save_brstack() helper
When we saves the branch stack to the perf sample data, we needs to update the sample flags and the dynamic size. To make sure this is done consistently, add the perf_sample_save_brstack() helper and convert all call sites. Suggested-by: Peter Zijlstra <[email protected]> Signed-off-by: Namhyung Kim <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Tested-by: Jiri Olsa <[email protected]> Acked-by: Jiri Olsa <[email protected]> Acked-by: Athira Rajeev <[email protected]> Acked-by: Peter Zijlstra <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 0a9081c commit eb55b45

File tree

6 files changed

+53
-53
lines changed

6 files changed

+53
-53
lines changed

arch/powerpc/perf/core-book3s.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2313,8 +2313,7 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
23132313
struct cpu_hw_events *cpuhw;
23142314
cpuhw = this_cpu_ptr(&cpu_hw_events);
23152315
power_pmu_bhrb_read(event, cpuhw);
2316-
data.br_stack = &cpuhw->bhrb_stack;
2317-
data.sample_flags |= PERF_SAMPLE_BRANCH_STACK;
2316+
perf_sample_save_brstack(&data, event, &cpuhw->bhrb_stack);
23182317
}
23192318

23202319
if (event->attr.sample_type & PERF_SAMPLE_DATA_SRC &&

arch/x86/events/amd/core.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -928,10 +928,8 @@ static int amd_pmu_v2_handle_irq(struct pt_regs *regs)
928928
if (!x86_perf_event_set_period(event))
929929
continue;
930930

931-
if (has_branch_stack(event)) {
932-
data.br_stack = &cpuc->lbr_stack;
933-
data.sample_flags |= PERF_SAMPLE_BRANCH_STACK;
934-
}
931+
if (has_branch_stack(event))
932+
perf_sample_save_brstack(&data, event, &cpuc->lbr_stack);
935933

936934
if (perf_event_overflow(event, &data, regs))
937935
x86_pmu_stop(event, 0);

arch/x86/events/intel/core.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3036,10 +3036,8 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status)
30363036

30373037
perf_sample_data_init(&data, 0, event->hw.last_period);
30383038

3039-
if (has_branch_stack(event)) {
3040-
data.br_stack = &cpuc->lbr_stack;
3041-
data.sample_flags |= PERF_SAMPLE_BRANCH_STACK;
3042-
}
3039+
if (has_branch_stack(event))
3040+
perf_sample_save_brstack(&data, event, &cpuc->lbr_stack);
30433041

30443042
if (perf_event_overflow(event, &data, regs))
30453043
x86_pmu_stop(event, 0);

arch/x86/events/intel/ds.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,10 +1720,8 @@ static void setup_pebs_fixed_sample_data(struct perf_event *event,
17201720
data->sample_flags |= PERF_SAMPLE_TIME;
17211721
}
17221722

1723-
if (has_branch_stack(event)) {
1724-
data->br_stack = &cpuc->lbr_stack;
1725-
data->sample_flags |= PERF_SAMPLE_BRANCH_STACK;
1726-
}
1723+
if (has_branch_stack(event))
1724+
perf_sample_save_brstack(data, event, &cpuc->lbr_stack);
17271725
}
17281726

17291727
static void adaptive_pebs_save_regs(struct pt_regs *regs,
@@ -1883,8 +1881,7 @@ static void setup_pebs_adaptive_sample_data(struct perf_event *event,
18831881

18841882
if (has_branch_stack(event)) {
18851883
intel_pmu_store_pebs_lbrs(lbr);
1886-
data->br_stack = &cpuc->lbr_stack;
1887-
data->sample_flags |= PERF_SAMPLE_BRANCH_STACK;
1884+
perf_sample_save_brstack(data, event, &cpuc->lbr_stack);
18881885
}
18891886
}
18901887

include/linux/perf_event.h

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,31 @@ extern u64 perf_event_read_value(struct perf_event *event,
11021102

11031103
extern struct perf_callchain_entry *perf_callchain(struct perf_event *event, struct pt_regs *regs);
11041104

1105+
static inline bool branch_sample_no_flags(const struct perf_event *event)
1106+
{
1107+
return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_NO_FLAGS;
1108+
}
1109+
1110+
static inline bool branch_sample_no_cycles(const struct perf_event *event)
1111+
{
1112+
return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_NO_CYCLES;
1113+
}
1114+
1115+
static inline bool branch_sample_type(const struct perf_event *event)
1116+
{
1117+
return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_TYPE_SAVE;
1118+
}
1119+
1120+
static inline bool branch_sample_hw_index(const struct perf_event *event)
1121+
{
1122+
return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_HW_INDEX;
1123+
}
1124+
1125+
static inline bool branch_sample_priv(const struct perf_event *event)
1126+
{
1127+
return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_PRIV_SAVE;
1128+
}
1129+
11051130

11061131
struct perf_sample_data {
11071132
/*
@@ -1210,6 +1235,21 @@ static inline void perf_sample_save_raw_data(struct perf_sample_data *data,
12101235
data->sample_flags |= PERF_SAMPLE_RAW;
12111236
}
12121237

1238+
static inline void perf_sample_save_brstack(struct perf_sample_data *data,
1239+
struct perf_event *event,
1240+
struct perf_branch_stack *brs)
1241+
{
1242+
int size = sizeof(u64); /* nr */
1243+
1244+
if (branch_sample_hw_index(event))
1245+
size += sizeof(u64);
1246+
size += brs->nr * sizeof(struct perf_branch_entry);
1247+
1248+
data->br_stack = brs;
1249+
data->dyn_size += size;
1250+
data->sample_flags |= PERF_SAMPLE_BRANCH_STACK;
1251+
}
1252+
12131253
/*
12141254
* Clear all bitfields in the perf_branch_entry.
12151255
* The to and from fields are not cleared because they are
@@ -1827,30 +1867,4 @@ static inline void perf_lopwr_cb(bool mode)
18271867
}
18281868
#endif
18291869

1830-
#ifdef CONFIG_PERF_EVENTS
1831-
static inline bool branch_sample_no_flags(const struct perf_event *event)
1832-
{
1833-
return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_NO_FLAGS;
1834-
}
1835-
1836-
static inline bool branch_sample_no_cycles(const struct perf_event *event)
1837-
{
1838-
return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_NO_CYCLES;
1839-
}
1840-
1841-
static inline bool branch_sample_type(const struct perf_event *event)
1842-
{
1843-
return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_TYPE_SAVE;
1844-
}
1845-
1846-
static inline bool branch_sample_hw_index(const struct perf_event *event)
1847-
{
1848-
return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_HW_INDEX;
1849-
}
1850-
1851-
static inline bool branch_sample_priv(const struct perf_event *event)
1852-
{
1853-
return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_PRIV_SAVE;
1854-
}
1855-
#endif /* CONFIG_PERF_EVENTS */
18561870
#endif /* _LINUX_PERF_EVENT_H */

kernel/events/core.c

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7310,7 +7310,7 @@ void perf_output_sample(struct perf_output_handle *handle,
73107310
}
73117311

73127312
if (sample_type & PERF_SAMPLE_BRANCH_STACK) {
7313-
if (data->sample_flags & PERF_SAMPLE_BRANCH_STACK) {
7313+
if (data->br_stack) {
73147314
size_t size;
73157315

73167316
size = data->br_stack->nr
@@ -7587,16 +7587,10 @@ void perf_prepare_sample(struct perf_event_header *header,
75877587
data->sample_flags |= PERF_SAMPLE_RAW;
75887588
}
75897589

7590-
if (sample_type & PERF_SAMPLE_BRANCH_STACK) {
7591-
int size = sizeof(u64); /* nr */
7592-
if (data->sample_flags & PERF_SAMPLE_BRANCH_STACK) {
7593-
if (branch_sample_hw_index(event))
7594-
size += sizeof(u64);
7595-
7596-
size += data->br_stack->nr
7597-
* sizeof(struct perf_branch_entry);
7598-
}
7599-
data->dyn_size += size;
7590+
if (filtered_sample_type & PERF_SAMPLE_BRANCH_STACK) {
7591+
data->br_stack = NULL;
7592+
data->dyn_size += sizeof(u64);
7593+
data->sample_flags |= PERF_SAMPLE_BRANCH_STACK;
76007594
}
76017595

76027596
if (sample_type & (PERF_SAMPLE_REGS_USER | PERF_SAMPLE_STACK_USER))

0 commit comments

Comments
 (0)