Skip to content

Commit

Permalink
Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/l…
Browse files Browse the repository at this point in the history
…inux/kernel/git/tip/linux-2.6-tip

* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (52 commits)
  perf record: Use per-task-per-cpu events for inherited events
  perf record: Properly synchronize child creation
  perf events: Allow per-task-per-cpu counters
  perf diff: Percent calcs should use double values
  perf diff: Change the default sort order to "dso,symbol"
  perf diff: Use perf_session__fprintf_hists just like 'perf record'
  perf report: Fix cut'n'paste error recently introduced
  perf session: Move perf report specific hits out of perf_session__fprintf_hists
  perf tools: Move hist entries printing routines from perf report
  perf report: Generalize perf_session__fprintf_hists()
  perf symbols: Move symbol filtering to event__preprocess_sample()
  perf symbols: Adopt the strlists for dso, comm
  perf symbols: Make symbol_conf global
  perf probe: Fix to show which probe point is not found
  perf probe: Check symbols in symtab/kallsyms
  perf probe: Check build-id of vmlinux
  perf probe: Reject second attempt of adding same-name event
  perf probe: Support event name for --add option
  perf probe: Add glob matching support on --del
  perf probe: Use strlist__for_each macros in probe-event.c
  ...
  • Loading branch information
Linus Torvalds committed Dec 16, 2009
2 parents bac5e54 + 60ab271 commit 8aedf8a
Show file tree
Hide file tree
Showing 53 changed files with 2,293 additions and 1,413 deletions.
12 changes: 3 additions & 9 deletions include/linux/perf_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,17 +211,11 @@ struct perf_event_attr {
__u32 wakeup_watermark; /* bytes before wakeup */
};

struct { /* Hardware breakpoint info */
__u64 bp_addr;
__u32 bp_type;
__u32 bp_len;
__u64 __bp_reserved_1;
__u64 __bp_reserved_2;
};

__u32 __reserved_2;

__u64 __reserved_3;
__u64 bp_addr;
__u32 bp_type;
__u32 bp_len;
};

