Skip to content

Commit

Permalink
Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/acme/linux-2.6 into perf/urgent
  • Loading branch information
Ingo Molnar committed Oct 23, 2010
2 parents eea4a0b + 8bfb5e7 commit b8ecad8
Show file tree
Hide file tree
Showing 11 changed files with 823 additions and 236 deletions.
2 changes: 1 addition & 1 deletion include/linux/interrupt.h
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ extern void open_softirq(int nr, void (*action)(struct softirq_action *));
extern void softirq_init(void);
static inline void __raise_softirq_irqoff(unsigned int nr)
{
trace_softirq_raise((struct softirq_action *)(unsigned long)nr, NULL);
trace_softirq_raise(nr);
or_softirq_pending(1UL << nr);
}

Expand Down
54 changes: 20 additions & 34 deletions include/trace/events/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,76 +86,62 @@ TRACE_EVENT(irq_handler_exit,

DECLARE_EVENT_CLASS(softirq,

TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
TP_PROTO(unsigned int vec_nr),

TP_ARGS(h, vec),
TP_ARGS(vec_nr),

TP_STRUCT__entry(
__field( int, vec )
__field( unsigned int, vec )
),

TP_fast_assign(
if (vec)
__entry->vec = (int)(h - vec);
else
__entry->vec = (int)(long)h;
__entry->vec = vec_nr;
),

TP_printk("vec=%d [action=%s]", __entry->vec,
TP_printk("vec=%u [action=%s]", __entry->vec,
show_softirq_name(__entry->vec))
);

/**
* softirq_entry - called immediately before the softirq handler
* @h: pointer to struct softirq_action
* @vec: pointer to first struct softirq_action in softirq_vec array
* @vec_nr: softirq vector number
*
* The @h parameter, contains a pointer to the struct softirq_action
* which has a pointer to the action handler that is called. By subtracting
* the @vec pointer from the @h pointer, we can determine the softirq
* number. Also, when used in combination with the softirq_exit tracepoint
* we can determine the softirq latency.
* When used in combination with the softirq_exit tracepoint
* we can determine the softirq handler runtine.
*/
DEFINE_EVENT(softirq, softirq_entry,

TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
TP_PROTO(unsigned int vec_nr),

TP_ARGS(h, vec)
TP_ARGS(vec_nr)
);

/**
* softirq_exit - called immediately after the softirq handler returns
* @h: pointer to struct softirq_action
* @vec: pointer to first struct softirq_action in softirq_vec array
* @vec_nr: softirq vector number
*
* The @h parameter contains a pointer to the struct softirq_action
* that has handled the softirq. By subtracting the @vec pointer from
* the @h pointer, we can determine the softirq number. Also, when used in
* combination with the softirq_entry tracepoint we can determine the softirq
* latency.
* When used in combination with the softirq_entry tracepoint
* we can determine the softirq handler runtine.
*/
DEFINE_EVENT(softirq, softirq_exit,

TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
TP_PROTO(unsigned int vec_nr),

TP_ARGS(h, vec)
TP_ARGS(vec_nr)
);

/**
* softirq_raise - called immediately when a softirq is raised
* @h: pointer to struct softirq_action
* @vec: pointer to first struct softirq_action in softirq_vec array
* @vec_nr: softirq vector number
*
* The @h parameter contains a pointer to the softirq vector number which is
* raised. @vec is NULL and it means @h includes vector number not
* softirq_action. When used in combination with the softirq_entry tracepoint
* we can determine the softirq raise latency.
* When used in combination with the softirq_entry tracepoint
* we can determine the softirq raise to run latency.
*/
DEFINE_EVENT(softirq, softirq_raise,

TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
TP_PROTO(unsigned int vec_nr),

TP_ARGS(h, vec)
TP_ARGS(vec_nr)
);

#endif /* _TRACE_IRQ_H */
Expand Down
16 changes: 9 additions & 7 deletions kernel/softirq.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,18 +229,20 @@ asmlinkage void __do_softirq(void)

do {
if (pending & 1) {
unsigned int vec_nr = h - softirq_vec;
int prev_count = preempt_count();
kstat_incr_softirqs_this_cpu(h - softirq_vec);

trace_softirq_entry(h, softirq_vec);
kstat_incr_softirqs_this_cpu(vec_nr);

trace_softirq_entry(vec_nr);
h->action(h);
trace_softirq_exit(h, softirq_vec);
trace_softirq_exit(vec_nr);
if (unlikely(prev_count != preempt_count())) {
printk(KERN_ERR "huh, entered softirq %td %s %p"
printk(KERN_ERR "huh, entered softirq %u %s %p"
"with preempt_count %08x,"
" exited with %08x?\n", h - softirq_vec,
softirq_to_name[h - softirq_vec],
h->action, prev_count, preempt_count());
" exited with %08x?\n", vec_nr,
softirq_to_name[vec_nr], h->action,
prev_count, preempt_count());
preempt_count() = prev_count;
}

Expand Down
18 changes: 17 additions & 1 deletion tools/perf/Documentation/perf-probe.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ or
or
'perf probe' --list
or
'perf probe' --line='FUNC[:RLN[+NUM|:RLN2]]|SRC:ALN[+NUM|:ALN2]'
'perf probe' [options] --line='FUNC[:RLN[+NUM|:RLN2]]|SRC:ALN[+NUM|:ALN2]'
or
'perf probe' [options] --vars='PROBEPOINT'

DESCRIPTION
-----------
Expand All @@ -31,6 +33,11 @@ OPTIONS
--vmlinux=PATH::
Specify vmlinux path which has debuginfo (Dwarf binary).

-m::
--module=MODNAME::
Specify module name in which perf-probe searches probe points
or lines.

-s::
--source=PATH::
Specify path to kernel source.
Expand All @@ -57,6 +64,15 @@ OPTIONS
Show source code lines which can be probed. This needs an argument
which specifies a range of the source code. (see LINE SYNTAX for detail)

-V::
--vars=::
Show available local variables at given probe point. The argument
syntax is same as PROBE SYNTAX, but NO ARGs.

--externs::
(Only for --vars) Show external defined variables in addition to local
variables.

-f::
--force::
Forcibly add events with existing name.
Expand Down
78 changes: 67 additions & 11 deletions tools/perf/builtin-probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,17 @@ static struct {
bool list_events;
bool force_add;
bool show_lines;
bool show_vars;
bool show_ext_vars;
bool mod_events;
int nevents;
struct perf_probe_event events[MAX_PROBES];
struct strlist *dellist;
struct line_range line_range;
const char *target_module;
int max_probe_points;
} params;


/* Parse an event definition. Note that any error must die. */
static int parse_probe_event(const char *str)
{
Expand Down Expand Up @@ -92,6 +95,7 @@ static int parse_probe_event_argv(int argc, const char **argv)
len = 0;
for (i = 0; i < argc; i++)
len += sprintf(&buf[len], "%s ", argv[i]);
params.mod_events = true;
ret = parse_probe_event(buf);
free(buf);
return ret;
Expand All @@ -100,16 +104,18 @@ static int parse_probe_event_argv(int argc, const char **argv)
static int opt_add_probe_event(const struct option *opt __used,
const char *str, int unset __used)
{
if (str)
if (str) {
params.mod_events = true;
return parse_probe_event(str);
else
} else
return 0;
}

static int opt_del_probe_event(const struct option *opt __used,
const char *str, int unset __used)
{
if (str) {
params.mod_events = true;
if (!params.dellist)
params.dellist = strlist__new(true, NULL);
strlist__add(params.dellist, str);
Expand All @@ -130,6 +136,25 @@ static int opt_show_lines(const struct option *opt __used,

return ret;
}

static int opt_show_vars(const struct option *opt __used,
const char *str, int unset __used)
{
struct perf_probe_event *pev = &params.events[params.nevents];
int ret;

if (!str)
return 0;

ret = parse_probe_event(str);
if (!ret && pev->nargs != 0) {
pr_err(" Error: '--vars' doesn't accept arguments.\n");
return -EINVAL;
}
params.show_vars = true;

return ret;
}
#endif

static const char * const probe_usage[] = {
Expand All @@ -138,7 +163,8 @@ static const char * const probe_usage[] = {
"perf probe [<options>] --del '[GROUP:]EVENT' ...",
"perf probe --list",
#ifdef DWARF_SUPPORT
"perf probe --line 'LINEDESC'",
"perf probe [<options>] --line 'LINEDESC'",
"perf probe [<options>] --vars 'PROBEPOINT'",
#endif
NULL
};
Expand Down Expand Up @@ -180,10 +206,17 @@ static const struct option options[] = {
OPT_CALLBACK('L', "line", NULL,
"FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]",
"Show source code lines.", opt_show_lines),
OPT_CALLBACK('V', "vars", NULL,
"FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT",
"Show accessible variables on PROBEDEF", opt_show_vars),
OPT_BOOLEAN('\0', "externs", &params.show_ext_vars,
"Show external variables too (with --vars only)"),
OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
"file", "vmlinux pathname"),
OPT_STRING('s', "source", &symbol_conf.source_prefix,
"directory", "path to kernel source"),
OPT_STRING('m', "module", &params.target_module,
"modname", "target module name"),
#endif
OPT__DRY_RUN(&probe_event_dry_run),
OPT_INTEGER('\0', "max-probes", &params.max_probe_points,
Expand Down Expand Up @@ -217,14 +250,18 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
usage_with_options(probe_usage, options);

if (params.list_events) {
if (params.nevents != 0 || params.dellist) {
if (params.mod_events) {
pr_err(" Error: Don't use --list with --add/--del.\n");
usage_with_options(probe_usage, options);
}
if (params.show_lines) {
pr_err(" Error: Don't use --list with --line.\n");
usage_with_options(probe_usage, options);
}
if (params.show_vars) {
pr_err(" Error: Don't use --list with --vars.\n");
usage_with_options(probe_usage, options);
}
ret = show_perf_probe_events();
if (ret < 0)
pr_err(" Error: Failed to show event list. (%d)\n",
Expand All @@ -234,17 +271,35 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)

#ifdef DWARF_SUPPORT
if (params.show_lines) {
if (params.nevents != 0 || params.dellist) {
pr_warning(" Error: Don't use --line with"
" --add/--del.\n");
if (params.mod_events) {
pr_err(" Error: Don't use --line with"
" --add/--del.\n");
usage_with_options(probe_usage, options);
}
if (params.show_vars) {
pr_err(" Error: Don't use --line with --vars.\n");
usage_with_options(probe_usage, options);
}

ret = show_line_range(&params.line_range);
ret = show_line_range(&params.line_range, params.target_module);
if (ret < 0)
pr_err(" Error: Failed to show lines. (%d)\n", ret);
return ret;
}
if (params.show_vars) {
if (params.mod_events) {
pr_err(" Error: Don't use --vars with"
" --add/--del.\n");
usage_with_options(probe_usage, options);
}
ret = show_available_vars(params.events, params.nevents,
params.max_probe_points,
params.target_module,
params.show_ext_vars);
if (ret < 0)
pr_err(" Error: Failed to show vars. (%d)\n", ret);
return ret;
}
#endif

if (params.dellist) {
Expand All @@ -258,8 +313,9 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)

if (params.nevents) {
ret = add_perf_probe_events(params.events, params.nevents,
params.force_add,
params.max_probe_points);
params.max_probe_points,
params.target_module,
params.force_add);
if (ret < 0) {
pr_err(" Error: Failed to add events. (%d)\n", ret);
return ret;
Expand Down
10 changes: 10 additions & 0 deletions tools/perf/util/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,16 @@ struct symbol *map_groups__find_function_by_name(struct map_groups *self,
return map_groups__find_symbol_by_name(self, MAP__FUNCTION, name, mapp, filter);
}

static inline
struct symbol *machine__find_kernel_function_by_name(struct machine *self,
const char *name,
struct map **mapp,
symbol_filter_t filter)
{
return map_groups__find_function_by_name(&self->kmaps, name, mapp,
filter);
}

int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
int verbose, FILE *fp);

Expand Down
Loading

0 comments on commit b8ecad8

Please sign in to comment.