Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2a83dc7e authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf fixes from Ingo Molnar:
 "Tooling fixes, plus a simple hardware-enablement patch for the Intel
  RAPL PMU (energy use measurement) on Haswell CPUs, which I hope is
  still fine at this stage"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  perf tools: Instead of redirecting flex output, use -o
  perf tools: Fix double free in perf test 21 (code-reading.c)
  perf stat: Initialize statistics correctly
  perf bench: Set more defaults in the 'numa' suite
  perf bench: Fix segfault at the end of an 'all' execution
  perf bench: Update manpage to mention numa and futex
  perf probe: Use dwarf_getcfi_elf() instead of dwarf_getcfi()
  perf probe: Fix to handle errors in line_range searching
  perf probe: Fix --line option behavior
  perf tools: Pick up libdw without explicit LIBDW_DIR
  MAINTAINERS: Change e-mail to kernel.org one
  perf callchains: Disable unwind libraries when libelf isn't found
  tools lib traceevent: Do not call warning() directly
  tools lib traceevent: Print event name when show warning if possible
  perf top: Fix documentation of invalid -s option
  perf/x86: Enable DRAM RAPL support on Intel Haswell
parents 17cf7db2 ad466db5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -6782,7 +6782,7 @@ PERFORMANCE EVENTS SUBSYSTEM
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
+30 −3
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@
#define INTEL_RAPL_PKG		0x2	/* pseudo-encoding */
#define RAPL_IDX_RAM_NRG_STAT	2	/* DRAM */
#define INTEL_RAPL_RAM		0x3	/* pseudo-encoding */
#define RAPL_IDX_PP1_NRG_STAT	3	/* DRAM */
#define RAPL_IDX_PP1_NRG_STAT	3	/* gpu */
#define INTEL_RAPL_PP1		0x4	/* pseudo-encoding */

/* Clients have PP0, PKG */
@@ -72,6 +72,12 @@
			 1<<RAPL_IDX_PKG_NRG_STAT|\
			 1<<RAPL_IDX_RAM_NRG_STAT)

/* Servers have PP0, PKG, RAM, PP1 */
#define RAPL_IDX_HSW	(1<<RAPL_IDX_PP0_NRG_STAT|\
			 1<<RAPL_IDX_PKG_NRG_STAT|\
			 1<<RAPL_IDX_RAM_NRG_STAT|\
			 1<<RAPL_IDX_PP1_NRG_STAT)

/*
 * event code: LSB 8 bits, passed in attr->config
 * any other bit is reserved
@@ -425,6 +431,24 @@ static struct attribute *rapl_events_cln_attr[] = {
	NULL,
};

static struct attribute *rapl_events_hsw_attr[] = {
	EVENT_PTR(rapl_cores),
	EVENT_PTR(rapl_pkg),
	EVENT_PTR(rapl_gpu),
	EVENT_PTR(rapl_ram),

	EVENT_PTR(rapl_cores_unit),
	EVENT_PTR(rapl_pkg_unit),
	EVENT_PTR(rapl_gpu_unit),
	EVENT_PTR(rapl_ram_unit),

	EVENT_PTR(rapl_cores_scale),
	EVENT_PTR(rapl_pkg_scale),
	EVENT_PTR(rapl_gpu_scale),
	EVENT_PTR(rapl_ram_scale),
	NULL,
};

static struct attribute_group rapl_pmu_events_group = {
	.name = "events",
	.attrs = NULL, /* patched at runtime */
@@ -631,11 +655,14 @@ static int __init rapl_pmu_init(void)
	switch (boot_cpu_data.x86_model) {
	case 42: /* Sandy Bridge */
	case 58: /* Ivy Bridge */
	case 60: /* Haswell */
	case 69: /* Haswell-Celeron */
		rapl_cntr_mask = RAPL_IDX_CLN;
		rapl_pmu_events_group.attrs = rapl_events_cln_attr;
		break;
	case 60: /* Haswell */
	case 69: /* Haswell-Celeron */
		rapl_cntr_mask = RAPL_IDX_HSW;
		rapl_pmu_events_group.attrs = rapl_events_hsw_attr;
		break;
	case 45: /* Sandy Bridge-EP */
	case 62: /* IvyTown */
		rapl_cntr_mask = RAPL_IDX_SRV;
+66 −43
Original line number Diff line number Diff line
@@ -50,6 +50,18 @@ static int show_warning = 1;
			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 @@ static int event_read_fields(struct event_format *event, struct format_field **f
		}

		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 @@ static int event_read_fields(struct event_format *event, struct format_field **f
				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 @@ process_cond(struct event_format *event, struct print_arg *top, char **tok)
	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 @@ process_array(struct event_format *event, struct print_arg *top, char **tok)

	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 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
	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 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
		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 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
			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 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
		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 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
	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 @@ process_flags(struct event_format *event, struct print_arg *arg, char **tok)

	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 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok)

	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 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok)

	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 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok)

	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 @@ process_dynamic_array(struct event_format *event, struct print_arg *arg, char **
	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 @@ process_paren(struct event_format *event, struct print_arg *arg, char **tok)

		/* 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 @@ process_func_handler(struct event_format *event, struct pevent_function_handler
	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 @@ process_function(struct event_format *event, struct print_arg *arg,
		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 @@ process_arg_token(struct event_format *event, struct print_arg *arg,

	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 @@ static int event_read_print_args(struct event_format *event, struct print_arg **

		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 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
	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 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
		}
		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 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
	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 @@ process_defined_func(struct trace_seq *s, void *data, int size,
			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 @@ process_defined_func(struct trace_seq *s, void *data, int size,
			 * 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 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
	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 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
	 */
	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 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
				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 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
			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 @@ get_bprint_format(void *data, int size __maybe_unused,
	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,7 +4026,7 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size,
		arg->field.field =
			pevent_find_any_field(event, arg->field.name);
		if (!arg->field.field) {
			do_warning("%s: field %s not found",
			do_warning_event(event, "%s: field %s not found",
					 __func__, arg->field.name);
			return;
		}
@@ -4176,7 +4199,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
			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 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
			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 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event

				/* 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 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
						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 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event

				/* should never happen */
				if (len > 31) {
					do_warning("bad format!");
					do_warning_event(event, "bad format!");
					event->flags |= EVENT_FL_FAILED;
					len = 31;
				}
+22 −0
Original line number Diff line number Diff line
@@ -48,6 +48,12 @@ SUBSYSTEM
'mem'::
	Memory access performance.

'numa'::
	NUMA scheduling and MM benchmarks.

'futex'::
	Futex stressing benchmarks.

'all'::
	All benchmark subsystems.

@@ -187,6 +193,22 @@ Show only the result with page faults before memset.
--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]
+0 −1
Original line number Diff line number Diff line
@@ -87,7 +87,6 @@ Default is to monitor all CPUS.
--realtime=<priority>::
	Collect data with this RT SCHED_FIFO priority.

-s <symbol>::
--sym-annotate=<symbol>::
        Annotate this symbol.

Loading