/*
Expand Down
15 changes: 9 additions & 6 deletions kernel/perf_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,9 @@ static void __perf_install_in_context(void *info)

add_event_to_ctx(event, ctx);

if (event->cpu != -1 && event->cpu != smp_processor_id())
goto unlock;

/*
* Don't put the event on if it is disabled or if
* it is in a group and the group isn't on.
Expand Down Expand Up @@ -925,6 +928,9 @@ static void __perf_event_enable(void *info)
goto unlock;
__perf_event_mark_enabled(event, ctx);

if (event->cpu != -1 && event->cpu != smp_processor_id())
goto unlock;

/*
* If the event is in a group and isn't the group leader,
* then don't put it on unless the group is on.
Expand Down Expand Up @@ -1595,15 +1601,12 @@ static struct perf_event_context *find_get_context(pid_t pid, int cpu)
unsigned long flags;
int err;

/*
* If cpu is not a wildcard then this is a percpu event:
*/
if (cpu != -1) {
if (pid == -1 && cpu != -1) {
/* Must be root to operate on a CPU event: */
if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
return ERR_PTR(-EACCES);

if (cpu < 0 || cpu > num_possible_cpus())
if (cpu < 0 || cpu >= nr_cpumask_bits)
return ERR_PTR(-EINVAL);

/*
Expand Down Expand Up @@ -4564,7 +4567,7 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr,
if (attr->type >= PERF_TYPE_MAX)
return -EINVAL;

if (attr->__reserved_1 || attr->__reserved_2 || attr->__reserved_3)
if (attr->__reserved_1 || attr->__reserved_2)
return -EINVAL;

if (attr->sample_type & ~(PERF_SAMPLE_MAX-1))
Expand Down
55 changes: 55 additions & 0 deletions tools/perf/Documentation/perf-diff.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
perf-diff(1)
==============

NAME
----
perf-diff - Read two perf.data files and display the differential profile

SYNOPSIS
--------
[verse]
'perf diff' [oldfile] [newfile]

DESCRIPTION
-----------
This command displays the performance difference amongst two perf.data files
captured via perf record.

If no parameters are passed it will assume perf.data.old and perf.data.

OPTIONS
-------
-d::
--dsos=::
Only consider symbols in these dsos. CSV that understands
file://filename entries.

-C::
--comms=::
Only consider symbols in these comms. CSV that understands
file://filename entries.

-S::
--symbols=::
Only consider these symbols. CSV that understands
file://filename entries.

-s::
--sort=::
Sort by key(s): pid, comm, dso, symbol.

-t::
--field-separator=::

Use a special separator character and don't pad with spaces, replacing
all occurances of this separator in symbol names (and other output)
with a '.' character, that thus it's the only non valid separator.

-v::
--verbose::
Be verbose, for instance, show the raw counts in addition to the
diff.

SEE ALSO
--------
linkperf:perf-record[1]
3 changes: 2 additions & 1 deletion tools/perf/Documentation/perf-probe.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ PROBE SYNTAX
------------
Probe points are defined by following syntax.

"FUNC[+OFFS|:RLN|%return][@SRC]|SRC:ALN [ARG ...]"
"[EVENT=]FUNC[+OFFS|:RLN|%return][@SRC]|SRC:ALN [ARG ...]"

'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. Currently, event group name is set as 'probe'.
'FUNC' specifies a probed function name, and it may have one of the following options; '+OFFS' is the offset from function entry address in bytes, 'RLN' is the relative-line number from function entry line, and '%return' means that it probes function return. In addition, 'SRC' specifies a source file which has that function.
It is also possible to specify a probe point by the source line number by using 'SRC:ALN' syntax, where 'SRC' is the source file path and 'ALN' is the line number.
'ARG' specifies the arguments of this probe point. You can use the name of local variable, or kprobe-tracer argument format (e.g. $retval, %ax, etc).
Expand Down
4 changes: 4 additions & 0 deletions tools/perf/Documentation/perf-report.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ OPTIONS
Only consider these symbols. CSV that understands
file://filename entries.

-s::
--sort=::
Sort by key(s): pid, comm, dso, symbol, parent.

-w::
--field-width=::
Force each column width to the provided list, for large terminal
Expand Down
27 changes: 26 additions & 1 deletion tools/perf/Documentation/perf-trace.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,43 @@ perf-trace - Read perf.data (created by perf record) and display trace output
SYNOPSIS
--------
[verse]
'perf trace' [-i <file> | --input=file] symbol_name
'perf trace' {record <script> | report <script> [args] }

DESCRIPTION
-----------
This command reads the input file and displays the trace recorded.

There are several variants of perf trace:

'perf trace' to see a detailed trace of the workload that was
recorded.

'perf trace record <script>' to record the events required for 'perf
trace report'. <script> is the name displayed in the output of
'perf trace --list' i.e. the actual script name minus any language
extension.

'perf trace report <script>' to run and display the results of
<script>. <script> is the name displayed in the output of 'perf
trace --list' i.e. the actual script name minus any language
extension. The perf.data output from a previous run of 'perf trace
record <script>' is used and should be present for this command to
succeed.

OPTIONS
-------
-D::
--dump-raw-trace=::
Display verbose dump of the trace data.

-L::
--Latency=::
Show latency attributes (irqs/preemption disabled, etc).

-l::
--list=::
Display a list of available trace scripts.

-s::
--script=::
Process trace data with the given script ([lang]:script[.ext]).
Expand Down
4 changes: 1 addition & 3 deletions tools/perf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,6 @@ LIB_H += util/values.h
LIB_H += util/sort.h
LIB_H += util/hist.h
LIB_H += util/thread.h
LIB_H += util/data_map.h
LIB_H += util/probe-finder.h
LIB_H += util/probe-event.h

Expand Down Expand Up @@ -428,6 +427,7 @@ BUILTIN_OBJS += bench/sched-messaging.o
BUILTIN_OBJS += bench/sched-pipe.o
BUILTIN_OBJS += bench/mem-memcpy.o

BUILTIN_OBJS += builtin-diff.o
BUILTIN_OBJS += builtin-help.o
BUILTIN_OBJS += builtin-sched.o
BUILTIN_OBJS += builtin-buildid-list.o
Expand Down Expand Up @@ -996,8 +996,6 @@ install: all
$(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
$(INSTALL) scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'
$(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
$(INSTALL) scripts/perl/Perf-Trace-Util/Makefile.PL -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util'
$(INSTALL) scripts/perl/Perf-Trace-Util/README -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util'
ifdef BUILT_INS
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
$(INSTALL) $(BUILT_INS) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
Expand Down
66 changes: 23 additions & 43 deletions tools/perf/builtin-annotate.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#include "util/sort.h"
#include "util/hist.h"
#include "util/session.h"
#include "util/data_map.h"

static char const *input_name = "perf.data";

Expand All @@ -52,11 +51,6 @@ struct sym_priv {
struct sym_ext *ext;
};

static struct symbol_conf symbol_conf = {
.priv_size = sizeof(struct sym_priv),
.try_vmlinux_path = true,
};

static const char *sym_hist_filter;

static int symbol_filter(struct map *map __used, struct symbol *sym)
Expand Down Expand Up @@ -122,30 +116,32 @@ static void hist_hit(struct hist_entry *he, u64 ip)
h->ip[offset]);
}

static int hist_entry__add(struct addr_location *al, u64 count)
static int perf_session__add_hist_entry(struct perf_session *self,
struct addr_location *al, u64 count)
{
bool hit;
struct hist_entry *he = __hist_entry__add(al, NULL, count, &hit);
struct hist_entry *he = __perf_session__add_hist_entry(self, al, NULL,
count, &hit);
if (he == NULL)
return -ENOMEM;
hist_hit(he, al->addr);
return 0;
}

static int process_sample_event(event_t *event)
static int process_sample_event(event_t *event, struct perf_session *session)
{
struct addr_location al;

dump_printf("(IP, %d): %d: %p\n", event->header.misc,
event->ip.pid, (void *)(long)event->ip.ip);

if (event__preprocess_sample(event, &al, symbol_filter) < 0) {
if (event__preprocess_sample(event, session, &al, symbol_filter) < 0) {
fprintf(stderr, "problem processing %d event, skipping it.\n",
event->header.type);
return -1;
}

if (hist_entry__add(&al, 1)) {
if (!al.filtered && perf_session__add_hist_entry(session, &al, 1)) {
fprintf(stderr, "problem incrementing symbol count, "
"skipping event\n");
return -1;
Expand Down Expand Up @@ -429,11 +425,11 @@ static void annotate_sym(struct hist_entry *he)
free_source_line(he, len);
}

static void find_annotations(void)
static void perf_session__find_annotations(struct perf_session *self)
{
struct rb_node *nd;

for (nd = rb_first(&output_hists); nd; nd = rb_next(nd)) {
for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) {
struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
struct sym_priv *priv;

Expand All @@ -454,7 +450,7 @@ static void find_annotations(void)
}
}

static struct perf_file_handler file_handler = {
static struct perf_event_ops event_ops = {
.process_sample_event = process_sample_event,
.process_mmap_event = event__process_mmap,
.process_comm_event = event__process_comm,
Expand All @@ -463,17 +459,14 @@ static struct perf_file_handler file_handler = {

static int __cmd_annotate(void)
{
struct perf_session *session = perf_session__new(input_name, O_RDONLY, force);
struct thread *idle;
int ret;
struct perf_session *session;

session = perf_session__new(input_name, O_RDONLY, force);
if (session == NULL)
return -ENOMEM;

idle = register_idle_thread();
register_perf_file_handler(&file_handler);

ret = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd);
ret = perf_session__process_events(session, &event_ops);
if (ret)
goto out_delete;

Expand All @@ -483,15 +476,14 @@ static int __cmd_annotate(void)
}

if (verbose > 3)
threads__fprintf(stdout);
perf_session__fprintf(session, stdout);

if (verbose > 2)
dsos__fprintf(stdout);

collapse__resort();
output__resort(event__total[0]);

find_annotations();
perf_session__collapse_resort(session);
perf_session__output_resort(session, session->event_total[0]);
perf_session__find_annotations(session);
out_delete:
perf_session__delete(session);

Expand Down Expand Up @@ -524,29 +516,17 @@ static const struct option options[] = {
OPT_END()
};

static void setup_sorting(void)
int cmd_annotate(int argc, const char **argv, const char *prefix __used)
{
char *tmp, *tok, *str = strdup(sort_order);

for (tok = strtok_r(str, ", ", &tmp);
tok; tok = strtok_r(NULL, ", ", &tmp)) {
if (sort_dimension__add(tok) < 0) {
error("Unknown --sort key: `%s'", tok);
usage_with_options(annotate_usage, options);
}
}
argc = parse_options(argc, argv, options, annotate_usage, 0);

free(str);
}
symbol_conf.priv_size = sizeof(struct sym_priv);
symbol_conf.try_vmlinux_path = true;

int cmd_annotate(int argc, const char **argv, const char *prefix __used)
{
if (symbol__init(&symbol_conf) < 0)
if (symbol__init() < 0)
return -1;

argc = parse_options(argc, argv, options, annotate_usage, 0);

setup_sorting();
setup_sorting(annotate_usage, options);

if (argc) {
/*
Expand Down
4 changes: 2 additions & 2 deletions tools/perf/builtin-buildid-list.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include "builtin.h"
#include "perf.h"
#include "util/cache.h"
#include "util/data_map.h"
#include "util/debug.h"
#include "util/parse-options.h"
#include "util/session.h"
Expand Down Expand Up @@ -55,8 +54,9 @@ static int perf_file_section__process_buildids(struct perf_file_section *self,
static int __cmd_buildid_list(void)
{
int err = -1;
struct perf_session *session = perf_session__new(input_name, O_RDONLY, force);
struct perf_session *session;

session = perf_session__new(input_name, O_RDONLY, force);
if (session == NULL)
return -1;

Expand Down
Loading

0 comments on commit 8aedf8a

Please sign in to comment.