2019-09-24 15:41:51 -03:00
// SPDX-License-Identifier: GPL-2.0
# include <inttypes.h>
# include <stdio.h>
# include <stdbool.h>
# include <linux/kernel.h>
# include <linux/types.h>
# include <linux/perf_event.h>
# include "util/evsel_fprintf.h"
struct bit_names {
int bit ;
const char * name ;
} ;
static void __p_bits ( char * buf , size_t size , u64 value , struct bit_names * bits )
{
bool first_bit = true ;
int i = 0 ;
do {
if ( value & bits [ i ] . bit ) {
buf + = scnprintf ( buf , size , " %s%s " , first_bit ? " " : " | " , bits [ i ] . name ) ;
first_bit = false ;
}
} while ( bits [ + + i ] . name ! = NULL ) ;
}
static void __p_sample_type ( char * buf , size_t size , u64 value )
{
# define bit_name(n) { PERF_SAMPLE_##n, #n }
struct bit_names bits [ ] = {
bit_name ( IP ) , bit_name ( TID ) , bit_name ( TIME ) , bit_name ( ADDR ) ,
bit_name ( READ ) , bit_name ( CALLCHAIN ) , bit_name ( ID ) , bit_name ( CPU ) ,
bit_name ( PERIOD ) , bit_name ( STREAM_ID ) , bit_name ( RAW ) ,
bit_name ( BRANCH_STACK ) , bit_name ( REGS_USER ) , bit_name ( STACK_USER ) ,
bit_name ( IDENTIFIER ) , bit_name ( REGS_INTR ) , bit_name ( DATA_SRC ) ,
2019-11-15 14:42:11 +02:00
bit_name ( WEIGHT ) , bit_name ( PHYS_ADDR ) , bit_name ( AUX ) ,
2020-11-30 09:27:53 -08:00
bit_name ( CGROUP ) , bit_name ( DATA_PAGE_SIZE ) ,
2019-09-24 15:41:51 -03:00
{ . name = NULL , }
} ;
# undef bit_name
__p_bits ( buf , size , value , bits ) ;
}
static void __p_branch_sample_type ( char * buf , size_t size , u64 value )
{
# define bit_name(n) { PERF_SAMPLE_BRANCH_##n, #n }
struct bit_names bits [ ] = {
bit_name ( USER ) , bit_name ( KERNEL ) , bit_name ( HV ) , bit_name ( ANY ) ,
bit_name ( ANY_CALL ) , bit_name ( ANY_RETURN ) , bit_name ( IND_CALL ) ,
bit_name ( ABORT_TX ) , bit_name ( IN_TX ) , bit_name ( NO_TX ) ,
bit_name ( COND ) , bit_name ( CALL_STACK ) , bit_name ( IND_JUMP ) ,
bit_name ( CALL ) , bit_name ( NO_FLAGS ) , bit_name ( NO_CYCLES ) ,
perf evsel: Support PERF_SAMPLE_BRANCH_HW_INDEX
A new branch sample type PERF_SAMPLE_BRANCH_HW_INDEX has been introduced
in latest kernel.
Enable HW_INDEX by default in LBR call stack mode.
If kernel doesn't support the sample type, switching it off.
Add HW_INDEX in attr_fprintf as well. User can check whether the branch
sample type is set via debug information or header.
Committer testing:
First collect some samples with LBR callchains, system wide, for a few
seconds:
# perf record --call-graph lbr -a sleep 5
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.625 MB perf.data (224 samples) ]
#
Now lets use 'perf evlist -v' to look at the branch_sample_type:
# perf evlist -v
cycles: size: 120, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|CALLCHAIN|CPU|PERIOD|BRANCH_STACK, read_format: ID, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, task: 1, precise_ip: 3, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, ksymbol: 1, bpf_event: 1, branch_sample_type: USER|CALL_STACK|NO_FLAGS|NO_CYCLES|HW_INDEX
#
So the machine has the kernel feature, and it was correctly added to
perf_event_attr.branch_sample_type, for the default 'cycles' event.
If we do it in another machine, where the kernel lacks the HW_INDEX
feature, we get:
# perf record --call-graph lbr -a sleep 2s
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 1.690 MB perf.data (499 samples) ]
# perf evlist -v
cycles: size: 120, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|CALLCHAIN|CPU|PERIOD|BRANCH_STACK, read_format: ID, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, task: 1, precise_ip: 3, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, ksymbol: 1, bpf_event: 1, branch_sample_type: USER|CALL_STACK|NO_FLAGS|NO_CYCLES
#
No HW_INDEX in attr.branch_sample_type.
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexey Budankov <alexey.budankov@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pavel Gerasimov <pavel.gerasimov@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Vitaly Slobodskoy <vitaly.slobodskoy@intel.com>
Link: http://lore.kernel.org/lkml/20200228163011.19358-3-kan.liang@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-02-28 08:30:01 -08:00
bit_name ( HW_INDEX ) ,
2019-09-24 15:41:51 -03:00
{ . name = NULL , }
} ;
# undef bit_name
__p_bits ( buf , size , value , bits ) ;
}
static void __p_read_format ( char * buf , size_t size , u64 value )
{
# define bit_name(n) { PERF_FORMAT_##n, #n }
struct bit_names bits [ ] = {
bit_name ( TOTAL_TIME_ENABLED ) , bit_name ( TOTAL_TIME_RUNNING ) ,
bit_name ( ID ) , bit_name ( GROUP ) ,
{ . name = NULL , }
} ;
# undef bit_name
__p_bits ( buf , size , value , bits ) ;
}
# define BUF_SIZE 1024
# define p_hex(val) snprintf(buf, BUF_SIZE, "%#"PRIx64, (uint64_t)(val))
# define p_unsigned(val) snprintf(buf, BUF_SIZE, "%"PRIu64, (uint64_t)(val))
# define p_signed(val) snprintf(buf, BUF_SIZE, "%"PRId64, (int64_t)(val))
# define p_sample_type(val) __p_sample_type(buf, BUF_SIZE, val)
# define p_branch_sample_type(val) __p_branch_sample_type(buf, BUF_SIZE, val)
# define p_read_format(val) __p_read_format(buf, BUF_SIZE, val)
# define PRINT_ATTRn(_n, _f, _p) \
do { \
if ( attr - > _f ) { \
_p ( attr - > _f ) ; \
ret + = attr__fprintf ( fp , _n , buf , priv ) ; \
} \
} while ( 0 )
# define PRINT_ATTRf(_f, _p) PRINT_ATTRn(#_f, _f, _p)
int perf_event_attr__fprintf ( FILE * fp , struct perf_event_attr * attr ,
attr__fprintf_f attr__fprintf , void * priv )
{
char buf [ BUF_SIZE ] ;
int ret = 0 ;
PRINT_ATTRf ( type , p_unsigned ) ;
PRINT_ATTRf ( size , p_unsigned ) ;
PRINT_ATTRf ( config , p_hex ) ;
PRINT_ATTRn ( " { sample_period, sample_freq } " , sample_period , p_unsigned ) ;
PRINT_ATTRf ( sample_type , p_sample_type ) ;
PRINT_ATTRf ( read_format , p_read_format ) ;
PRINT_ATTRf ( disabled , p_unsigned ) ;
PRINT_ATTRf ( inherit , p_unsigned ) ;
PRINT_ATTRf ( pinned , p_unsigned ) ;
PRINT_ATTRf ( exclusive , p_unsigned ) ;
PRINT_ATTRf ( exclude_user , p_unsigned ) ;
PRINT_ATTRf ( exclude_kernel , p_unsigned ) ;
PRINT_ATTRf ( exclude_hv , p_unsigned ) ;
PRINT_ATTRf ( exclude_idle , p_unsigned ) ;
PRINT_ATTRf ( mmap , p_unsigned ) ;
PRINT_ATTRf ( comm , p_unsigned ) ;
PRINT_ATTRf ( freq , p_unsigned ) ;
PRINT_ATTRf ( inherit_stat , p_unsigned ) ;
PRINT_ATTRf ( enable_on_exec , p_unsigned ) ;
PRINT_ATTRf ( task , p_unsigned ) ;
PRINT_ATTRf ( watermark , p_unsigned ) ;
PRINT_ATTRf ( precise_ip , p_unsigned ) ;
PRINT_ATTRf ( mmap_data , p_unsigned ) ;
PRINT_ATTRf ( sample_id_all , p_unsigned ) ;
PRINT_ATTRf ( exclude_host , p_unsigned ) ;
PRINT_ATTRf ( exclude_guest , p_unsigned ) ;
PRINT_ATTRf ( exclude_callchain_kernel , p_unsigned ) ;
PRINT_ATTRf ( exclude_callchain_user , p_unsigned ) ;
PRINT_ATTRf ( mmap2 , p_unsigned ) ;
PRINT_ATTRf ( comm_exec , p_unsigned ) ;
PRINT_ATTRf ( use_clockid , p_unsigned ) ;
PRINT_ATTRf ( context_switch , p_unsigned ) ;
PRINT_ATTRf ( write_backward , p_unsigned ) ;
PRINT_ATTRf ( namespaces , p_unsigned ) ;
PRINT_ATTRf ( ksymbol , p_unsigned ) ;
PRINT_ATTRf ( bpf_event , p_unsigned ) ;
PRINT_ATTRf ( aux_output , p_unsigned ) ;
2020-03-25 21:45:30 +09:00
PRINT_ATTRf ( cgroup , p_unsigned ) ;
perf record: Add --buildid-mmap option to enable PERF_RECORD_MMAP2's build id
Add --buildid-mmap option to enable build id in PERF_RECORD_MMAP2 events.
It will only work if there's kernel support for that and it disables
build id cache (implies --no-buildid).
It's also possible to enable it permanently via config option in
~/.perfconfig file:
[record]
build-id=mmap
Also added build_id bit in the verbose output for perf_event_attr:
# perf record --buildid-mmap -vv
...
perf_event_attr:
type 1
size 120
...
build_id 1
Adding also missing text_poke bit.
Committer testing:
$ perf record -h build
Usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]
-B, --no-buildid do not collect buildids in perf.data
-N, --no-buildid-cache
do not update the buildid cache
--buildid-all Record build-id of all DSOs regardless of hits
--buildid-mmap Record build-id in map events
$
$ perf record --buildid-mmap sleep 1
Failed: no support to record build id in mmap events, update your kernel.
$
After adding the needed kernel bits in a test kernel:
$ perf record -vv --buildid-mmap sleep 1 |& grep -m1 build
Enabling build id in mmap2 events.
$ perf evlist -v
cycles:u: size: 120, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD, read_format: ID, disabled: 1, inherit: 1, exclude_kernel: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, ksymbol: 1, bpf_event: 1, build_id: 1
$
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: Ian Rogers <irogers@google.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexei Budankov <abudankov@huawei.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Michael Petlan <mpetlan@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Song Liu <songliubraving@fb.com>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lore.kernel.org/lkml/20201214105457.543111-16-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-12-14 11:54:57 +01:00
PRINT_ATTRf ( text_poke , p_unsigned ) ;
PRINT_ATTRf ( build_id , p_unsigned ) ;
2019-09-24 15:41:51 -03:00
PRINT_ATTRn ( " { wakeup_events, wakeup_watermark } " , wakeup_events , p_unsigned ) ;
PRINT_ATTRf ( bp_type , p_unsigned ) ;
PRINT_ATTRn ( " { bp_addr, config1 } " , bp_addr , p_hex ) ;
PRINT_ATTRn ( " { bp_len, config2 } " , bp_len , p_hex ) ;
PRINT_ATTRf ( branch_sample_type , p_branch_sample_type ) ;
PRINT_ATTRf ( sample_regs_user , p_hex ) ;
PRINT_ATTRf ( sample_stack_user , p_unsigned ) ;
PRINT_ATTRf ( clockid , p_signed ) ;
PRINT_ATTRf ( sample_regs_intr , p_hex ) ;
PRINT_ATTRf ( aux_watermark , p_unsigned ) ;
PRINT_ATTRf ( sample_max_stack , p_unsigned ) ;
2019-11-15 14:42:11 +02:00
PRINT_ATTRf ( aux_sample_size , p_unsigned ) ;
2020-05-12 15:19:18 +03:00
PRINT_ATTRf ( text_poke , p_unsigned ) ;
2019-09-24 15:41:51 -03:00
return ret ;
}