summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/Documentation/perf-record.txt1
-rw-r--r--tools/perf/Documentation/perf-report.txt4
-rw-r--r--tools/perf/Documentation/perf-script.txt3
-rw-r--r--tools/perf/builtin-report.c2
-rw-r--r--tools/perf/builtin-script.c2
-rw-r--r--tools/perf/builtin-stat.c1
-rw-r--r--tools/perf/util/Build1
-rw-r--r--tools/perf/util/callchain.c89
-rw-r--r--tools/perf/util/callchain.h1
-rw-r--r--tools/perf/util/counts.c52
-rw-r--r--tools/perf/util/counts.h37
-rw-r--r--tools/perf/util/evsel.c14
-rw-r--r--tools/perf/util/evsel.h4
-rw-r--r--tools/perf/util/hist.c9
-rw-r--r--tools/perf/util/hist.h1
-rw-r--r--tools/perf/util/parse-events.c6
-rw-r--r--tools/perf/util/parse-events.h1
-rw-r--r--tools/perf/util/parse-events.l1
-rw-r--r--tools/perf/util/pmu.c2
-rw-r--r--tools/perf/util/python-ext-sources2
-rw-r--r--tools/perf/util/sort.c52
-rw-r--r--tools/perf/util/sort.h2
-rw-r--r--tools/perf/util/srcline.c6
-rw-r--r--tools/perf/util/stat.c49
-rw-r--r--tools/perf/util/stat.h30
-rw-r--r--tools/perf/util/util.c90
-rw-r--r--tools/perf/util/util.h3
27 files changed, 292 insertions, 173 deletions
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 0d852d1bc90f..afbe45ef7e3e 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -49,6 +49,7 @@ OPTIONS
These params can be used to overload default config values per event.
Here is a list of the params.
- 'period': Set event sampling period
+ - 'freq': Set event sampling frequency
- 'time': Disable/enable time stamping. Acceptable values are 1 for
enabling time stamping. 0 for disabling time stamping.
The default is 1.
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 960da203ec11..7b07d19e2d54 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -81,6 +81,8 @@ OPTIONS
- cpu: cpu number the task ran at the time of sample
- srcline: filename and line number executed at the time of sample. The
DWARF debugging info must be provided.
+ - srcfile: file name of the source file of the same. Requires dwarf
+ information.
- weight: Event specific weight, e.g. memory latency or transaction
abort cost. This is the global weight.
- local_weight: Local weight version of the weight above.
@@ -354,6 +356,8 @@ OPTIONS
To disable decoding entirely, use --no-itrace.
+--full-source-path::
+ Show the full path for source files for srcline output.
include::callchain-overhead-calculation.txt[]
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index e2fec5fc21e7..8e9be1f9c1dd 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -260,6 +260,9 @@ OPTIONS
To disable decoding entirely, use --no-itrace.
+--full-source-path::
+ Show the full path for source files for srcline output.
+
SEE ALSO
--------
linkperf:perf-record[1], linkperf:perf-script-perl[1],
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 3a9d1b659fcd..f301e865001f 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -738,6 +738,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
"Instruction Tracing options",
itrace_parse_synth_opts),
+ OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
+ "Show full source file name path for source lines"),
OPT_END()
};
struct perf_data_file file = {
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 7912feb9a024..7b376d215e94 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -1653,6 +1653,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
"Instruction Tracing options",
itrace_parse_synth_opts),
+ OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
+ "Show full source file name path for source lines"),
OPT_END()
};
const char * const script_subcommands[] = { "record", "report", NULL };
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index a054ddc0b2a0..7aa039bd379a 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -58,6 +58,7 @@
#include "util/cpumap.h"
#include "util/thread.h"
#include "util/thread_map.h"
+#include "util/counts.h"
#include <stdlib.h>
#include <sys/prctl.h>
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 2ee81d74cf45..1ce0adc8b3cb 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -68,6 +68,7 @@ libperf-y += target.o
libperf-y += rblist.o
libperf-y += intlist.o
libperf-y += vdso.o
+libperf-y += counts.o
libperf-y += stat.o
libperf-y += stat-shadow.o
libperf-y += record.o
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 931cca8e6ae8..773fe13ce627 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -25,96 +25,9 @@
__thread struct callchain_cursor callchain_cursor;
-#ifdef HAVE_DWARF_UNWIND_SUPPORT
-static int get_stack_size(const char *str, unsigned long *_size)
-{
- char *endptr;
- unsigned long size;
- unsigned long max_size = round_down(USHRT_MAX, sizeof(u64));
-
- size = strtoul(str, &endptr, 0);
-
- do {
- if (*endptr)
- break;
-
- size = round_up(size, sizeof(u64));
- if (!size || size > max_size)
- break;
-
- *_size = size;
- return 0;
-
- } while (0);
-
- pr_err("callchain: Incorrect stack dump size (max %ld): %s\n",
- max_size, str);
- return -1;
-}
-#endif /* HAVE_DWARF_UNWIND_SUPPORT */
-
int parse_callchain_record_opt(const char *arg, struct callchain_param *param)
{
- char *tok, *name, *saveptr = NULL;
- char *buf;
- int ret = -1;
-
- /* We need buffer that we know we can write to. */
- buf = malloc(strlen(arg) + 1);
- if (!buf)
- return -ENOMEM;
-
- strcpy(buf, arg);
-
- tok = strtok_r((char *)buf, ",", &saveptr);
- name = tok ? : (char *)buf;
-
- do {
- /* Framepointer style */
- if (!strncmp(name, "fp", sizeof("fp"))) {
- if (!strtok_r(NULL, ",", &saveptr)) {
- param->record_mode = CALLCHAIN_FP;
- ret = 0;
- } else
- pr_err("callchain: No more arguments "
- "needed for --call-graph fp\n");
- break;
-
-#ifdef HAVE_DWARF_UNWIND_SUPPORT
- /* Dwarf style */
- } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
- const unsigned long default_stack_dump_size = 8192;
-
- ret = 0;
- param->record_mode = CALLCHAIN_DWARF;
- param->dump_size = default_stack_dump_size;
-
- tok = strtok_r(NULL, ",", &saveptr);
- if (tok) {
- unsigned long size = 0;
-
- ret = get_stack_size(tok, &size);
- param->dump_size = size;
- }
-#endif /* HAVE_DWARF_UNWIND_SUPPORT */
- } else if (!strncmp(name, "lbr", sizeof("lbr"))) {
- if (!strtok_r(NULL, ",", &saveptr)) {
- param->record_mode = CALLCHAIN_LBR;
- ret = 0;
- } else
- pr_err("callchain: No more arguments "
- "needed for --call-graph lbr\n");
- break;
- } else {
- pr_err("callchain: Unknown --call-graph option "
- "value: %s\n", arg);
- break;
- }
-
- } while (0);
-
- free(buf);
- return ret;
+ return parse_callchain_record(arg, param);
}
static int parse_callchain_mode(const char *value)
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 68a32c2fe87a..acee2b3cd801 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -177,6 +177,7 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *
bool hide_unresolved);
extern const char record_callchain_help[];
+extern int parse_callchain_record(const char *arg, struct callchain_param *param);
int parse_callchain_record_opt(const char *arg, struct callchain_param *param);
int parse_callchain_report_opt(const char *arg);
int perf_callchain_config(const char *var, const char *value);
diff --git a/tools/perf/util/counts.c b/tools/perf/util/counts.c
new file mode 100644
index 000000000000..e3fde313deb2
--- /dev/null
+++ b/tools/perf/util/counts.c
@@ -0,0 +1,52 @@
+#include <stdlib.h>
+#include "evsel.h"
+#include "counts.h"
+
+struct perf_counts *perf_counts__new(int ncpus, int nthreads)
+{
+ struct perf_counts *counts = zalloc(sizeof(*counts));
+
+ if (counts) {
+ struct xyarray *values;
+
+ values = xyarray__new(ncpus, nthreads, sizeof(struct perf_counts_values));
+ if (!values) {
+ free(counts);
+ return NULL;
+ }
+
+ counts->values = values;
+ }
+
+ return counts;
+}
+
+void perf_counts__delete(struct perf_counts *counts)
+{
+ if (counts) {
+ xyarray__delete(counts->values);
+ free(counts);
+ }
+}
+
+static void perf_counts__reset(struct perf_counts *counts)
+{
+ xyarray__reset(counts->values);
+}
+
+void perf_evsel__reset_counts(struct perf_evsel *evsel)
+{
+ perf_counts__reset(evsel->counts);
+}
+
+int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads)
+{
+ evsel->counts = perf_counts__new(ncpus, nthreads);
+ return evsel->counts != NULL ? 0 : -ENOMEM;
+}
+
+void perf_evsel__free_counts(struct perf_evsel *evsel)
+{
+ perf_counts__delete(evsel->counts);
+ evsel->counts = NULL;
+}
diff --git a/tools/perf/util/counts.h b/tools/perf/util/counts.h
new file mode 100644
index 000000000000..34d8baaf558a
--- /dev/null
+++ b/tools/perf/util/counts.h
@@ -0,0 +1,37 @@
+#ifndef __PERF_COUNTS_H
+#define __PERF_COUNTS_H
+
+#include "xyarray.h"
+
+struct perf_counts_values {
+ union {
+ struct {
+ u64 val;
+ u64 ena;
+ u64 run;
+ };
+ u64 values[3];
+ };
+};
+
+struct perf_counts {
+ s8 scaled;
+ struct perf_counts_values aggr;
+ struct xyarray *values;
+};
+
+
+static inline struct perf_counts_values*
+perf_counts(struct perf_counts *counts, int cpu, int thread)
+{
+ return xyarray__entry(counts->values, cpu, thread);
+}
+
+struct perf_counts *perf_counts__new(int ncpus, int nthreads);
+void perf_counts__delete(struct perf_counts *counts);
+
+void perf_evsel__reset_counts(struct perf_evsel *evsel);
+int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads);
+void perf_evsel__free_counts(struct perf_evsel *evsel);
+
+#endif /* __PERF_COUNTS_H */
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index f572f469a30d..04fddddc6b6f 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -598,6 +598,11 @@ static void apply_config_terms(struct perf_evsel *evsel)
switch (term->type) {
case PERF_EVSEL__CONFIG_TERM_PERIOD:
attr->sample_period = term->val.period;
+ attr->freq = 0;
+ break;
+ case PERF_EVSEL__CONFIG_TERM_FREQ:
+ attr->sample_freq = term->val.freq;
+ attr->freq = 1;
break;
case PERF_EVSEL__CONFIG_TERM_TIME:
if (term->val.time)
@@ -2153,8 +2158,13 @@ int perf_evsel__fprintf(struct perf_evsel *evsel,
printed += perf_event_attr__fprintf(fp, &evsel->attr,
__print_attr__fprintf, &first);
} else if (details->freq) {
- printed += comma_fprintf(fp, &first, " sample_freq=%" PRIu64,
- (u64)evsel->attr.sample_freq);
+ const char *term = "sample_freq";
+
+ if (!evsel->attr.freq)
+ term = "sample_period";
+
+ printed += comma_fprintf(fp, &first, " %s=%" PRIu64,
+ term, (u64)evsel->attr.sample_freq);
}
out:
fputc('\n', fp);
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 6a129081f3ad..fdf2674ab339 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -9,7 +9,7 @@
#include "xyarray.h"
#include "symbol.h"
#include "cpumap.h"
-#include "stat.h"
+#include "counts.h"
struct perf_evsel;
@@ -39,6 +39,7 @@ struct cgroup_sel;
*/
enum {
PERF_EVSEL__CONFIG_TERM_PERIOD,
+ PERF_EVSEL__CONFIG_TERM_FREQ,
PERF_EVSEL__CONFIG_TERM_TIME,
PERF_EVSEL__CONFIG_TERM_MAX,
};
@@ -48,6 +49,7 @@ struct perf_evsel_config_term {
int type;
union {
u64 period;
+ u64 freq;
bool time;
} val;
};
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index a6e9ddd37913..6bccfae334b1 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -151,6 +151,12 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
hists__new_col_len(hists, HISTC_LOCAL_WEIGHT, 12);
hists__new_col_len(hists, HISTC_GLOBAL_WEIGHT, 12);
+ if (h->srcline)
+ hists__new_col_len(hists, HISTC_SRCLINE, strlen(h->srcline));
+
+ if (h->srcfile)
+ hists__new_col_len(hists, HISTC_SRCFILE, strlen(h->srcfile));
+
if (h->transaction)
hists__new_col_len(hists, HISTC_TRANSACTION,
hist_entry__transaction_len());
@@ -761,6 +767,7 @@ iter_add_next_cumulative_entry(struct hist_entry_iter *iter,
struct hist_entry **he_cache = iter->priv;
struct hist_entry *he;
struct hist_entry he_tmp = {
+ .hists = evsel__hists(evsel),
.cpu = al->cpu,
.thread = al->thread,
.comm = thread__comm(al->thread),
@@ -945,6 +952,8 @@ void hist_entry__delete(struct hist_entry *he)
zfree(&he->stat_acc);
free_srcline(he->srcline);
+ if (he->srcfile && he->srcfile[0])
+ free(he->srcfile);
free_callchain(he->callchain);
free(he);
}
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index e2f712f85d2e..bc528d54e457 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -30,6 +30,7 @@ enum hist_column {
HISTC_PARENT,
HISTC_CPU,
HISTC_SRCLINE,
+ HISTC_SRCFILE,
HISTC_MISPREDICT,
HISTC_IN_TX,
HISTC_ABORT,
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 828936dc3f1e..dbf315df4220 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -597,6 +597,9 @@ do { \
case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
CHECK_TYPE_VAL(NUM);
break;
+ case PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ:
+ CHECK_TYPE_VAL(NUM);
+ break;
case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE:
/*
* TODO uncomment when the field is available
@@ -659,6 +662,9 @@ do { \
case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
ADD_CONFIG_TERM(PERIOD, period, term->val.num);
break;
+ case PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ:
+ ADD_CONFIG_TERM(FREQ, freq, term->val.num);
+ break;
case PARSE_EVENTS__TERM_TYPE_TIME:
ADD_CONFIG_TERM(TIME, time, term->val.num);
break;
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index e6f9aacc1cce..ce2d13a16226 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -62,6 +62,7 @@ enum {
PARSE_EVENTS__TERM_TYPE_CONFIG2,
PARSE_EVENTS__TERM_TYPE_NAME,
PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD,
+ PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ,
PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE,
PARSE_EVENTS__TERM_TYPE_TIME,
};
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index f5427505ae77..4306f5ad75c7 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -182,6 +182,7 @@ config1 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG1); }
config2 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG2); }
name { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NAME); }
period { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); }
+freq { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ); }
branch_type { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); }
time { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_TIME); }
, { return ','; }
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index d4b0e6454bc6..d85f11b8cacf 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -634,7 +634,7 @@ static char *formats_error_string(struct list_head *formats)
{
struct perf_pmu_format *format;
char *err, *str;
- static const char *static_terms = "config,config1,config2,name,period,branch_type,time\n";
+ static const char *static_terms = "config,config1,config2,name,period,freq,branch_type,time\n";
unsigned i = 0;
if (!asprintf(&str, "valid terms:"))
diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources
index 0766d98c5da5..51be28b1bca2 100644
--- a/tools/perf/util/python-ext-sources
+++ b/tools/perf/util/python-ext-sources
@@ -16,7 +16,7 @@ util/util.c
util/xyarray.c
util/cgroup.c
util/rblist.c
-util/stat.c
+util/counts.c
util/strlist.c
util/trace-event.c
../lib/rbtree.c
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 5177088a71d3..c0c32b050e45 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -319,6 +319,57 @@ struct sort_entry sort_srcline = {
.se_width_idx = HISTC_SRCLINE,
};
+/* --sort srcfile */
+
+static char no_srcfile[1];
+
+static char *get_srcfile(struct hist_entry *e)
+{
+ char *sf, *p;
+ struct map *map = e->ms.map;
+
+ sf = get_srcline(map->dso, map__rip_2objdump(map, e->ip),
+ e->ms.sym, true);
+ p = strchr(sf, ':');
+ if (p && *sf) {
+ *p = 0;
+ return sf;
+ }
+ free(sf);
+ return no_srcfile;
+}
+
+static int64_t
+sort__srcfile_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+ if (!left->srcfile) {
+ if (!left->ms.map)
+ left->srcfile = no_srcfile;
+ else
+ left->srcfile = get_srcfile(left);
+ }
+ if (!right->srcfile) {
+ if (!right->ms.map)
+ right->srcfile = no_srcfile;
+ else
+ right->srcfile = get_srcfile(right);
+ }
+ return strcmp(right->srcfile, left->srcfile);
+}
+
+static int hist_entry__srcfile_snprintf(struct hist_entry *he, char *bf,
+ size_t size, unsigned int width)
+{
+ return repsep_snprintf(bf, size, "%-*.*s", width, width, he->srcfile);
+}
+
+struct sort_entry sort_srcfile = {
+ .se_header = "Source File",
+ .se_cmp = sort__srcfile_cmp,
+ .se_snprintf = hist_entry__srcfile_snprintf,
+ .se_width_idx = HISTC_SRCFILE,
+};
+
/* --sort parent */
static int64_t
@@ -1196,6 +1247,7 @@ static struct sort_dimension common_sort_dimensions[] = {
DIM(SORT_PARENT, "parent", sort_parent),
DIM(SORT_CPU, "cpu", sort_cpu),
DIM(SORT_SRCLINE, "srcline", sort_srcline),
+ DIM(SORT_SRCFILE, "srcfile", sort_srcfile),
DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight),
DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
DIM(SORT_TRANSACTION, "transaction", sort_transaction),
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index bc6c87a76d16..3c2a399f8f5b 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -114,6 +114,7 @@ struct hist_entry {
};
};
char *srcline;
+ char *srcfile;
struct symbol *parent;
struct rb_root sorted_chain;
struct branch_info *branch_info;
@@ -172,6 +173,7 @@ enum sort_type {
SORT_PARENT,
SORT_CPU,
SORT_SRCLINE,
+ SORT_SRCFILE,
SORT_LOCAL_WEIGHT,
SORT_GLOBAL_WEIGHT,
SORT_TRANSACTION,
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index c93fb0c5bd0b..fc08248f08ca 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -10,6 +10,8 @@
#include "symbol.h"
+bool srcline_full_filename;
+
#ifdef HAVE_LIBBFD_SUPPORT
/*
@@ -277,7 +279,9 @@ char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
if (!addr2line(dso_name, addr, &file, &line, dso))
goto out;
- if (asprintf(&srcline, "%s:%u", basename(file), line) < 0) {
+ if (asprintf(&srcline, "%s:%u",
+ srcline_full_filename ? file : basename(file),
+ line) < 0) {
free(file);
goto out;
}
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index c5c709cdc3ce..415c359de465 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -97,55 +97,6 @@ void perf_stat_evsel_id_init(struct perf_evsel *evsel)
}
}
-struct perf_counts *perf_counts__new(int ncpus, int nthreads)
-{
- struct perf_counts *counts = zalloc(sizeof(*counts));
-
- if (counts) {
- struct xyarray *values;
-
- values = xyarray__new(ncpus, nthreads, sizeof(struct perf_counts_values));
- if (!values) {
- free(counts);
- return NULL;
- }
-
- counts->values = values;
- }
-
- return counts;
-}
-
-void perf_counts__delete(struct perf_counts *counts)
-{
- if (counts) {
- xyarray__delete(counts->values);
- free(counts);
- }
-}
-
-static void perf_counts__reset(struct perf_counts *counts)
-{
- xyarray__reset(counts->values);
-}
-
-void perf_evsel__reset_counts(struct perf_evsel *evsel)
-{
- perf_counts__reset(evsel->counts);
-}
-
-int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads)
-{
- evsel->counts = perf_counts__new(ncpus, nthreads);
- return evsel->counts != NULL ? 0 : -ENOMEM;
-}
-
-void perf_evsel__free_counts(struct perf_evsel *evsel)
-{
- perf_counts__delete(evsel->counts);
- evsel->counts = NULL;
-}
-
void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
{
int i;
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 0b897b083682..62448c8175d3 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -33,23 +33,6 @@ enum aggr_mode {
AGGR_THREAD,
};
-struct perf_counts_values {
- union {
- struct {
- u64 val;
- u64 ena;
- u64 run;
- };
- u64 values[3];
- };
-};
-
-struct perf_counts {
- s8 scaled;
- struct perf_counts_values aggr;
- struct xyarray *values;
-};
-
struct perf_stat_config {
enum aggr_mode aggr_mode;
bool scale;
@@ -57,12 +40,6 @@ struct perf_stat_config {
unsigned int interval;
};
-static inline struct perf_counts_values*
-perf_counts(struct perf_counts *counts, int cpu, int thread)
-{
- return xyarray__entry(counts->values, cpu, thread);
-}
-
void update_stats(struct stats *stats, u64 val);
double avg_stats(struct stats *stats);
double stddev_stats(struct stats *stats);
@@ -96,13 +73,6 @@ void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 *count,
void perf_stat__print_shadow_stats(FILE *out, struct perf_evsel *evsel,
double avg, int cpu, enum aggr_mode aggr);
-struct perf_counts *perf_counts__new(int ncpus, int nthreads);
-void perf_counts__delete(struct perf_counts *counts);
-
-void perf_evsel__reset_counts(struct perf_evsel *evsel);
-int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads);
-void perf_evsel__free_counts(struct perf_evsel *evsel);
-
void perf_evsel__reset_stat_priv(struct perf_evsel *evsel);
int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel);
void perf_evsel__free_stat_priv(struct perf_evsel *evsel);
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index edc2d633b332..f7adf1203df1 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -566,6 +566,96 @@ unsigned long parse_tag_value(const char *str, struct parse_tag *tags)
return (unsigned long) -1;
}
+int get_stack_size(const char *str, unsigned long *_size)
+{
+ char *endptr;
+ unsigned long size;
+ unsigned long max_size = round_down(USHRT_MAX, sizeof(u64));
+
+ size = strtoul(str, &endptr, 0);
+
+ do {
+ if (*endptr)
+ break;
+
+ size = round_up(size, sizeof(u64));
+ if (!size || size > max_size)
+ break;
+
+ *_size = size;
+ return 0;
+
+ } while (0);
+
+ pr_err("callchain: Incorrect stack dump size (max %ld): %s\n",
+ max_size, str);
+ return -1;
+}
+
+int parse_callchain_record(const char *arg, struct callchain_param *param)
+{
+ char *tok, *name, *saveptr = NULL;
+ char *buf;
+ int ret = -1;
+
+ /* We need buffer that we know we can write to. */
+ buf = malloc(strlen(arg) + 1);
+ if (!buf)
+ return -ENOMEM;
+
+ strcpy(buf, arg);
+
+ tok = strtok_r((char *)buf, ",", &saveptr);
+ name = tok ? : (char *)buf;
+
+ do {
+ /* Framepointer style */
+ if (!strncmp(name, "fp", sizeof("fp"))) {
+ if (!strtok_r(NULL, ",", &saveptr)) {
+ param->record_mode = CALLCHAIN_FP;
+ ret = 0;
+ } else
+ pr_err("callchain: No more arguments "
+ "needed for --call-graph fp\n");
+ break;
+
+#ifdef HAVE_DWARF_UNWIND_SUPPORT
+ /* Dwarf style */
+ } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
+ const unsigned long default_stack_dump_size = 8192;
+
+ ret = 0;
+ param->record_mode = CALLCHAIN_DWARF;
+ param->dump_size = default_stack_dump_size;
+
+ tok = strtok_r(NULL, ",", &saveptr);
+ if (tok) {
+ unsigned long size = 0;
+
+ ret = get_stack_size(tok, &size);
+ param->dump_size = size;
+ }
+#endif /* HAVE_DWARF_UNWIND_SUPPORT */
+ } else if (!strncmp(name, "lbr", sizeof("lbr"))) {
+ if (!strtok_r(NULL, ",", &saveptr)) {
+ param->record_mode = CALLCHAIN_LBR;
+ ret = 0;
+ } else
+ pr_err("callchain: No more arguments "
+ "needed for --call-graph lbr\n");
+ break;
+ } else {
+ pr_err("callchain: Unknown --call-graph option "
+ "value: %s\n", arg);
+ break;
+ }
+
+ } while (0);
+
+ free(buf);
+ return ret;
+}
+
int filename__read_str(const char *filename, char **buf, size_t *sizep)
{
size_t size = 0, alloc_size = 0;
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 20d625a4cacf..88a891562a47 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -318,6 +318,7 @@ static inline int path__join3(char *bf, size_t size,
struct dso;
struct symbol;
+extern bool srcline_full_filename;
char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
bool show_sym);
void free_srcline(char *srcline);
@@ -351,4 +352,6 @@ static inline char *asprintf_expr_not_in_ints(const char *var, size_t nints, int
return asprintf_expr_inout_ints(var, false, nints, ints);
}
+int get_stack_size(const char *str, unsigned long *_size);
+
#endif /* GIT_COMPAT_UTIL_H */