Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
aef29bf2
Commit
aef29bf2
authored
Jun 03, 2011
by
Ingo Molnar
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'perf/core' of
ssh://k/pub/scm/linux/kernel/git/acme/linux
into perf/core
parents
27eb4a1e
7cec0922
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
245 additions
and
110 deletions
+245
-110
tools/perf/Documentation/perf-script.txt
tools/perf/Documentation/perf-script.txt
+6
-6
tools/perf/builtin-script.c
tools/perf/builtin-script.c
+98
-10
tools/perf/builtin-stat.c
tools/perf/builtin-stat.c
+7
-2
tools/perf/builtin-test.c
tools/perf/builtin-test.c
+1
-1
tools/perf/util/event.c
tools/perf/util/event.c
+0
-16
tools/perf/util/event.h
tools/perf/util/event.h
+0
-2
tools/perf/util/evlist.c
tools/perf/util/evlist.c
+38
-30
tools/perf/util/evlist.h
tools/perf/util/evlist.h
+4
-2
tools/perf/util/evsel.c
tools/perf/util/evsel.c
+17
-0
tools/perf/util/evsel.h
tools/perf/util/evsel.h
+8
-0
tools/perf/util/python.c
tools/perf/util/python.c
+14
-15
tools/perf/util/session.c
tools/perf/util/session.c
+49
-24
tools/perf/util/session.h
tools/perf/util/session.h
+3
-2
No files found.
tools/perf/Documentation/perf-script.txt
View file @
aef29bf2
...
...
@@ -115,10 +115,10 @@ OPTIONS
-f::
--fields::
Comma separated list of fields to print. Options are:
comm, tid, pid, time, cpu, event, trace,
sym. Field
list can be prepended with the type, trace, sw or hw,
comm, tid, pid, time, cpu, event, trace,
ip, sym, dso, addr.
Field
list can be prepended with the type, trace, sw or hw,
to indicate to which event type the field list applies.
e.g., -f sw:comm,tid,time,sym and -f trace:time,cpu,trace
e.g., -f sw:comm,tid,time,
ip,
sym and -f trace:time,cpu,trace
perf script -f <fields>
...
...
@@ -132,17 +132,17 @@ OPTIONS
The arguments are processed in the order received. A later usage can
reset a prior request. e.g.:
-f trace: -f comm,tid,time,sym
-f trace: -f comm,tid,time,
ip,
sym
The first -f suppresses trace events (field list is ""), but then the
second invocation sets the fields to comm,tid,time,sym. In this case a
second invocation sets the fields to comm,tid,time,
ip,
sym. In this case a
warning is given to the user:
"Overriding previous field request for all events."
Alternativey, consider the order:
-f comm,tid,time,sym -f trace:
-f comm,tid,time,
ip,
sym -f trace:
The first -f sets the fields for all events and the second -f
suppresses trace events. The user is given a warning message about
...
...
tools/perf/builtin-script.c
View file @
aef29bf2
...
...
@@ -30,7 +30,10 @@ enum perf_output_field {
PERF_OUTPUT_CPU
=
1U
<<
4
,
PERF_OUTPUT_EVNAME
=
1U
<<
5
,
PERF_OUTPUT_TRACE
=
1U
<<
6
,
PERF_OUTPUT_SYM
=
1U
<<
7
,
PERF_OUTPUT_IP
=
1U
<<
7
,
PERF_OUTPUT_SYM
=
1U
<<
8
,
PERF_OUTPUT_DSO
=
1U
<<
9
,
PERF_OUTPUT_ADDR
=
1U
<<
10
,
};
struct
output_option
{
...
...
@@ -44,7 +47,10 @@ struct output_option {
{.
str
=
"cpu"
,
.
field
=
PERF_OUTPUT_CPU
},
{.
str
=
"event"
,
.
field
=
PERF_OUTPUT_EVNAME
},
{.
str
=
"trace"
,
.
field
=
PERF_OUTPUT_TRACE
},
{.
str
=
"ip"
,
.
field
=
PERF_OUTPUT_IP
},
{.
str
=
"sym"
,
.
field
=
PERF_OUTPUT_SYM
},
{.
str
=
"dso"
,
.
field
=
PERF_OUTPUT_DSO
},
{.
str
=
"addr"
,
.
field
=
PERF_OUTPUT_ADDR
},
};
/* default set to maintain compatibility with current format */
...
...
@@ -60,7 +66,8 @@ static struct {
.
fields
=
PERF_OUTPUT_COMM
|
PERF_OUTPUT_TID
|
PERF_OUTPUT_CPU
|
PERF_OUTPUT_TIME
|
PERF_OUTPUT_EVNAME
|
PERF_OUTPUT_SYM
,
PERF_OUTPUT_EVNAME
|
PERF_OUTPUT_IP
|
PERF_OUTPUT_SYM
|
PERF_OUTPUT_DSO
,
.
invalid_fields
=
PERF_OUTPUT_TRACE
,
},
...
...
@@ -70,7 +77,8 @@ static struct {
.
fields
=
PERF_OUTPUT_COMM
|
PERF_OUTPUT_TID
|
PERF_OUTPUT_CPU
|
PERF_OUTPUT_TIME
|
PERF_OUTPUT_EVNAME
|
PERF_OUTPUT_SYM
,
PERF_OUTPUT_EVNAME
|
PERF_OUTPUT_IP
|
PERF_OUTPUT_SYM
|
PERF_OUTPUT_DSO
,
.
invalid_fields
=
PERF_OUTPUT_TRACE
,
},
...
...
@@ -88,7 +96,8 @@ static struct {
.
fields
=
PERF_OUTPUT_COMM
|
PERF_OUTPUT_TID
|
PERF_OUTPUT_CPU
|
PERF_OUTPUT_TIME
|
PERF_OUTPUT_EVNAME
|
PERF_OUTPUT_SYM
,
PERF_OUTPUT_EVNAME
|
PERF_OUTPUT_IP
|
PERF_OUTPUT_SYM
|
PERF_OUTPUT_DSO
,
.
invalid_fields
=
PERF_OUTPUT_TRACE
,
},
...
...
@@ -157,9 +166,9 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
!
perf_session__has_traces
(
session
,
"record -R"
))
return
-
EINVAL
;
if
(
PRINT_FIELD
(
SYM
))
{
if
(
PRINT_FIELD
(
IP
))
{
if
(
perf_event_attr__check_stype
(
attr
,
PERF_SAMPLE_IP
,
"IP"
,
PERF_OUTPUT_
SYM
))
PERF_OUTPUT_
IP
))
return
-
EINVAL
;
if
(
!
no_callchain
&&
...
...
@@ -167,6 +176,24 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
symbol_conf
.
use_callchain
=
false
;
}
if
(
PRINT_FIELD
(
ADDR
)
&&
perf_event_attr__check_stype
(
attr
,
PERF_SAMPLE_ADDR
,
"ADDR"
,
PERF_OUTPUT_ADDR
))
return
-
EINVAL
;
if
(
PRINT_FIELD
(
SYM
)
&&
!
PRINT_FIELD
(
IP
)
&&
!
PRINT_FIELD
(
ADDR
))
{
pr_err
(
"Display of symbols requested but neither sample IP nor "
"sample address
\n
is selected. Hence, no addresses to convert "
"to symbols.
\n
"
);
return
-
EINVAL
;
}
if
(
PRINT_FIELD
(
DSO
)
&&
!
PRINT_FIELD
(
IP
)
&&
!
PRINT_FIELD
(
ADDR
))
{
pr_err
(
"Display of DSO requested but neither sample IP nor "
"sample address
\n
is selected. Hence, no addresses to convert "
"to DSO.
\n
"
);
return
-
EINVAL
;
}
if
((
PRINT_FIELD
(
PID
)
||
PRINT_FIELD
(
TID
))
&&
perf_event_attr__check_stype
(
attr
,
PERF_SAMPLE_TID
,
"TID"
,
PERF_OUTPUT_TID
|
PERF_OUTPUT_PID
))
...
...
@@ -230,7 +257,7 @@ static void print_sample_start(struct perf_sample *sample,
if
(
PRINT_FIELD
(
COMM
))
{
if
(
latency_format
)
printf
(
"%8.8s "
,
thread
->
comm
);
else
if
(
PRINT_FIELD
(
SYM
)
&&
symbol_conf
.
use_callchain
)
else
if
(
PRINT_FIELD
(
IP
)
&&
symbol_conf
.
use_callchain
)
printf
(
"%s "
,
thread
->
comm
);
else
printf
(
"%16s "
,
thread
->
comm
);
...
...
@@ -271,6 +298,63 @@ static void print_sample_start(struct perf_sample *sample,
}
}
static
bool
sample_addr_correlates_sym
(
struct
perf_event_attr
*
attr
)
{
if
((
attr
->
type
==
PERF_TYPE_SOFTWARE
)
&&
((
attr
->
config
==
PERF_COUNT_SW_PAGE_FAULTS
)
||
(
attr
->
config
==
PERF_COUNT_SW_PAGE_FAULTS_MIN
)
||
(
attr
->
config
==
PERF_COUNT_SW_PAGE_FAULTS_MAJ
)))
return
true
;
return
false
;
}
static
void
print_sample_addr
(
union
perf_event
*
event
,
struct
perf_sample
*
sample
,
struct
perf_session
*
session
,
struct
thread
*
thread
,
struct
perf_event_attr
*
attr
)
{
struct
addr_location
al
;
u8
cpumode
=
event
->
header
.
misc
&
PERF_RECORD_MISC_CPUMODE_MASK
;
const
char
*
symname
,
*
dsoname
;
printf
(
"%16"
PRIx64
,
sample
->
addr
);
if
(
!
sample_addr_correlates_sym
(
attr
))
return
;
thread__find_addr_map
(
thread
,
session
,
cpumode
,
MAP__FUNCTION
,
event
->
ip
.
pid
,
sample
->
addr
,
&
al
);
if
(
!
al
.
map
)
thread__find_addr_map
(
thread
,
session
,
cpumode
,
MAP__VARIABLE
,
event
->
ip
.
pid
,
sample
->
addr
,
&
al
);
al
.
cpu
=
sample
->
cpu
;
al
.
sym
=
NULL
;
if
(
al
.
map
)
al
.
sym
=
map__find_symbol
(
al
.
map
,
al
.
addr
,
NULL
);
if
(
PRINT_FIELD
(
SYM
))
{
if
(
al
.
sym
&&
al
.
sym
->
name
)
symname
=
al
.
sym
->
name
;
else
symname
=
""
;
printf
(
" %16s"
,
symname
);
}
if
(
PRINT_FIELD
(
DSO
))
{
if
(
al
.
map
&&
al
.
map
->
dso
&&
al
.
map
->
dso
->
name
)
dsoname
=
al
.
map
->
dso
->
name
;
else
dsoname
=
""
;
printf
(
" (%s)"
,
dsoname
);
}
}
static
void
process_event
(
union
perf_event
*
event
__unused
,
struct
perf_sample
*
sample
,
struct
perf_evsel
*
evsel
,
...
...
@@ -288,12 +372,16 @@ static void process_event(union perf_event *event __unused,
print_trace_event
(
sample
->
cpu
,
sample
->
raw_data
,
sample
->
raw_size
);
if
(
PRINT_FIELD
(
SYM
))
{
if
(
PRINT_FIELD
(
ADDR
))
print_sample_addr
(
event
,
sample
,
session
,
thread
,
attr
);
if
(
PRINT_FIELD
(
IP
))
{
if
(
!
symbol_conf
.
use_callchain
)
printf
(
" "
);
else
printf
(
"
\n
"
);
perf_session__print_symbols
(
event
,
sample
,
session
);
perf_session__print_ip
(
event
,
sample
,
session
,
PRINT_FIELD
(
SYM
),
PRINT_FIELD
(
DSO
));
}
printf
(
"
\n
"
);
...
...
@@ -985,7 +1073,7 @@ static const struct option options[] = {
OPT_STRING
(
0
,
"symfs"
,
&
symbol_conf
.
symfs
,
"directory"
,
"Look for files with symbols relative to this directory"
),
OPT_CALLBACK
(
'f'
,
"fields"
,
NULL
,
"str"
,
"comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,
sym
"
,
"comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,
ip,sym,dso,addr
"
,
parse_output_fields
),
OPT_END
()
...
...
tools/perf/builtin-stat.c
View file @
aef29bf2
...
...
@@ -61,6 +61,8 @@
#include <locale.h>
#define DEFAULT_SEPARATOR " "
#define CNTR_NOT_SUPPORTED "<not supported>"
#define CNTR_NOT_COUNTED "<not counted>"
static
struct
perf_event_attr
default_attrs
[]
=
{
...
...
@@ -448,6 +450,7 @@ static int run_perf_stat(int argc __used, const char **argv)
if
(
verbose
)
ui__warning
(
"%s event is not supported by the kernel.
\n
"
,
event_name
(
counter
));
counter
->
supported
=
false
;
continue
;
}
...
...
@@ -466,6 +469,7 @@ static int run_perf_stat(int argc __used, const char **argv)
die
(
"Not all events could be opened.
\n
"
);
return
-
1
;
}
counter
->
supported
=
true
;
}
if
(
perf_evlist__set_filters
(
evsel_list
))
{
...
...
@@ -861,7 +865,7 @@ static void print_counter_aggr(struct perf_evsel *counter)
if
(
scaled
==
-
1
)
{
fprintf
(
stderr
,
"%*s%s%*s"
,
csv_output
?
0
:
18
,
"<not counted>"
,
counter
->
supported
?
CNTR_NOT_COUNTED
:
CNTR_NOT_SUPPORTED
,
csv_sep
,
csv_output
?
0
:
-
24
,
event_name
(
counter
));
...
...
@@ -914,7 +918,8 @@ static void print_counter(struct perf_evsel *counter)
csv_output
?
0
:
-
4
,
evsel_list
->
cpus
->
map
[
cpu
],
csv_sep
,
csv_output
?
0
:
18
,
"<not counted>"
,
csv_sep
,
counter
->
supported
?
CNTR_NOT_COUNTED
:
CNTR_NOT_SUPPORTED
,
csv_sep
,
csv_output
?
0
:
-
24
,
event_name
(
counter
));
...
...
tools/perf/builtin-test.c
View file @
aef29bf2
...
...
@@ -474,7 +474,7 @@ static int test__basic_mmap(void)
unsigned
int
nr_events
[
nsyscalls
],
expected_nr_events
[
nsyscalls
],
i
,
j
;
struct
perf_evsel
*
evsels
[
nsyscalls
],
*
evsel
;
int
sample_size
=
perf
_sample_size
(
attr
.
sample_type
);
int
sample_size
=
__perf_evsel_
_sample_size
(
attr
.
sample_type
);
for
(
i
=
0
;
i
<
nsyscalls
;
++
i
)
{
char
name
[
64
];
...
...
tools/perf/util/event.c
View file @
aef29bf2
...
...
@@ -35,22 +35,6 @@ const char *perf_event__name(unsigned int id)
return
perf_event__names
[
id
];
}
int
perf_sample_size
(
u64
sample_type
)
{
u64
mask
=
sample_type
&
PERF_SAMPLE_MASK
;
int
size
=
0
;
int
i
;
for
(
i
=
0
;
i
<
64
;
i
++
)
{
if
(
mask
&
(
1ULL
<<
i
))
size
++
;
}
size
*=
sizeof
(
u64
);
return
size
;
}
static
struct
perf_sample
synth_sample
=
{
.
pid
=
-
1
,
.
tid
=
-
1
,
...
...
tools/perf/util/event.h
View file @
aef29bf2
...
...
@@ -82,8 +82,6 @@ struct perf_sample {
struct
ip_callchain
*
callchain
;
};
int
perf_sample_size
(
u64
sample_type
);
#define BUILD_ID_SIZE 20
struct
build_id_event
{
...
...
tools/perf/util/evlist.c
View file @
aef29bf2
...
...
@@ -12,7 +12,6 @@
#include "evlist.h"
#include "evsel.h"
#include "util.h"
#include "debug.h"
#include <sys/mman.h>
...
...
@@ -257,19 +256,15 @@ int perf_evlist__alloc_mmap(struct perf_evlist *evlist)
return
evlist
->
mmap
!=
NULL
?
0
:
-
ENOMEM
;
}
static
int
__perf_evlist__mmap
(
struct
perf_evlist
*
evlist
,
struct
perf_evsel
*
evsel
,
static
int
__perf_evlist__mmap
(
struct
perf_evlist
*
evlist
,
int
idx
,
int
prot
,
int
mask
,
int
fd
)
{
evlist
->
mmap
[
idx
].
prev
=
0
;
evlist
->
mmap
[
idx
].
mask
=
mask
;
evlist
->
mmap
[
idx
].
base
=
mmap
(
NULL
,
evlist
->
mmap_len
,
prot
,
MAP_SHARED
,
fd
,
0
);
if
(
evlist
->
mmap
[
idx
].
base
==
MAP_FAILED
)
{
if
(
evlist
->
cpus
->
map
[
idx
]
==
-
1
&&
evsel
->
attr
.
inherit
)
ui__warning
(
"Inherit is not allowed on per-task "
"events using mmap.
\n
"
);
if
(
evlist
->
mmap
[
idx
].
base
==
MAP_FAILED
)
return
-
1
;
}
perf_evlist__add_pollfd
(
evlist
,
fd
);
return
0
;
...
...
@@ -289,7 +284,7 @@ static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int m
if
(
output
==
-
1
)
{
output
=
fd
;
if
(
__perf_evlist__mmap
(
evlist
,
evsel
,
cpu
,
if
(
__perf_evlist__mmap
(
evlist
,
cpu
,
prot
,
mask
,
output
)
<
0
)
goto
out_unmap
;
}
else
{
...
...
@@ -329,7 +324,7 @@ static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, in
if
(
output
==
-
1
)
{
output
=
fd
;
if
(
__perf_evlist__mmap
(
evlist
,
evsel
,
thread
,
if
(
__perf_evlist__mmap
(
evlist
,
thread
,
prot
,
mask
,
output
)
<
0
)
goto
out_unmap
;
}
else
{
...
...
@@ -460,33 +455,46 @@ int perf_evlist__set_filters(struct perf_evlist *evlist)
return
0
;
}
u64
perf_evlist__sample_type
(
struct
perf_evlist
*
evlist
)
bool
perf_evlist__valid_sample_type
(
const
struct
perf_evlist
*
evlist
)
{
struct
perf_evsel
*
pos
;
u64
type
=
0
;
list_for_each_entry
(
pos
,
&
evlist
->
entries
,
node
)
{
if
(
!
type
)
type
=
pos
->
attr
.
sample_type
;
else
if
(
type
!=
pos
->
attr
.
sample_type
)
die
(
"non matching sample_type"
);
struct
perf_evsel
*
pos
,
*
first
;
pos
=
first
=
list_entry
(
evlist
->
entries
.
next
,
struct
perf_evsel
,
node
);
list_for_each_entry_continue
(
pos
,
&
evlist
->
entries
,
node
)
{
if
(
first
->
attr
.
sample_type
!=
pos
->
attr
.
sample_type
)
return
false
;
}
return
t
yp
e
;
return
t
ru
e
;
}
bool
perf_evlist__sample_id_all
(
const
struct
perf_evlist
*
evlist
)
u64
perf_evlist__sample_type
(
const
struct
perf_evlist
*
evlist
)
{
struct
perf_evsel
*
first
;
first
=
list_entry
(
evlist
->
entries
.
next
,
struct
perf_evsel
,
node
);
return
first
->
attr
.
sample_type
;
}
bool
perf_evlist__valid_sample_id_all
(
const
struct
perf_evlist
*
evlist
)
{
bool
value
=
false
,
first
=
true
;
struct
perf_evsel
*
pos
;
list_for_each_entry
(
pos
,
&
evlist
->
entries
,
node
)
{
if
(
first
)
{
value
=
pos
->
attr
.
sample_id_all
;
first
=
false
;
}
else
if
(
value
!=
pos
->
attr
.
sample_id_all
)
die
(
"non matching sample_id_all"
);
struct
perf_evsel
*
pos
,
*
first
;
pos
=
first
=
list_entry
(
evlist
->
entries
.
next
,
struct
perf_evsel
,
node
);
list_for_each_entry_continue
(
pos
,
&
evlist
->
entries
,
node
)
{
if
(
first
->
attr
.
sample_id_all
!=
pos
->
attr
.
sample_id_all
)
return
false
;
}
return
value
;
return
true
;
}
bool
perf_evlist__sample_id_all
(
const
struct
perf_evlist
*
evlist
)
{
struct
perf_evsel
*
first
;
first
=
list_entry
(
evlist
->
entries
.
next
,
struct
perf_evsel
,
node
);
return
first
->
attr
.
sample_id_all
;
}
tools/perf/util/evlist.h
View file @
aef29bf2
...
...
@@ -66,7 +66,9 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid,
void
perf_evlist__delete_maps
(
struct
perf_evlist
*
evlist
);
int
perf_evlist__set_filters
(
struct
perf_evlist
*
evlist
);
u64
perf_evlist__sample_type
(
struct
perf_evlist
*
evlist
);
bool
perf_evlist__sample_id_all
(
const
struct
perf_evlist
*
evlist
);
u64
perf_evlist__sample_type
(
const
struct
perf_evlist
*
evlist
);
bool
perf_evlist__sample_id_all
(
const
const
struct
perf_evlist
*
evlist
);
bool
perf_evlist__valid_sample_type
(
const
struct
perf_evlist
*
evlist
);
bool
perf_evlist__valid_sample_id_all
(
const
struct
perf_evlist
*
evlist
);
#endif
/* __PERF_EVLIST_H */
tools/perf/util/evsel.c
View file @
aef29bf2
...
...
@@ -15,6 +15,22 @@
#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
int
__perf_evsel__sample_size
(
u64
sample_type
)
{
u64
mask
=
sample_type
&
PERF_SAMPLE_MASK
;
int
size
=
0
;
int
i
;
for
(
i
=
0
;
i
<
64
;
i
++
)
{
if
(
mask
&
(
1ULL
<<
i
))
size
++
;
}
size
*=
sizeof
(
u64
);
return
size
;
}
void
perf_evsel__init
(
struct
perf_evsel
*
evsel
,
struct
perf_event_attr
*
attr
,
int
idx
)
{
...
...
@@ -361,6 +377,7 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
array
++
;
}
data
->
addr
=
0
;
if
(
type
&
PERF_SAMPLE_ADDR
)
{
data
->
addr
=
*
array
;
array
++
;
...
...
tools/perf/util/evsel.h
View file @
aef29bf2
...
...
@@ -61,6 +61,7 @@ struct perf_evsel {
off_t
id_offset
;
};
struct
cgroup_sel
*
cgrp
;
bool
supported
;
};
struct
cpu_map
;
...
...
@@ -149,4 +150,11 @@ static inline int perf_evsel__read_scaled(struct perf_evsel *evsel,
return
__perf_evsel__read
(
evsel
,
ncpus
,
nthreads
,
true
);
}
int
__perf_evsel__sample_size
(
u64
sample_type
);
static
inline
int
perf_evsel__sample_size
(
struct
perf_evsel
*
evsel
)
{
return
__perf_evsel__sample_size
(
evsel
->
attr
.
sample_type
);
}
#endif
/* __PERF_EVSEL_H */
tools/perf/util/python.c
View file @
aef29bf2
...
...
@@ -247,7 +247,7 @@ struct pyrf_cpu_map {
static
int
pyrf_cpu_map__init
(
struct
pyrf_cpu_map
*
pcpus
,
PyObject
*
args
,
PyObject
*
kwargs
)
{
static
char
*
kwlist
[]
=
{
"cpustr"
,
NULL
,
NULL
,
};
static
char
*
kwlist
[]
=
{
"cpustr"
,
NULL
};
char
*
cpustr
=
NULL
;
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kwargs
,
"|s"
,
...
...
@@ -316,7 +316,7 @@ struct pyrf_thread_map {
static
int
pyrf_thread_map__init
(
struct
pyrf_thread_map
*
pthreads
,
PyObject
*
args
,
PyObject
*
kwargs
)
{
static
char
*
kwlist
[]
=
{
"pid"
,
"tid"
,
NULL
,
NULL
,
};
static
char
*
kwlist
[]
=
{
"pid"
,
"tid"
,
NULL
};
int
pid
=
-
1
,
tid
=
-
1
;
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kwargs
,
"|ii"
,
...
...
@@ -418,7 +418,9 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
"wakeup_events"
,
"bp_type"
,
"bp_addr"
,
"bp_len"
,
NULL
,
NULL
,
};
"bp_len"
,
NULL
};
u64
sample_period
=
0
;
u32
disabled
=
0
,
inherit
=
0
,
...
...
@@ -499,7 +501,7 @@ static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
struct
thread_map
*
threads
=
NULL
;
PyObject
*
pcpus
=
NULL
,
*
pthreads
=
NULL
;
int
group
=
0
,
inherit
=
0
;
static
char
*
kwlist
[]
=
{
"cpus"
,
"threads"
,
"group"
,
"inherit"
,
NULL
,
NULL
};
static
char
*
kwlist
[]
=
{
"cpus"
,
"threads"
,
"group"
,
"inherit"
,
NULL
};
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kwargs
,
"|OOii"
,
kwlist
,
&
pcpus
,
&
pthreads
,
&
group
,
&
inherit
))
...
...
@@ -582,8 +584,7 @@ static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
PyObject
*
args
,
PyObject
*
kwargs
)
{
struct
perf_evlist
*
evlist
=
&
pevlist
->
evlist
;
static
char
*
kwlist
[]
=
{
"pages"
,
"overwrite"
,
NULL
,
NULL
};
static
char
*
kwlist
[]
=
{
"pages"
,
"overwrite"
,
NULL
};
int
pages
=
128
,
overwrite
=
false
;
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kwargs
,
"|ii"
,
kwlist
,
...
...
@@ -603,7 +604,7 @@ static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,
PyObject
*
args
,
PyObject
*
kwargs
)
{
struct
perf_evlist
*
evlist
=
&
pevlist
->
evlist
;
static
char
*
kwlist
[]
=
{
"timeout"
,
NULL
,
NULL
};
static
char
*
kwlist
[]
=
{
"timeout"
,
NULL
};
int
timeout
=
-
1
,
n
;
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kwargs
,
"|i"
,
kwlist
,
&
timeout
))
...
...
@@ -674,7 +675,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
struct
perf_evlist
*
evlist
=
&
pevlist
->
evlist
;
union
perf_event
*
event
;
int
sample_id_all
=
1
,
cpu
;
static
char
*
kwlist
[]
=
{
"sample_id_all"
,
NULL
,
NULL
};
static
char
*
kwlist
[]
=
{
"cpu"
,
"sample_id_all"
,
NULL
};
int
err
;
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kwargs
,
"i|i"
,
kwlist
,
...
...
@@ -692,16 +693,14 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
first
=
list_entry
(
evlist
->
entries
.
next
,
struct
perf_evsel
,
node
);
err
=
perf_event__parse_sample
(
event
,
first
->
attr
.
sample_type
,
perf_
sample_size
(
first
->
attr
.
sample_type
),
perf_
evsel__sample_size
(
first
),
sample_id_all
,
&
pevent
->
sample
);
if
(
err
)
{
pr_err
(
"Can't parse sample, err = %d
\n
"
,
err
);
goto
end
;
}
if
(
err
)
return
PyErr_Format
(
PyExc_OSError
,
"perf: can't parse sample, err=%d"
,
err
);
return
pyevent
;
}
end:
Py_INCREF
(
Py_None
);
return
Py_None
;
}
...
...
tools/perf/util/session.c
View file @
aef29bf2
...
...
@@ -58,6 +58,16 @@ static int perf_session__open(struct perf_session *self, bool force)
goto
out_close
;
}
if
(
!
perf_evlist__valid_sample_type
(
self
->
evlist
))
{
pr_err
(
"non matching sample_type"
);
goto
out_close
;
}
if
(
!
perf_evlist__valid_sample_id_all
(
self
->
evlist
))
{
pr_err
(
"non matching sample_id_all"
);
goto
out_close
;
}
self
->
size
=
input_stat
.
st_size
;
return
0
;
...
...
@@ -97,7 +107,7 @@ static void perf_session__id_header_size(struct perf_session *session)
void
perf_session__update_sample_type
(
struct
perf_session
*
self
)
{
self
->
sample_type
=
perf_evlist__sample_type
(
self
->
evlist
);
self
->
sample_size
=
perf
_sample_size
(
self
->
sample_type
);
self
->
sample_size
=
__perf_evsel_
_sample_size
(
self
->
sample_type
);
self
->
sample_id_all
=
perf_evlist__sample_id_all
(
self
->
evlist
);
perf_session__id_header_size
(
self
);
}
...
...
@@ -698,9 +708,9 @@ static void dump_sample(struct perf_session *session, union perf_event *event,
if
(
!
dump_trace
)
return
;
printf
(
"(IP, %d): %d/%d: %#"
PRIx64
" period: %"
PRIu64
"
\n
"
,
printf
(
"(IP, %d): %d/%d: %#"
PRIx64
" period: %"
PRIu64
"
addr: %#"
PRIx64
"
\n
"
,
event
->
header
.
misc
,
sample
->
pid
,
sample
->
tid
,
sample
->
ip
,
sample
->
period
);
sample
->
period
,
sample
->
addr
);
if
(
session
->
sample_type
&
PERF_SAMPLE_CALLCHAIN
)
callchain__printf
(
sample
);
...
...
@@ -1192,9 +1202,10 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
return
NULL
;
}
void
perf_session__print_symbols
(
union
perf_event
*
event
,
struct
perf_sample
*
sample
,
struct
perf_session
*
session
)
void
perf_session__print_ip
(
union
perf_event
*
event
,
struct
perf_sample
*
sample
,
struct
perf_session
*
session
,
int
print_sym
,
int
print_dso
)
{
struct
addr_location
al
;
const
char
*
symname
,
*
dsoname
;
...
...
@@ -1223,32 +1234,46 @@ void perf_session__print_symbols(union perf_event *event,
if
(
!
node
)
break
;
if
(
node
->
sym
&&
node
->
sym
->
name
)
symname
=
node
->
sym
->
name
;
else
symname
=
""
;
printf
(
"
\t
%16"
PRIx64
,
node
->
ip
);
if
(
print_sym
)
{
if
(
node
->
sym
&&
node
->
sym
->
name
)
symname
=
node
->
sym
->
name
;
else
symname
=
""
;
if
(
node
->
map
&&
node
->
map
->
dso
&&
node
->
map
->
dso
->
name
)
dsoname
=
node
->
map
->
dso
->
name
;
else
dsoname
=
""
;
printf
(
" %s"
,
symname
);
}
if
(
print_dso
)
{
if
(
node
->
map
&&
node
->
map
->
dso
&&
node
->
map
->
dso
->
name
)
dsoname
=
node
->
map
->
dso
->
name
;
else
dsoname
=
""
;
printf
(
"
\t
%16"
PRIx64
" %s (%s)
\n
"
,
node
->
ip
,
symname
,
dsoname
);
printf
(
" (%s)"
,
dsoname
);
}
printf
(
"
\n
"
);
callchain_cursor_advance
(
cursor
);
}
}
else
{
if
(
al
.
sym
&&
al
.
sym
->
name
)
symname
=
al
.
sym
->
name
;
else
symname
=
""
;
printf
(
"%16"
PRIx64
,
al
.
addr
);
if
(
print_sym
)
{
if
(
al
.
sym
&&
al
.
sym
->
name
)
symname
=
al
.
sym
->
name
;
else
symname
=
""
;
if
(
al
.
map
&&
al
.
map
->
dso
&&
al
.
map
->
dso
->
name
)
dsoname
=
al
.
map
->
dso
->
name
;
else
dsoname
=
""
;
printf
(
" %s"
,
symname
);
}
printf
(
"%16"
PRIx64
" %s (%s)"
,
al
.
addr
,
symname
,
dsoname
);
if
(
print_dso
)
{
if
(
al
.
map
&&
al
.
map
->
dso
&&
al
.
map
->
dso
->
name
)
dsoname
=
al
.
map
->
dso
->
name
;
else
dsoname
=
""
;
printf
(
" (%s)"
,
dsoname
);
}
}
}
tools/perf/util/session.h
View file @
aef29bf2
...
...
@@ -167,8 +167,9 @@ static inline int perf_session__parse_sample(struct perf_session *session,
struct
perf_evsel
*
perf_session__find_first_evtype
(
struct
perf_session
*
session
,
unsigned
int
type
);
void
perf_session__print_
symbols
(
union
perf_event
*
event
,
void
perf_session__print_
ip
(
union
perf_event
*
event
,
struct
perf_sample
*
sample
,
struct
perf_session
*
session
);
struct
perf_session
*
session
,
int
print_sym
,
int
print_dso
);
#endif
/* __PERF_SESSION_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment