Merge branch 'perf-core-for-mingo' into perf/urgent
Conflicts:
tools/perf/bench/numa.c
Pull perf fixes from Jiri Olsa.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
diff --git a/MAINTAINERS b/MAINTAINERS
index 6dc67b1..80399ff 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6782,7 +6782,7 @@
M: Peter Zijlstra <a.p.zijlstra@chello.nl>
M: Paul Mackerras <paulus@samba.org>
M: Ingo Molnar <mingo@redhat.com>
-M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
+M: Arnaldo Carvalho de Melo <acme@kernel.org>
L: linux-kernel@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
S: Supported
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 1587ea39..baec7d8 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -50,6 +50,18 @@
warning(fmt, ##__VA_ARGS__); \
} while (0)
+#define do_warning_event(event, fmt, ...) \
+ do { \
+ if (!show_warning) \
+ continue; \
+ \
+ if (event) \
+ warning("[%s:%s] " fmt, event->system, \
+ event->name, ##__VA_ARGS__); \
+ else \
+ warning(fmt, ##__VA_ARGS__); \
+ } while (0)
+
static void init_input_buf(const char *buf, unsigned long long size)
{
input_buf = buf;
@@ -1355,7 +1367,7 @@
}
if (!field->type) {
- do_warning("%s: no type found", __func__);
+ do_warning_event(event, "%s: no type found", __func__);
goto fail;
}
field->name = last_token;
@@ -1402,7 +1414,7 @@
free_token(token);
type = read_token(&token);
if (type == EVENT_NONE) {
- do_warning("failed to find token");
+ do_warning_event(event, "failed to find token");
goto fail;
}
}
@@ -1636,7 +1648,7 @@
right = alloc_arg();
if (!arg || !left || !right) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
/* arg will be freed at out_free */
free_arg(left);
free_arg(right);
@@ -1686,7 +1698,7 @@
arg = alloc_arg();
if (!arg) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
/* '*tok' is set to top->op.op. No need to free. */
*tok = NULL;
return EVENT_ERROR;
@@ -1792,7 +1804,7 @@
if (arg->type == PRINT_OP && !arg->op.left) {
/* handle single op */
if (token[1]) {
- do_warning("bad op token %s", token);
+ do_warning_event(event, "bad op token %s", token);
goto out_free;
}
switch (token[0]) {
@@ -1802,7 +1814,7 @@
case '-':
break;
default:
- do_warning("bad op token %s", token);
+ do_warning_event(event, "bad op token %s", token);
goto out_free;
}
@@ -1888,7 +1900,7 @@
char *new_atom;
if (left->type != PRINT_ATOM) {
- do_warning("bad pointer type");
+ do_warning_event(event, "bad pointer type");
goto out_free;
}
new_atom = realloc(left->atom.atom,
@@ -1930,7 +1942,7 @@
type = process_array(event, arg, tok);
} else {
- do_warning("unknown op '%s'", token);
+ do_warning_event(event, "unknown op '%s'", token);
event->flags |= EVENT_FL_FAILED;
/* the arg is now the left side */
goto out_free;
@@ -1951,7 +1963,7 @@
return type;
out_warn_free:
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
out_free:
free_token(token);
*tok = NULL;
@@ -2385,7 +2397,7 @@
field = alloc_arg();
if (!field) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
goto out_free;
}
@@ -2438,7 +2450,7 @@
field = alloc_arg();
if (!field) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
goto out_free;
}
@@ -2477,7 +2489,7 @@
field = alloc_arg();
if (!field) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
goto out_free;
}
@@ -2492,7 +2504,7 @@
field = alloc_arg();
if (!field) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
*tok = NULL;
return EVENT_ERROR;
}
@@ -2555,7 +2567,7 @@
free_token(token);
arg = alloc_arg();
if (!arg) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
*tok = NULL;
return EVENT_ERROR;
}
@@ -2614,13 +2626,14 @@
/* prevous must be an atom */
if (arg->type != PRINT_ATOM) {
- do_warning("previous needed to be PRINT_ATOM");
+ do_warning_event(event, "previous needed to be PRINT_ATOM");
goto out_free;
}
item_arg = alloc_arg();
if (!item_arg) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!",
+ __func__);
goto out_free;
}
@@ -2721,21 +2734,24 @@
for (i = 0; i < func->nr_args; i++) {
farg = alloc_arg();
if (!farg) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!",
+ __func__);
return EVENT_ERROR;
}
type = process_arg(event, farg, &token);
if (i < (func->nr_args - 1)) {
if (type != EVENT_DELIM || strcmp(token, ",") != 0) {
- warning("Error: function '%s()' expects %d arguments but event %s only uses %d",
+ do_warning_event(event,
+ "Error: function '%s()' expects %d arguments but event %s only uses %d",
func->name, func->nr_args,
event->name, i + 1);
goto err;
}
} else {
if (type != EVENT_DELIM || strcmp(token, ")") != 0) {
- warning("Error: function '%s()' only expects %d arguments but event %s has more",
+ do_warning_event(event,
+ "Error: function '%s()' only expects %d arguments but event %s has more",
func->name, func->nr_args, event->name);
goto err;
}
@@ -2792,7 +2808,7 @@
return process_func_handler(event, func, arg, tok);
}
- do_warning("function %s not defined", token);
+ do_warning_event(event, "function %s not defined", token);
free_token(token);
return EVENT_ERROR;
}
@@ -2878,7 +2894,7 @@
case EVENT_ERROR ... EVENT_NEWLINE:
default:
- do_warning("unexpected type %d", type);
+ do_warning_event(event, "unexpected type %d", type);
return EVENT_ERROR;
}
*tok = token;
@@ -2901,7 +2917,8 @@
arg = alloc_arg();
if (!arg) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!",
+ __func__);
return -1;
}
@@ -3481,11 +3498,12 @@
return val;
out_warning_op:
- do_warning("%s: unknown op '%s'", __func__, arg->op.op);
+ do_warning_event(event, "%s: unknown op '%s'", __func__, arg->op.op);
return 0;
out_warning_field:
- do_warning("%s: field %s not found", __func__, arg->field.name);
+ do_warning_event(event, "%s: field %s not found",
+ __func__, arg->field.name);
return 0;
}
@@ -3591,7 +3609,8 @@
}
str = malloc(len + 1);
if (!str) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!",
+ __func__);
return;
}
memcpy(str, data + field->offset, len);
@@ -3697,7 +3716,8 @@
return;
out_warning_field:
- do_warning("%s: field %s not found", __func__, arg->field.name);
+ do_warning_event(event, "%s: field %s not found",
+ __func__, arg->field.name);
}
static unsigned long long
@@ -3742,14 +3762,16 @@
trace_seq_terminate(&str);
string = malloc(sizeof(*string));
if (!string) {
- do_warning("%s(%d): malloc str", __func__, __LINE__);
+ do_warning_event(event, "%s(%d): malloc str",
+ __func__, __LINE__);
goto out_free;
}
string->next = strings;
string->str = strdup(str.buffer);
if (!string->str) {
free(string);
- do_warning("%s(%d): malloc str", __func__, __LINE__);
+ do_warning_event(event, "%s(%d): malloc str",
+ __func__, __LINE__);
goto out_free;
}
args[i] = (uintptr_t)string->str;
@@ -3761,7 +3783,7 @@
* Something went totally wrong, this is not
* an input error, something in this code broke.
*/
- do_warning("Unexpected end of arguments\n");
+ do_warning_event(event, "Unexpected end of arguments\n");
goto out_free;
}
farg = farg->next;
@@ -3811,12 +3833,12 @@
if (!field) {
field = pevent_find_field(event, "buf");
if (!field) {
- do_warning("can't find buffer field for binary printk");
+ do_warning_event(event, "can't find buffer field for binary printk");
return NULL;
}
ip_field = pevent_find_field(event, "ip");
if (!ip_field) {
- do_warning("can't find ip field for binary printk");
+ do_warning_event(event, "can't find ip field for binary printk");
return NULL;
}
pevent->bprint_buf_field = field;
@@ -3830,7 +3852,8 @@
*/
args = alloc_arg();
if (!args) {
- do_warning("%s(%d): not enough memory!", __func__, __LINE__);
+ do_warning_event(event, "%s(%d): not enough memory!",
+ __func__, __LINE__);
return NULL;
}
arg = args;
@@ -3896,7 +3919,7 @@
bptr += vsize;
arg = alloc_arg();
if (!arg) {
- do_warning("%s(%d): not enough memory!",
+ do_warning_event(event, "%s(%d): not enough memory!",
__func__, __LINE__);
goto out_free;
}
@@ -3919,7 +3942,7 @@
case 's':
arg = alloc_arg();
if (!arg) {
- do_warning("%s(%d): not enough memory!",
+ do_warning_event(event, "%s(%d): not enough memory!",
__func__, __LINE__);
goto out_free;
}
@@ -3959,7 +3982,7 @@
if (!field) {
field = pevent_find_field(event, "fmt");
if (!field) {
- do_warning("can't find format field for binary printk");
+ do_warning_event(event, "can't find format field for binary printk");
return NULL;
}
pevent->bprint_fmt_field = field;
@@ -4003,8 +4026,8 @@
arg->field.field =
pevent_find_any_field(event, arg->field.name);
if (!arg->field.field) {
- do_warning("%s: field %s not found",
- __func__, arg->field.name);
+ do_warning_event(event, "%s: field %s not found",
+ __func__, arg->field.name);
return;
}
}
@@ -4176,7 +4199,7 @@
case '*':
/* The argument is the length. */
if (!arg) {
- do_warning("no argument match");
+ do_warning_event(event, "no argument match");
event->flags |= EVENT_FL_FAILED;
goto out_failed;
}
@@ -4213,7 +4236,7 @@
case 'X':
case 'u':
if (!arg) {
- do_warning("no argument match");
+ do_warning_event(event, "no argument match");
event->flags |= EVENT_FL_FAILED;
goto out_failed;
}
@@ -4223,7 +4246,7 @@
/* should never happen */
if (len > 31) {
- do_warning("bad format!");
+ do_warning_event(event, "bad format!");
event->flags |= EVENT_FL_FAILED;
len = 31;
}
@@ -4290,13 +4313,13 @@
trace_seq_printf(s, format, (long long)val);
break;
default:
- do_warning("bad count (%d)", ls);
+ do_warning_event(event, "bad count (%d)", ls);
event->flags |= EVENT_FL_FAILED;
}
break;
case 's':
if (!arg) {
- do_warning("no matching argument");
+ do_warning_event(event, "no matching argument");
event->flags |= EVENT_FL_FAILED;
goto out_failed;
}
@@ -4306,7 +4329,7 @@
/* should never happen */
if (len > 31) {
- do_warning("bad format!");
+ do_warning_event(event, "bad format!");
event->flags |= EVENT_FL_FAILED;
len = 31;
}
diff --git a/tools/perf/Documentation/perf-bench.txt b/tools/perf/Documentation/perf-bench.txt
index 7065cd6..4464ad7 100644
--- a/tools/perf/Documentation/perf-bench.txt
+++ b/tools/perf/Documentation/perf-bench.txt
@@ -48,6 +48,12 @@
'mem'::
Memory access performance.
+'numa'::
+ NUMA scheduling and MM benchmarks.
+
+'futex'::
+ Futex stressing benchmarks.
+
'all'::
All benchmark subsystems.
@@ -187,6 +193,22 @@
--no-prefault::
Show only the result without page faults before memset.
+SUITES FOR 'numa'
+~~~~~~~~~~~~~~~~~
+*mem*::
+Suite for evaluating NUMA workloads.
+
+SUITES FOR 'futex'
+~~~~~~~~~~~~~~~~~~
+*hash*::
+Suite for evaluating hash tables.
+
+*wake*::
+Suite for evaluating wake calls.
+
+*requeue*::
+Suite for evaluating requeue calls.
+
SEE ALSO
--------
linkperf:perf[1]
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
index cdd8d49..976b00c 100644
--- a/tools/perf/Documentation/perf-top.txt
+++ b/tools/perf/Documentation/perf-top.txt
@@ -87,7 +87,6 @@
--realtime=<priority>::
Collect data with this RT SCHED_FIFO priority.
--s <symbol>::
--sym-annotate=<symbol>::
Annotate this symbol.
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c
index 97d86d8..ebfa163 100644
--- a/tools/perf/bench/numa.c
+++ b/tools/perf/bench/numa.c
@@ -1593,6 +1593,10 @@
p->data_rand_walk = true;
p->nr_loops = -1;
p->init_random = true;
+ p->mb_global_str = "1";
+ p->nr_proc = 1;
+ p->nr_threads = 1;
+ p->nr_secs = 5;
p->run_all = argc == 1;
}
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 8b0e1c9..65a151e 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -174,13 +174,20 @@
static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
{
- memset(evsel->priv, 0, sizeof(struct perf_stat));
+ int i;
+ struct perf_stat *ps = evsel->priv;
+
+ for (i = 0; i < 3; i++)
+ init_stats(&ps->res_stats[i]);
}
static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
{
evsel->priv = zalloc(sizeof(struct perf_stat));
- return evsel->priv == NULL ? -ENOMEM : 0;
+ if (evsel == NULL)
+ return -ENOMEM;
+ perf_evsel__reset_stat_priv(evsel);
+ return 0;
}
static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index c234182..ee21fa9 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -65,10 +65,9 @@
ifdef LIBDW_DIR
LIBDW_CFLAGS := -I$(LIBDW_DIR)/include
LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
-
- FEATURE_CHECK_CFLAGS-libdw-dwarf-unwind := $(LIBDW_CFLAGS)
- FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) -ldw
endif
+ FEATURE_CHECK_CFLAGS-libdw-dwarf-unwind := $(LIBDW_CFLAGS)
+ FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) -ldw
endif
# include ARCH specific config
@@ -278,6 +277,8 @@
NO_LIBELF := 1
NO_DWARF := 1
NO_DEMANGLE := 1
+ NO_LIBUNWIND := 1
+ NO_LIBDW_DWARF_UNWIND := 1
else
msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
endif
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index df02386..5627621 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -985,7 +985,7 @@
#if _ELFUTILS_PREREQ(0, 142)
/* Get the call frame information from this dwarf */
- pf->cfi = dwarf_getcfi(dbg->dbg);
+ pf->cfi = dwarf_getcfi_elf(dwarf_getelf(dbg->dbg));
#endif
off = 0;
@@ -1441,13 +1441,15 @@
void *data)
{
struct line_finder *lf = data;
+ int err;
if ((strtailcmp(fname, lf->fname) != 0) ||
(lf->lno_s > lineno || lf->lno_e < lineno))
return 0;
- if (line_range_add_line(fname, lineno, lf->lr) < 0)
- return -EINVAL;
+ err = line_range_add_line(fname, lineno, lf->lr);
+ if (err < 0 && err != -EEXIST)
+ return err;
return 0;
}
@@ -1473,14 +1475,15 @@
static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
{
- find_line_range_by_line(in_die, data);
+ int ret = find_line_range_by_line(in_die, data);
/*
* We have to check all instances of inlined function, because
* some execution paths can be optimized out depends on the
- * function argument of instances
+ * function argument of instances. However, if an error occurs,
+ * it should be handled by the caller.
*/
- return 0;
+ return ret < 0 ? ret : 0;
}
/* Search function definition from function name */