You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'perf/scripting' into perf/core
Merge reason: it's ready for v2.6.33. Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
@@ -0,0 +1,219 @@
|
||||
perf-trace-perl(1)
|
||||
==================
|
||||
|
||||
NAME
|
||||
----
|
||||
perf-trace-perl - Process trace data with a Perl script
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'perf trace' [-s [lang]:script[.ext] ]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
This perf trace option is used to process perf trace data using perf's
|
||||
built-in Perl interpreter. It reads and processes the input file and
|
||||
displays the results of the trace analysis implemented in the given
|
||||
Perl script, if any.
|
||||
|
||||
STARTER SCRIPTS
|
||||
---------------
|
||||
|
||||
You can avoid reading the rest of this document by running 'perf trace
|
||||
-g perl' in the same directory as an existing perf.data trace file.
|
||||
That will generate a starter script containing a handler for each of
|
||||
the event types in the trace file; it simply prints every available
|
||||
field for each event in the trace file.
|
||||
|
||||
You can also look at the existing scripts in
|
||||
~/libexec/perf-core/scripts/perl for typical examples showing how to
|
||||
do basic things like aggregate event data, print results, etc. Also,
|
||||
the check-perf-trace.pl script, while not interesting for its results,
|
||||
attempts to exercise all of the main scripting features.
|
||||
|
||||
EVENT HANDLERS
|
||||
--------------
|
||||
|
||||
When perf trace is invoked using a trace script, a user-defined
|
||||
'handler function' is called for each event in the trace. If there's
|
||||
no handler function defined for a given event type, the event is
|
||||
ignored (or passed to a 'trace_handled' function, see below) and the
|
||||
next event is processed.
|
||||
|
||||
Most of the event's field values are passed as arguments to the
|
||||
handler function; some of the less common ones aren't - those are
|
||||
available as calls back into the perf executable (see below).
|
||||
|
||||
As an example, the following perf record command can be used to record
|
||||
all sched_wakeup events in the system:
|
||||
|
||||
# perf record -c 1 -f -a -M -R -e sched:sched_wakeup
|
||||
|
||||
Traces meant to be processed using a script should be recorded with
|
||||
the above options: -c 1 says to sample every event, -a to enable
|
||||
system-wide collection, -M to multiplex the output, and -R to collect
|
||||
raw samples.
|
||||
|
||||
The format file for the sched_wakep event defines the following fields
|
||||
(see /sys/kernel/debug/tracing/events/sched/sched_wakeup/format):
|
||||
|
||||
----
|
||||
format:
|
||||
field:unsigned short common_type;
|
||||
field:unsigned char common_flags;
|
||||
field:unsigned char common_preempt_count;
|
||||
field:int common_pid;
|
||||
field:int common_lock_depth;
|
||||
|
||||
field:char comm[TASK_COMM_LEN];
|
||||
field:pid_t pid;
|
||||
field:int prio;
|
||||
field:int success;
|
||||
field:int target_cpu;
|
||||
----
|
||||
|
||||
The handler function for this event would be defined as:
|
||||
|
||||
----
|
||||
sub sched::sched_wakeup
|
||||
{
|
||||
my ($event_name, $context, $common_cpu, $common_secs,
|
||||
$common_nsecs, $common_pid, $common_comm,
|
||||
$comm, $pid, $prio, $success, $target_cpu) = @_;
|
||||
}
|
||||
----
|
||||
|
||||
The handler function takes the form subsystem::event_name.
|
||||
|
||||
The $common_* arguments in the handler's argument list are the set of
|
||||
arguments passed to all event handlers; some of the fields correspond
|
||||
to the common_* fields in the format file, but some are synthesized,
|
||||
and some of the common_* fields aren't common enough to to be passed
|
||||
to every event as arguments but are available as library functions.
|
||||
|
||||
Here's a brief description of each of the invariant event args:
|
||||
|
||||
$event_name the name of the event as text
|
||||
$context an opaque 'cookie' used in calls back into perf
|
||||
$common_cpu the cpu the event occurred on
|
||||
$common_secs the secs portion of the event timestamp
|
||||
$common_nsecs the nsecs portion of the event timestamp
|
||||
$common_pid the pid of the current task
|
||||
$common_comm the name of the current process
|
||||
|
||||
All of the remaining fields in the event's format file have
|
||||
counterparts as handler function arguments of the same name, as can be
|
||||
seen in the example above.
|
||||
|
||||
The above provides the basics needed to directly access every field of
|
||||
every event in a trace, which covers 90% of what you need to know to
|
||||
write a useful trace script. The sections below cover the rest.
|
||||
|
||||
SCRIPT LAYOUT
|
||||
-------------
|
||||
|
||||
Every perf trace Perl script should start by setting up a Perl module
|
||||
search path and 'use'ing a few support modules (see module
|
||||
descriptions below):
|
||||
|
||||
----
|
||||
use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib";
|
||||
use lib "./Perf-Trace-Util/lib";
|
||||
use Perf::Trace::Core;
|
||||
use Perf::Trace::Context;
|
||||
use Perf::Trace::Util;
|
||||
----
|
||||
|
||||
The rest of the script can contain handler functions and support
|
||||
functions in any order.
|
||||
|
||||
Aside from the event handler functions discussed above, every script
|
||||
can implement a set of optional functions:
|
||||
|
||||
*trace_begin*, if defined, is called before any event is processed and
|
||||
gives scripts a chance to do setup tasks:
|
||||
|
||||
----
|
||||
sub trace_begin
|
||||
{
|
||||
}
|
||||
----
|
||||
|
||||
*trace_end*, if defined, is called after all events have been
|
||||
processed and gives scripts a chance to do end-of-script tasks, such
|
||||
as display results:
|
||||
|
||||
----
|
||||
sub trace_end
|
||||
{
|
||||
}
|
||||
----
|
||||
|
||||
*trace_unhandled*, if defined, is called after for any event that
|
||||
doesn't have a handler explicitly defined for it. The standard set
|
||||
of common arguments are passed into it:
|
||||
|
||||
----
|
||||
sub trace_unhandled
|
||||
{
|
||||
my ($event_name, $context, $common_cpu, $common_secs,
|
||||
$common_nsecs, $common_pid, $common_comm) = @_;
|
||||
}
|
||||
----
|
||||
|
||||
The remaining sections provide descriptions of each of the available
|
||||
built-in perf trace Perl modules and their associated functions.
|
||||
|
||||
AVAILABLE MODULES AND FUNCTIONS
|
||||
-------------------------------
|
||||
|
||||
The following sections describe the functions and variables available
|
||||
via the various Perf::Trace::* Perl modules. To use the functions and
|
||||
variables from the given module, add the corresponding 'use
|
||||
Perf::Trace::XXX' line to your perf trace script.
|
||||
|
||||
Perf::Trace::Core Module
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
These functions provide some essential functions to user scripts.
|
||||
|
||||
The *flag_str* and *symbol_str* functions provide human-readable
|
||||
strings for flag and symbolic fields. These correspond to the strings
|
||||
and values parsed from the 'print fmt' fields of the event format
|
||||
files:
|
||||
|
||||
flag_str($event_name, $field_name, $field_value) - returns the string represention corresponding to $field_value for the flag field $field_name of event $event_name
|
||||
symbol_str($event_name, $field_name, $field_value) - returns the string represention corresponding to $field_value for the symbolic field $field_name of event $event_name
|
||||
|
||||
Perf::Trace::Context Module
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Some of the 'common' fields in the event format file aren't all that
|
||||
common, but need to be made accessible to user scripts nonetheless.
|
||||
|
||||
Perf::Trace::Context defines a set of functions that can be used to
|
||||
access this data in the context of the current event. Each of these
|
||||
functions expects a $context variable, which is the same as the
|
||||
$context variable passed into every event handler as the second
|
||||
argument.
|
||||
|
||||
common_pc($context) - returns common_preempt count for the current event
|
||||
common_flags($context) - returns common_flags for the current event
|
||||
common_lock_depth($context) - returns common_lock_depth for the current event
|
||||
|
||||
Perf::Trace::Util Module
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Various utility functions for use with perf trace:
|
||||
|
||||
nsecs($secs, $nsecs) - returns total nsecs given secs/nsecs pair
|
||||
nsecs_secs($nsecs) - returns whole secs portion given nsecs
|
||||
nsecs_nsecs($nsecs) - returns nsecs remainder given nsecs
|
||||
nsecs_str($nsecs) - returns printable string in the form secs.nsecs
|
||||
avg($total, $n) - returns average given a sum and a total number of values
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
linkperf:perf-trace[1]
|
||||
@@ -20,6 +20,15 @@ OPTIONS
|
||||
--dump-raw-trace=::
|
||||
Display verbose dump of the trace data.
|
||||
|
||||
-s::
|
||||
--script=::
|
||||
Process trace data with the given script ([lang]:script[.ext]).
|
||||
|
||||
-g::
|
||||
--gen-script=::
|
||||
Generate perf-trace.[ext] starter script for given language,
|
||||
using current perf.data.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
linkperf:perf-record[1]
|
||||
linkperf:perf-record[1], linkperf:perf-trace-perl[1]
|
||||
|
||||
+25
-1
@@ -409,6 +409,7 @@ LIB_OBJS += util/thread.o
|
||||
LIB_OBJS += util/trace-event-parse.o
|
||||
LIB_OBJS += util/trace-event-read.o
|
||||
LIB_OBJS += util/trace-event-info.o
|
||||
LIB_OBJS += util/trace-event-perl.o
|
||||
LIB_OBJS += util/svghelper.o
|
||||
LIB_OBJS += util/sort.o
|
||||
LIB_OBJS += util/hist.o
|
||||
@@ -491,6 +492,16 @@ else
|
||||
LIB_OBJS += util/probe-finder.o
|
||||
endif
|
||||
|
||||
PERL_EMBED_LDOPTS = `perl -MExtUtils::Embed -e ldopts 2>/dev/null`
|
||||
PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
|
||||
|
||||
ifneq ($(shell sh -c "(echo '\#include <EXTERN.h>'; echo '\#include <perl.h>'; echo 'int main(void) { perl_alloc(); return 0; }') | $(CC) -x c - $(PERL_EMBED_CCOPTS) -o /dev/null $(PERL_EMBED_LDOPTS) > /dev/null 2>&1 && echo y"), y)
|
||||
BASIC_CFLAGS += -DNO_LIBPERL
|
||||
else
|
||||
ALL_LDFLAGS += $(PERL_EMBED_LDOPTS)
|
||||
LIB_OBJS += scripts/perl/Perf-Trace-Util/Context.o
|
||||
endif
|
||||
|
||||
ifdef NO_DEMANGLE
|
||||
BASIC_CFLAGS += -DNO_DEMANGLE
|
||||
else
|
||||
@@ -862,6 +873,12 @@ util/hweight.o: ../../lib/hweight.c PERF-CFLAGS
|
||||
util/find_next_bit.o: ../../lib/find_next_bit.c PERF-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o util/find_next_bit.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
|
||||
|
||||
util/trace-event-perl.o: util/trace-event-perl.c PERF-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o util/trace-event-perl.o -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
|
||||
|
||||
scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c PERF-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o scripts/perl/Perf-Trace-Util/Context.o -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
|
||||
|
||||
perf-%$X: %.o $(PERFLIBS)
|
||||
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
|
||||
|
||||
@@ -969,6 +986,13 @@ export perfexec_instdir
|
||||
install: all
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
|
||||
$(INSTALL) perf$X '$(DESTDIR_SQ)$(bindir_SQ)'
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
|
||||
$(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)'
|
||||
@@ -1054,7 +1078,7 @@ distclean: clean
|
||||
# $(RM) configure
|
||||
|
||||
clean:
|
||||
$(RM) *.o */*.o $(LIB_FILE)
|
||||
$(RM) *.o */*.o */*/*.o */*/*/*.o $(LIB_FILE)
|
||||
$(RM) $(ALL_PROGRAMS) $(BUILT_INS) perf$X
|
||||
$(RM) $(TEST_PROGRAMS)
|
||||
$(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope*
|
||||
|
||||
+254
-5
@@ -5,6 +5,50 @@
|
||||
#include "util/symbol.h"
|
||||
#include "util/thread.h"
|
||||
#include "util/header.h"
|
||||
#include "util/exec_cmd.h"
|
||||
#include "util/trace-event.h"
|
||||
|
||||
static char const *script_name;
|
||||
static char const *generate_script_lang;
|
||||
|
||||
static int default_start_script(const char *script __attribute((unused)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int default_stop_script(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int default_generate_script(const char *outfile __attribute ((unused)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct scripting_ops default_scripting_ops = {
|
||||
.start_script = default_start_script,
|
||||
.stop_script = default_stop_script,
|
||||
.process_event = print_event,
|
||||
.generate_script = default_generate_script,
|
||||
};
|
||||
|
||||
static struct scripting_ops *scripting_ops;
|
||||
|
||||
static void setup_scripting(void)
|
||||
{
|
||||
/* make sure PERF_EXEC_PATH is set for scripts */
|
||||
perf_set_argv_exec_path(perf_exec_path());
|
||||
|
||||
setup_perl_scripting();
|
||||
|
||||
scripting_ops = &default_scripting_ops;
|
||||
}
|
||||
|
||||
static int cleanup_scripting(void)
|
||||
{
|
||||
return scripting_ops->stop_script();
|
||||
}
|
||||
|
||||
#include "util/parse-options.h"
|
||||
|
||||
@@ -13,11 +57,12 @@
|
||||
|
||||
#include "util/trace-event.h"
|
||||
#include "util/data_map.h"
|
||||
#include "util/exec_cmd.h"
|
||||
|
||||
static char const *input_name = "perf.data";
|
||||
static char const *input_name = "perf.data";
|
||||
|
||||
static struct perf_header *header;
|
||||
static u64 sample_type;
|
||||
static struct perf_header *header;
|
||||
static u64 sample_type;
|
||||
|
||||
static int process_sample_event(event_t *event)
|
||||
{
|
||||
@@ -69,7 +114,8 @@ static int process_sample_event(event_t *event)
|
||||
* field, although it should be the same than this perf
|
||||
* event pid
|
||||
*/
|
||||
print_event(cpu, raw->data, raw->size, timestamp, thread->comm);
|
||||
scripting_ops->process_event(cpu, raw->data, raw->size,
|
||||
timestamp, thread->comm);
|
||||
}
|
||||
event__stats.total += period;
|
||||
|
||||
@@ -105,6 +151,154 @@ static int __cmd_trace(void)
|
||||
0, 0, &event__cwdlen, &event__cwd);
|
||||
}
|
||||
|
||||
struct script_spec {
|
||||
struct list_head node;
|
||||
struct scripting_ops *ops;
|
||||
char spec[0];
|
||||
};
|
||||
|
||||
LIST_HEAD(script_specs);
|
||||
|
||||
static struct script_spec *script_spec__new(const char *spec,
|
||||
struct scripting_ops *ops)
|
||||
{
|
||||
struct script_spec *s = malloc(sizeof(*s) + strlen(spec) + 1);
|
||||
|
||||
if (s != NULL) {
|
||||
strcpy(s->spec, spec);
|
||||
s->ops = ops;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static void script_spec__delete(struct script_spec *s)
|
||||
{
|
||||
free(s->spec);
|
||||
free(s);
|
||||
}
|
||||
|
||||
static void script_spec__add(struct script_spec *s)
|
||||
{
|
||||
list_add_tail(&s->node, &script_specs);
|
||||
}
|
||||
|
||||
static struct script_spec *script_spec__find(const char *spec)
|
||||
{
|
||||
struct script_spec *s;
|
||||
|
||||
list_for_each_entry(s, &script_specs, node)
|
||||
if (strcasecmp(s->spec, spec) == 0)
|
||||
return s;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct script_spec *script_spec__findnew(const char *spec,
|
||||
struct scripting_ops *ops)
|
||||
{
|
||||
struct script_spec *s = script_spec__find(spec);
|
||||
|
||||
if (s)
|
||||
return s;
|
||||
|
||||
s = script_spec__new(spec, ops);
|
||||
if (!s)
|
||||
goto out_delete_spec;
|
||||
|
||||
script_spec__add(s);
|
||||
|
||||
return s;
|
||||
|
||||
out_delete_spec:
|
||||
script_spec__delete(s);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int script_spec_register(const char *spec, struct scripting_ops *ops)
|
||||
{
|
||||
struct script_spec *s;
|
||||
|
||||
s = script_spec__find(spec);
|
||||
if (s)
|
||||
return -1;
|
||||
|
||||
s = script_spec__findnew(spec, ops);
|
||||
if (!s)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct scripting_ops *script_spec__lookup(const char *spec)
|
||||
{
|
||||
struct script_spec *s = script_spec__find(spec);
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
return s->ops;
|
||||
}
|
||||
|
||||
static void list_available_languages(void)
|
||||
{
|
||||
struct script_spec *s;
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Scripting language extensions (used in "
|
||||
"perf trace -s [spec:]script.[spec]):\n\n");
|
||||
|
||||
list_for_each_entry(s, &script_specs, node)
|
||||
fprintf(stderr, " %-42s [%s]\n", s->spec, s->ops->name);
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
static int parse_scriptname(const struct option *opt __used,
|
||||
const char *str, int unset __used)
|
||||
{
|
||||
char spec[PATH_MAX];
|
||||
const char *script, *ext;
|
||||
int len;
|
||||
|
||||
if (strcmp(str, "list") == 0) {
|
||||
list_available_languages();
|
||||
return 0;
|
||||
}
|
||||
|
||||
script = strchr(str, ':');
|
||||
if (script) {
|
||||
len = script - str;
|
||||
if (len >= PATH_MAX) {
|
||||
fprintf(stderr, "invalid language specifier");
|
||||
return -1;
|
||||
}
|
||||
strncpy(spec, str, len);
|
||||
spec[len] = '\0';
|
||||
scripting_ops = script_spec__lookup(spec);
|
||||
if (!scripting_ops) {
|
||||
fprintf(stderr, "invalid language specifier");
|
||||
return -1;
|
||||
}
|
||||
script++;
|
||||
} else {
|
||||
script = str;
|
||||
ext = strchr(script, '.');
|
||||
if (!ext) {
|
||||
fprintf(stderr, "invalid script extension");
|
||||
return -1;
|
||||
}
|
||||
scripting_ops = script_spec__lookup(++ext);
|
||||
if (!scripting_ops) {
|
||||
fprintf(stderr, "invalid script extension");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
script_name = strdup(script);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char * const annotate_usage[] = {
|
||||
"perf trace [<options>] <command>",
|
||||
NULL
|
||||
@@ -117,13 +311,23 @@ static const struct option options[] = {
|
||||
"be more verbose (show symbol address, etc)"),
|
||||
OPT_BOOLEAN('l', "latency", &latency_format,
|
||||
"show latency attributes (irqs/preemption disabled, etc)"),
|
||||
OPT_CALLBACK('s', "script", NULL, "name",
|
||||
"script file name (lang:script name, script name, or *)",
|
||||
parse_scriptname),
|
||||
OPT_STRING('g', "gen-script", &generate_script_lang, "lang",
|
||||
"generate perf-trace.xx script in specified language"),
|
||||
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
int cmd_trace(int argc, const char **argv, const char *prefix __used)
|
||||
{
|
||||
int err;
|
||||
|
||||
symbol__init(0);
|
||||
|
||||
setup_scripting();
|
||||
|
||||
argc = parse_options(argc, argv, options, annotate_usage, 0);
|
||||
if (argc) {
|
||||
/*
|
||||
@@ -136,5 +340,50 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
|
||||
|
||||
setup_pager();
|
||||
|
||||
return __cmd_trace();
|
||||
if (generate_script_lang) {
|
||||
struct stat perf_stat;
|
||||
|
||||
int input = open(input_name, O_RDONLY);
|
||||
if (input < 0) {
|
||||
perror("failed to open file");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
err = fstat(input, &perf_stat);
|
||||
if (err < 0) {
|
||||
perror("failed to stat file");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (!perf_stat.st_size) {
|
||||
fprintf(stderr, "zero-sized file, nothing to do!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
scripting_ops = script_spec__lookup(generate_script_lang);
|
||||
if (!scripting_ops) {
|
||||
fprintf(stderr, "invalid language specifier");
|
||||
return -1;
|
||||
}
|
||||
|
||||
header = perf_header__new();
|
||||
if (header == NULL)
|
||||
return -1;
|
||||
|
||||
perf_header__read(header, input);
|
||||
err = scripting_ops->generate_script("perf-trace");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (script_name) {
|
||||
err = scripting_ops->start_script(script_name);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = __cmd_trace();
|
||||
|
||||
cleanup_scripting();
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* This file was generated automatically by ExtUtils::ParseXS version 2.18_02 from the
|
||||
* contents of Context.xs. Do not edit this file, edit Context.xs instead.
|
||||
*
|
||||
* ANY CHANGES MADE HERE WILL BE LOST!
|
||||
*
|
||||
*/
|
||||
|
||||
#line 1 "Context.xs"
|
||||
/*
|
||||
* Context.xs. XS interfaces for perf trace.
|
||||
*
|
||||
* Copyright (C) 2009 Tom Zanussi <tzanussi@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EXTERN.h"
|
||||
#include "perl.h"
|
||||
#include "XSUB.h"
|
||||
#include "../../../util/trace-event-perl.h"
|
||||
|
||||
#ifndef PERL_UNUSED_VAR
|
||||
# define PERL_UNUSED_VAR(var) if (0) var = var
|
||||
#endif
|
||||
|
||||
#line 41 "Context.c"
|
||||
|
||||
XS(XS_Perf__Trace__Context_common_pc); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Perf__Trace__Context_common_pc)
|
||||
{
|
||||
#ifdef dVAR
|
||||
dVAR; dXSARGS;
|
||||
#else
|
||||
dXSARGS;
|
||||
#endif
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: %s(%s)", "Perf::Trace::Context::common_pc", "context");
|
||||
PERL_UNUSED_VAR(cv); /* -W */
|
||||
{
|
||||
struct scripting_context * context = INT2PTR(struct scripting_context *,SvIV(ST(0)));
|
||||
int RETVAL;
|
||||
dXSTARG;
|
||||
|
||||
RETVAL = common_pc(context);
|
||||
XSprePUSH; PUSHi((IV)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
|
||||
XS(XS_Perf__Trace__Context_common_flags); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Perf__Trace__Context_common_flags)
|
||||
{
|
||||
#ifdef dVAR
|
||||
dVAR; dXSARGS;
|
||||
#else
|
||||
dXSARGS;
|
||||
#endif
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: %s(%s)", "Perf::Trace::Context::common_flags", "context");
|
||||
PERL_UNUSED_VAR(cv); /* -W */
|
||||
{
|
||||
struct scripting_context * context = INT2PTR(struct scripting_context *,SvIV(ST(0)));
|
||||
int RETVAL;
|
||||
dXSTARG;
|
||||
|
||||
RETVAL = common_flags(context);
|
||||
XSprePUSH; PUSHi((IV)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
|
||||
XS(XS_Perf__Trace__Context_common_lock_depth); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Perf__Trace__Context_common_lock_depth)
|
||||
{
|
||||
#ifdef dVAR
|
||||
dVAR; dXSARGS;
|
||||
#else
|
||||
dXSARGS;
|
||||
#endif
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: %s(%s)", "Perf::Trace::Context::common_lock_depth", "context");
|
||||
PERL_UNUSED_VAR(cv); /* -W */
|
||||
{
|
||||
struct scripting_context * context = INT2PTR(struct scripting_context *,SvIV(ST(0)));
|
||||
int RETVAL;
|
||||
dXSTARG;
|
||||
|
||||
RETVAL = common_lock_depth(context);
|
||||
XSprePUSH; PUSHi((IV)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
XS(boot_Perf__Trace__Context); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(boot_Perf__Trace__Context)
|
||||
{
|
||||
#ifdef dVAR
|
||||
dVAR; dXSARGS;
|
||||
#else
|
||||
dXSARGS;
|
||||
#endif
|
||||
const char* file = __FILE__;
|
||||
|
||||
PERL_UNUSED_VAR(cv); /* -W */
|
||||
PERL_UNUSED_VAR(items); /* -W */
|
||||
XS_VERSION_BOOTCHECK ;
|
||||
|
||||
newXSproto("Perf::Trace::Context::common_pc", XS_Perf__Trace__Context_common_pc, file, "$");
|
||||
newXSproto("Perf::Trace::Context::common_flags", XS_Perf__Trace__Context_common_flags, file, "$");
|
||||
newXSproto("Perf::Trace::Context::common_lock_depth", XS_Perf__Trace__Context_common_lock_depth, file, "$");
|
||||
if (PL_unitcheckav)
|
||||
call_list(PL_scopestack_ix, PL_unitcheckav);
|
||||
XSRETURN_YES;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Context.xs. XS interfaces for perf trace.
|
||||
*
|
||||
* Copyright (C) 2009 Tom Zanussi <tzanussi@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EXTERN.h"
|
||||
#include "perl.h"
|
||||
#include "XSUB.h"
|
||||
#include "../../../util/trace-event-perl.h"
|
||||
|
||||
MODULE = Perf::Trace::Context PACKAGE = Perf::Trace::Context
|
||||
PROTOTYPES: ENABLE
|
||||
|
||||
int
|
||||
common_pc(context)
|
||||
struct scripting_context * context
|
||||
|
||||
int
|
||||
common_flags(context)
|
||||
struct scripting_context * context
|
||||
|
||||
int
|
||||
common_lock_depth(context)
|
||||
struct scripting_context * context
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
use 5.010000;
|
||||
use ExtUtils::MakeMaker;
|
||||
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
|
||||
# the contents of the Makefile that is written.
|
||||
WriteMakefile(
|
||||
NAME => 'Perf::Trace::Context',
|
||||
VERSION_FROM => 'lib/Perf/Trace/Context.pm', # finds $VERSION
|
||||
PREREQ_PM => {}, # e.g., Module::Name => 1.1
|
||||
($] >= 5.005 ? ## Add these new keywords supported since 5.005
|
||||
(ABSTRACT_FROM => 'lib/Perf/Trace/Context.pm', # retrieve abstract from module
|
||||
AUTHOR => 'Tom Zanussi <tzanussi@gmail.com>') : ()),
|
||||
LIBS => [''], # e.g., '-lm'
|
||||
DEFINE => '-I ../..', # e.g., '-DHAVE_SOMETHING'
|
||||
INC => '-I.', # e.g., '-I. -I/usr/include/other'
|
||||
# Un-comment this if you add C files to link with later:
|
||||
OBJECT => 'Context.o', # link all the C files too
|
||||
);
|
||||
@@ -0,0 +1,59 @@
|
||||
Perf-Trace-Util version 0.01
|
||||
============================
|
||||
|
||||
This module contains utility functions for use with perf trace.
|
||||
|
||||
Core.pm and Util.pm are pure Perl modules; Core.pm contains routines
|
||||
that the core perf support for Perl calls on and should always be
|
||||
'used', while Util.pm contains useful but optional utility functions
|
||||
that scripts may want to use. Context.pm contains the Perl->C
|
||||
interface that allows scripts to access data in the embedding perf
|
||||
executable; scripts wishing to do that should 'use Context.pm'.
|
||||
|
||||
The Perl->C perf interface is completely driven by Context.xs. If you
|
||||
want to add new Perl functions that end up accessing C data in the
|
||||
perf executable, you add desciptions of the new functions here.
|
||||
scripting_context is a pointer to the perf data in the perf executable
|
||||
that you want to access - it's passed as the second parameter,
|
||||
$context, to all handler functions.
|
||||
|
||||
After you do that:
|
||||
|
||||
perl Makefile.PL # to create a Makefile for the next step
|
||||
make # to create Context.c
|
||||
|
||||
edit Context.c to add const to the char* file = __FILE__ line in
|
||||
XS(boot_Perf__Trace__Context) to silence a warning/error.
|
||||
|
||||
You can delete the Makefile, object files and anything else that was
|
||||
generated e.g. blib and shared library, etc, except for of course
|
||||
Context.c
|
||||
|
||||
You should then be able to run the normal perf make as usual.
|
||||
|
||||
INSTALLATION
|
||||
|
||||
Building perf with perf trace Perl scripting should install this
|
||||
module in the right place.
|
||||
|
||||
You should make sure libperl and ExtUtils/Embed.pm are installed first
|
||||
e.g. apt-get install libperl-dev or yum install perl-ExtUtils-Embed.
|
||||
|
||||
DEPENDENCIES
|
||||
|
||||
This module requires these other modules and libraries:
|
||||
|
||||
None
|
||||
|
||||
COPYRIGHT AND LICENCE
|
||||
|
||||
Copyright (C) 2009 by Tom Zanussi <tzanussi@gmail.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the same terms as Perl itself, either Perl version 5.10.0 or,
|
||||
at your option, any later version of Perl 5 you may have available.
|
||||
|
||||
Alternatively, this software may be distributed under the terms of the
|
||||
GNU General Public License ("GPL") version 2 as published by the Free
|
||||
Software Foundation.
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package Perf::Trace::Context;
|
||||
|
||||
use 5.010000;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
require Exporter;
|
||||
|
||||
our @ISA = qw(Exporter);
|
||||
|
||||
our %EXPORT_TAGS = ( 'all' => [ qw(
|
||||
) ] );
|
||||
|
||||
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
||||
|
||||
our @EXPORT = qw(
|
||||
common_pc common_flags common_lock_depth
|
||||
);
|
||||
|
||||
our $VERSION = '0.01';
|
||||
|
||||
require XSLoader;
|
||||
XSLoader::load('Perf::Trace::Context', $VERSION);
|
||||
|
||||
1;
|
||||
__END__
|
||||
=head1 NAME
|
||||
|
||||
Perf::Trace::Context - Perl extension for accessing functions in perf.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Perf::Trace::Context;
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
Perf (trace) documentation
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Tom Zanussi, E<lt>tzanussi@gmail.com<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (C) 2009 by Tom Zanussi
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the same terms as Perl itself, either Perl version 5.10.0 or,
|
||||
at your option, any later version of Perl 5 you may have available.
|
||||
|
||||
Alternatively, this software may be distributed under the terms of the
|
||||
GNU General Public License ("GPL") version 2 as published by the Free
|
||||
Software Foundation.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,192 @@
|
||||
package Perf::Trace::Core;
|
||||
|
||||
use 5.010000;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
require Exporter;
|
||||
|
||||
our @ISA = qw(Exporter);
|
||||
|
||||
our %EXPORT_TAGS = ( 'all' => [ qw(
|
||||
) ] );
|
||||
|
||||
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
||||
|
||||
our @EXPORT = qw(
|
||||
define_flag_field define_flag_value flag_str dump_flag_fields
|
||||
define_symbolic_field define_symbolic_value symbol_str dump_symbolic_fields
|
||||
trace_flag_str
|
||||
);
|
||||
|
||||
our $VERSION = '0.01';
|
||||
|
||||
my %trace_flags = (0x00 => "NONE",
|
||||
0x01 => "IRQS_OFF",
|
||||
0x02 => "IRQS_NOSUPPORT",
|
||||
0x04 => "NEED_RESCHED",
|
||||
0x08 => "HARDIRQ",
|
||||
0x10 => "SOFTIRQ");
|
||||
|
||||
sub trace_flag_str
|
||||
{
|
||||
my ($value) = @_;
|
||||
|
||||
my $string;
|
||||
|
||||
my $print_delim = 0;
|
||||
|
||||
foreach my $idx (sort {$a <=> $b} keys %trace_flags) {
|
||||
if (!$value && !$idx) {
|
||||
$string .= "NONE";
|
||||
last;
|
||||
}
|
||||
|
||||
if ($idx && ($value & $idx) == $idx) {
|
||||
if ($print_delim) {
|
||||
$string .= " | ";
|
||||
}
|
||||
$string .= "$trace_flags{$idx}";
|
||||
$print_delim = 1;
|
||||
$value &= ~$idx;
|
||||
}
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
my %flag_fields;
|
||||
my %symbolic_fields;
|
||||
|
||||
sub flag_str
|
||||
{
|
||||
my ($event_name, $field_name, $value) = @_;
|
||||
|
||||
my $string;
|
||||
|
||||
if ($flag_fields{$event_name}{$field_name}) {
|
||||
my $print_delim = 0;
|
||||
foreach my $idx (sort {$a <=> $b} keys %{$flag_fields{$event_name}{$field_name}{"values"}}) {
|
||||
if (!$value && !$idx) {
|
||||
$string .= "$flag_fields{$event_name}{$field_name}{'values'}{$idx}";
|
||||
last;
|
||||
}
|
||||
if ($idx && ($value & $idx) == $idx) {
|
||||
if ($print_delim && $flag_fields{$event_name}{$field_name}{'delim'}) {
|
||||
$string .= " $flag_fields{$event_name}{$field_name}{'delim'} ";
|
||||
}
|
||||
$string .= "$flag_fields{$event_name}{$field_name}{'values'}{$idx}";
|
||||
$print_delim = 1;
|
||||
$value &= ~$idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
sub define_flag_field
|
||||
{
|
||||
my ($event_name, $field_name, $delim) = @_;
|
||||
|
||||
$flag_fields{$event_name}{$field_name}{"delim"} = $delim;
|
||||
}
|
||||
|
||||
sub define_flag_value
|
||||
{
|
||||
my ($event_name, $field_name, $value, $field_str) = @_;
|
||||
|
||||
$flag_fields{$event_name}{$field_name}{"values"}{$value} = $field_str;
|
||||
}
|
||||
|
||||
sub dump_flag_fields
|
||||
{
|
||||
for my $event (keys %flag_fields) {
|
||||
print "event $event:\n";
|
||||
for my $field (keys %{$flag_fields{$event}}) {
|
||||
print " field: $field:\n";
|
||||
print " delim: $flag_fields{$event}{$field}{'delim'}\n";
|
||||
foreach my $idx (sort {$a <=> $b} keys %{$flag_fields{$event}{$field}{"values"}}) {
|
||||
print " value $idx: $flag_fields{$event}{$field}{'values'}{$idx}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub symbol_str
|
||||
{
|
||||
my ($event_name, $field_name, $value) = @_;
|
||||
|
||||
if ($symbolic_fields{$event_name}{$field_name}) {
|
||||
foreach my $idx (sort {$a <=> $b} keys %{$symbolic_fields{$event_name}{$field_name}{"values"}}) {
|
||||
if (!$value && !$idx) {
|
||||
return "$symbolic_fields{$event_name}{$field_name}{'values'}{$idx}";
|
||||
last;
|
||||
}
|
||||
if ($value == $idx) {
|
||||
return "$symbolic_fields{$event_name}{$field_name}{'values'}{$idx}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub define_symbolic_field
|
||||
{
|
||||
my ($event_name, $field_name) = @_;
|
||||
|
||||
# nothing to do, really
|
||||
}
|
||||
|
||||
sub define_symbolic_value
|
||||
{
|
||||
my ($event_name, $field_name, $value, $field_str) = @_;
|
||||
|
||||
$symbolic_fields{$event_name}{$field_name}{"values"}{$value} = $field_str;
|
||||
}
|
||||
|
||||
sub dump_symbolic_fields
|
||||
{
|
||||
for my $event (keys %symbolic_fields) {
|
||||
print "event $event:\n";
|
||||
for my $field (keys %{$symbolic_fields{$event}}) {
|
||||
print " field: $field:\n";
|
||||
foreach my $idx (sort {$a <=> $b} keys %{$symbolic_fields{$event}{$field}{"values"}}) {
|
||||
print " value $idx: $symbolic_fields{$event}{$field}{'values'}{$idx}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
=head1 NAME
|
||||
|
||||
Perf::Trace::Core - Perl extension for perf trace
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Perf::Trace::Core
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
Perf (trace) documentation
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Tom Zanussi, E<lt>tzanussi@gmail.com<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (C) 2009 by Tom Zanussi
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the same terms as Perl itself, either Perl version 5.10.0 or,
|
||||
at your option, any later version of Perl 5 you may have available.
|
||||
|
||||
Alternatively, this software may be distributed under the terms of the
|
||||
GNU General Public License ("GPL") version 2 as published by the Free
|
||||
Software Foundation.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,88 @@
|
||||
package Perf::Trace::Util;
|
||||
|
||||
use 5.010000;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
require Exporter;
|
||||
|
||||
our @ISA = qw(Exporter);
|
||||
|
||||
our %EXPORT_TAGS = ( 'all' => [ qw(
|
||||
) ] );
|
||||
|
||||
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
||||
|
||||
our @EXPORT = qw(
|
||||
avg nsecs nsecs_secs nsecs_nsecs nsecs_usecs print_nsecs
|
||||
);
|
||||
|
||||
our $VERSION = '0.01';
|
||||
|
||||
sub avg
|
||||
{
|
||||
my ($total, $n) = @_;
|
||||
|
||||
return $total / $n;
|
||||
}
|
||||
|
||||
my $NSECS_PER_SEC = 1000000000;
|
||||
|
||||
sub nsecs
|
||||
{
|
||||
my ($secs, $nsecs) = @_;
|
||||
|
||||
return $secs * $NSECS_PER_SEC + $nsecs;
|
||||
}
|
||||
|
||||
sub nsecs_secs {
|
||||
my ($nsecs) = @_;
|
||||
|
||||
return $nsecs / $NSECS_PER_SEC;
|
||||
}
|
||||
|
||||
sub nsecs_nsecs {
|
||||
my ($nsecs) = @_;
|
||||
|
||||
return $nsecs - nsecs_secs($nsecs);
|
||||
}
|
||||
|
||||
sub nsecs_str {
|
||||
my ($nsecs) = @_;
|
||||
|
||||
my $str = sprintf("%5u.%09u", nsecs_secs($nsecs), nsecs_nsecs($nsecs));
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
=head1 NAME
|
||||
|
||||
Perf::Trace::Util - Perl extension for perf trace
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Perf::Trace::Util;
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
Perf (trace) documentation
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Tom Zanussi, E<lt>tzanussi@gmail.com<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (C) 2009 by Tom Zanussi
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the same terms as Perl itself, either Perl version 5.10.0 or,
|
||||
at your option, any later version of Perl 5 you may have available.
|
||||
|
||||
Alternatively, this software may be distributed under the terms of the
|
||||
GNU General Public License ("GPL") version 2 as published by the Free
|
||||
Software Foundation.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1 @@
|
||||
struct scripting_context * T_PTR
|
||||
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
perf record -c 1 -f -a -M -R -e kmem:kmalloc -e irq:softirq_entry
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
perf trace -s ~/libexec/perf-core/scripts/perl/check-perf-trace.pl
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
perf record -c 1 -f -a -M -R -e syscalls:sys_enter_read -e syscalls:sys_enter_write
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-file.pl
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
perf record -c 1 -f -a -M -R -e syscalls:sys_enter_read -e syscalls:sys_exit_read -e syscalls:sys_enter_write -e syscalls:sys_exit_write
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-pid.pl
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
perf record -c 1 -f -a -M -R -e sched:sched_switch -e sched:sched_wakeup
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
perf trace -s ~/libexec/perf-core/scripts/perl/wakeup-latency.pl
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user