Browse Source

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core

Pull perf/core updates from Arnaldo Carvalho de Melo:

Changes in user visible interfaces:

  * Rename 'record's --no-delay option to --no-buffering, better reflecting its
    purpose and freeing up '--delay' to take the place of '--initial-delay', so that
    'record' and 'stat' are consistent.

Refactorings:

  * Get rid of die() and friends (good riddance!) in libtraceevent (Namhyung Kim)

Infrastructure enhancements:

  * Fix cross build problems related to pkgconfig and CROSS_COMPILE not being
    propagated to the feature tests, leading to features being tested in the
    host and then being enabled on the target. (Mark Rutland)

  * Fix pointer-integer size mismatch in some libtraceevent plugins (Mark Rutland)

  * Fix build error due to zfree() cast (Namhyung Kim)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Ingo Molnar 12 years ago
parent
commit
3e7e09dbd1

+ 1 - 1
tools/lib/traceevent/Makefile

@@ -136,7 +136,7 @@ export Q VERBOSE
 
 
 EVENT_PARSE_VERSION = $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION)
 EVENT_PARSE_VERSION = $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION)
 
 
-INCLUDES = -I. $(CONFIG_INCLUDES)
+INCLUDES = -I. -I $(srctree)/../../include $(CONFIG_INCLUDES)
 
 
 # Set compile option CFLAGS if not set elsewhere
 # Set compile option CFLAGS if not set elsewhere
 CFLAGS ?= -g -Wall
 CFLAGS ?= -g -Wall

+ 11 - 3
tools/lib/traceevent/event-parse.h

@@ -58,6 +58,12 @@ struct pevent_record {
 #endif
 #endif
 };
 };
 
 
+enum trace_seq_fail {
+	TRACE_SEQ__GOOD,
+	TRACE_SEQ__BUFFER_POISONED,
+	TRACE_SEQ__MEM_ALLOC_FAILED,
+};
+
 /*
 /*
  * Trace sequences are used to allow a function to call several other functions
  * Trace sequences are used to allow a function to call several other functions
  * to create a string of data to use (up to a max of PAGE_SIZE).
  * to create a string of data to use (up to a max of PAGE_SIZE).
@@ -68,6 +74,7 @@ struct trace_seq {
 	unsigned int		buffer_size;
 	unsigned int		buffer_size;
 	unsigned int		len;
 	unsigned int		len;
 	unsigned int		readpos;
 	unsigned int		readpos;
+	enum trace_seq_fail	state;
 };
 };
 
 
 void trace_seq_init(struct trace_seq *s);
 void trace_seq_init(struct trace_seq *s);
@@ -98,7 +105,7 @@ typedef int (*pevent_event_handler_func)(struct trace_seq *s,
 					 void *context);
 					 void *context);
 
 
 typedef int (*pevent_plugin_load_func)(struct pevent *pevent);
 typedef int (*pevent_plugin_load_func)(struct pevent *pevent);
-typedef int (*pevent_plugin_unload_func)(void);
+typedef int (*pevent_plugin_unload_func)(struct pevent *pevent);
 
 
 struct plugin_option {
 struct plugin_option {
 	struct plugin_option		*next;
 	struct plugin_option		*next;
@@ -123,7 +130,7 @@ struct plugin_option {
  * PEVENT_PLUGIN_UNLOADER:  (optional)
  * PEVENT_PLUGIN_UNLOADER:  (optional)
  *   The function called just before unloading
  *   The function called just before unloading
  *
  *
- *   int PEVENT_PLUGIN_UNLOADER(void)
+ *   int PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
  *
  *
  * PEVENT_PLUGIN_OPTIONS:  (optional)
  * PEVENT_PLUGIN_OPTIONS:  (optional)
  *   Plugin options that can be set before loading
  *   Plugin options that can be set before loading
@@ -404,7 +411,8 @@ enum pevent_errno {
 struct plugin_list;
 struct plugin_list;
 
 
 struct plugin_list *traceevent_load_plugins(struct pevent *pevent);
 struct plugin_list *traceevent_load_plugins(struct pevent *pevent);
-void traceevent_unload_plugins(struct plugin_list *plugin_list);
+void traceevent_unload_plugins(struct plugin_list *plugin_list,
+			       struct pevent *pevent);
 
 
 struct cmdline;
 struct cmdline;
 struct cmdline_list;
 struct cmdline_list;

+ 2 - 2
tools/lib/traceevent/event-plugin.c

@@ -197,7 +197,7 @@ traceevent_load_plugins(struct pevent *pevent)
 }
 }
 
 
 void
 void
-traceevent_unload_plugins(struct plugin_list *plugin_list)
+traceevent_unload_plugins(struct plugin_list *plugin_list, struct pevent *pevent)
 {
 {
 	pevent_plugin_unload_func func;
 	pevent_plugin_unload_func func;
 	struct plugin_list *list;
 	struct plugin_list *list;
@@ -207,7 +207,7 @@ traceevent_unload_plugins(struct plugin_list *plugin_list)
 		plugin_list = list->next;
 		plugin_list = list->next;
 		func = dlsym(list->handle, PEVENT_PLUGIN_UNLOADER_NAME);
 		func = dlsym(list->handle, PEVENT_PLUGIN_UNLOADER_NAME);
 		if (func)
 		if (func)
-			func();
+			func(pevent);
 		dlclose(list->handle);
 		dlclose(list->handle);
 		free(list->name);
 		free(list->name);
 		free(list);
 		free(list);

+ 0 - 4
tools/lib/traceevent/event-utils.h

@@ -23,18 +23,14 @@
 #include <ctype.h>
 #include <ctype.h>
 
 
 /* Can be overridden */
 /* Can be overridden */
-void die(const char *fmt, ...);
-void *malloc_or_die(unsigned int size);
 void warning(const char *fmt, ...);
 void warning(const char *fmt, ...);
 void pr_stat(const char *fmt, ...);
 void pr_stat(const char *fmt, ...);
 void vpr_stat(const char *fmt, va_list ap);
 void vpr_stat(const char *fmt, va_list ap);
 
 
 /* Always available */
 /* Always available */
-void __die(const char *fmt, ...);
 void __warning(const char *fmt, ...);
 void __warning(const char *fmt, ...);
 void __pr_stat(const char *fmt, ...);
 void __pr_stat(const char *fmt, ...);
 
 
-void __vdie(const char *fmt, ...);
 void __vwarning(const char *fmt, ...);
 void __vwarning(const char *fmt, ...);
 void __vpr_stat(const char *fmt, ...);
 void __vpr_stat(const char *fmt, ...);
 
 

+ 0 - 44
tools/lib/traceevent/parse-utils.c

@@ -25,40 +25,6 @@
 
 
 #define __weak __attribute__((weak))
 #define __weak __attribute__((weak))
 
 
-void __vdie(const char *fmt, va_list ap)
-{
-	int ret = errno;
-
-	if (errno)
-		perror("trace-cmd");
-	else
-		ret = -1;
-
-	fprintf(stderr, "  ");
-	vfprintf(stderr, fmt, ap);
-
-	fprintf(stderr, "\n");
-	exit(ret);
-}
-
-void __die(const char *fmt, ...)
-{
-	va_list ap;
-
-	va_start(ap, fmt);
-	__vdie(fmt, ap);
-	va_end(ap);
-}
-
-void __weak die(const char *fmt, ...)
-{
-	va_list ap;
-
-	va_start(ap, fmt);
-	__vdie(fmt, ap);
-	va_end(ap);
-}
-
 void __vwarning(const char *fmt, va_list ap)
 void __vwarning(const char *fmt, va_list ap)
 {
 {
 	if (errno)
 	if (errno)
@@ -117,13 +83,3 @@ void __weak pr_stat(const char *fmt, ...)
 	__vpr_stat(fmt, ap);
 	__vpr_stat(fmt, ap);
 	va_end(ap);
 	va_end(ap);
 }
 }
-
-void __weak *malloc_or_die(unsigned int size)
-{
-	void *data;
-
-	data = malloc(size);
-	if (!data)
-		die("malloc");
-	return data;
-}

+ 1 - 1
tools/lib/traceevent/plugin_cfg80211.c

@@ -8,7 +8,7 @@ static unsigned long long
 process___le16_to_cpup(struct trace_seq *s,
 process___le16_to_cpup(struct trace_seq *s,
 		       unsigned long long *args)
 		       unsigned long long *args)
 {
 {
-	uint16_t *val = (uint16_t *) args[0];
+	uint16_t *val = (uint16_t *) (unsigned long) args[0];
 	return val ? (long long) le16toh(*val) : 0;
 	return val ? (long long) le16toh(*val) : 0;
 }
 }
 
 

+ 1 - 1
tools/lib/traceevent/plugin_function.c

@@ -144,7 +144,7 @@ int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
 	return 0;
 	return 0;
 }
 }
 
 
-void PEVENT_PLUGIN_UNLOADER(void)
+void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
 {
 {
 	int i, x;
 	int i, x;
 
 

+ 1 - 1
tools/lib/traceevent/plugin_scsi.c

@@ -405,7 +405,7 @@ scsi_trace_parse_cdb(struct trace_seq *p, unsigned char *cdb, int len)
 unsigned long long process_scsi_trace_parse_cdb(struct trace_seq *s,
 unsigned long long process_scsi_trace_parse_cdb(struct trace_seq *s,
 						unsigned long long *args)
 						unsigned long long *args)
 {
 {
-	scsi_trace_parse_cdb(s, (unsigned char *) args[1], args[2]);
+	scsi_trace_parse_cdb(s, (unsigned char *) (unsigned long) args[1], args[2]);
 	return 0;
 	return 0;
 }
 }
 
 

+ 52 - 15
tools/lib/traceevent/trace-seq.c

@@ -22,6 +22,7 @@
 #include <string.h>
 #include <string.h>
 #include <stdarg.h>
 #include <stdarg.h>
 
 
+#include <asm/bug.h>
 #include "event-parse.h"
 #include "event-parse.h"
 #include "event-utils.h"
 #include "event-utils.h"
 
 
@@ -32,10 +33,21 @@
 #define TRACE_SEQ_POISON	((void *)0xdeadbeef)
 #define TRACE_SEQ_POISON	((void *)0xdeadbeef)
 #define TRACE_SEQ_CHECK(s)						\
 #define TRACE_SEQ_CHECK(s)						\
 do {									\
 do {									\
-	if ((s)->buffer == TRACE_SEQ_POISON)			\
-		die("Usage of trace_seq after it was destroyed");	\
+	if (WARN_ONCE((s)->buffer == TRACE_SEQ_POISON,			\
+		      "Usage of trace_seq after it was destroyed"))	\
+		(s)->state = TRACE_SEQ__BUFFER_POISONED;		\
 } while (0)
 } while (0)
 
 
+#define TRACE_SEQ_CHECK_RET_N(s, n)		\
+do {						\
+	TRACE_SEQ_CHECK(s);			\
+	if ((s)->state != TRACE_SEQ__GOOD)	\
+		return n; 			\
+} while (0)
+
+#define TRACE_SEQ_CHECK_RET(s)   TRACE_SEQ_CHECK_RET_N(s, )
+#define TRACE_SEQ_CHECK_RET0(s)  TRACE_SEQ_CHECK_RET_N(s, 0)
+
 /**
 /**
  * trace_seq_init - initialize the trace_seq structure
  * trace_seq_init - initialize the trace_seq structure
  * @s: a pointer to the trace_seq structure to initialize
  * @s: a pointer to the trace_seq structure to initialize
@@ -45,7 +57,11 @@ void trace_seq_init(struct trace_seq *s)
 	s->len = 0;
 	s->len = 0;
 	s->readpos = 0;
 	s->readpos = 0;
 	s->buffer_size = TRACE_SEQ_BUF_SIZE;
 	s->buffer_size = TRACE_SEQ_BUF_SIZE;
-	s->buffer = malloc_or_die(s->buffer_size);
+	s->buffer = malloc(s->buffer_size);
+	if (s->buffer != NULL)
+		s->state = TRACE_SEQ__GOOD;
+	else
+		s->state = TRACE_SEQ__MEM_ALLOC_FAILED;
 }
 }
 
 
 /**
 /**
@@ -71,17 +87,23 @@ void trace_seq_destroy(struct trace_seq *s)
 {
 {
 	if (!s)
 	if (!s)
 		return;
 		return;
-	TRACE_SEQ_CHECK(s);
+	TRACE_SEQ_CHECK_RET(s);
 	free(s->buffer);
 	free(s->buffer);
 	s->buffer = TRACE_SEQ_POISON;
 	s->buffer = TRACE_SEQ_POISON;
 }
 }
 
 
 static void expand_buffer(struct trace_seq *s)
 static void expand_buffer(struct trace_seq *s)
 {
 {
+	char *buf;
+
+	buf = realloc(s->buffer, s->buffer_size + TRACE_SEQ_BUF_SIZE);
+	if (WARN_ONCE(!buf, "Can't allocate trace_seq buffer memory")) {
+		s->state = TRACE_SEQ__MEM_ALLOC_FAILED;
+		return;
+	}
+
+	s->buffer = buf;
 	s->buffer_size += TRACE_SEQ_BUF_SIZE;
 	s->buffer_size += TRACE_SEQ_BUF_SIZE;
-	s->buffer = realloc(s->buffer, s->buffer_size);
-	if (!s->buffer)
-		die("Can't allocate trace_seq buffer memory");
 }
 }
 
 
 /**
 /**
@@ -105,9 +127,9 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
 	int len;
 	int len;
 	int ret;
 	int ret;
 
 
-	TRACE_SEQ_CHECK(s);
-
  try_again:
  try_again:
+	TRACE_SEQ_CHECK_RET0(s);
+
 	len = (s->buffer_size - 1) - s->len;
 	len = (s->buffer_size - 1) - s->len;
 
 
 	va_start(ap, fmt);
 	va_start(ap, fmt);
@@ -141,9 +163,9 @@ trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
 	int len;
 	int len;
 	int ret;
 	int ret;
 
 
-	TRACE_SEQ_CHECK(s);
-
  try_again:
  try_again:
+	TRACE_SEQ_CHECK_RET0(s);
+
 	len = (s->buffer_size - 1) - s->len;
 	len = (s->buffer_size - 1) - s->len;
 
 
 	ret = vsnprintf(s->buffer + s->len, len, fmt, args);
 	ret = vsnprintf(s->buffer + s->len, len, fmt, args);
@@ -172,13 +194,15 @@ int trace_seq_puts(struct trace_seq *s, const char *str)
 {
 {
 	int len;
 	int len;
 
 
-	TRACE_SEQ_CHECK(s);
+	TRACE_SEQ_CHECK_RET0(s);
 
 
 	len = strlen(str);
 	len = strlen(str);
 
 
 	while (len > ((s->buffer_size - 1) - s->len))
 	while (len > ((s->buffer_size - 1) - s->len))
 		expand_buffer(s);
 		expand_buffer(s);
 
 
+	TRACE_SEQ_CHECK_RET0(s);
+
 	memcpy(s->buffer + s->len, str, len);
 	memcpy(s->buffer + s->len, str, len);
 	s->len += len;
 	s->len += len;
 
 
@@ -187,11 +211,13 @@ int trace_seq_puts(struct trace_seq *s, const char *str)
 
 
 int trace_seq_putc(struct trace_seq *s, unsigned char c)
 int trace_seq_putc(struct trace_seq *s, unsigned char c)
 {
 {
-	TRACE_SEQ_CHECK(s);
+	TRACE_SEQ_CHECK_RET0(s);
 
 
 	while (s->len >= (s->buffer_size - 1))
 	while (s->len >= (s->buffer_size - 1))
 		expand_buffer(s);
 		expand_buffer(s);
 
 
+	TRACE_SEQ_CHECK_RET0(s);
+
 	s->buffer[s->len++] = c;
 	s->buffer[s->len++] = c;
 
 
 	return 1;
 	return 1;
@@ -199,7 +225,7 @@ int trace_seq_putc(struct trace_seq *s, unsigned char c)
 
 
 void trace_seq_terminate(struct trace_seq *s)
 void trace_seq_terminate(struct trace_seq *s)
 {
 {
-	TRACE_SEQ_CHECK(s);
+	TRACE_SEQ_CHECK_RET(s);
 
 
 	/* There's always one character left on the buffer */
 	/* There's always one character left on the buffer */
 	s->buffer[s->len] = 0;
 	s->buffer[s->len] = 0;
@@ -208,5 +234,16 @@ void trace_seq_terminate(struct trace_seq *s)
 int trace_seq_do_printf(struct trace_seq *s)
 int trace_seq_do_printf(struct trace_seq *s)
 {
 {
 	TRACE_SEQ_CHECK(s);
 	TRACE_SEQ_CHECK(s);
-	return printf("%.*s", s->len, s->buffer);
+
+	switch (s->state) {
+	case TRACE_SEQ__GOOD:
+		return printf("%.*s", s->len, s->buffer);
+	case TRACE_SEQ__BUFFER_POISONED:
+		puts("Usage of trace_seq after it was destroyed");
+		break;
+	case TRACE_SEQ__MEM_ALLOC_FAILED:
+		puts("Can't allocate trace_seq buffer memory");
+		break;
+	}
+	return -1;
 }
 }

+ 3 - 3
tools/perf/Documentation/perf-record.txt

@@ -68,8 +68,7 @@ OPTIONS
 --realtime=::
 --realtime=::
 	Collect data with this RT SCHED_FIFO priority.
 	Collect data with this RT SCHED_FIFO priority.
 
 
--D::
---no-delay::
+--no-buffering::
 	Collect data without buffering.
 	Collect data without buffering.
 
 
 -c::
 -c::
@@ -209,7 +208,8 @@ overrides that and uses per-thread mmaps.  A side-effect of that is that
 inheritance is automatically disabled.  --per-thread is ignored with a warning
 inheritance is automatically disabled.  --per-thread is ignored with a warning
 if combined with -a or -C options.
 if combined with -a or -C options.
 
 
---initial-delay msecs::
+-D::
+--delay=::
 After starting the program, wait msecs before measuring. This is useful to
 After starting the program, wait msecs before measuring. This is useful to
 filter out the startup phase of the program, which is often very different.
 filter out the startup phase of the program, which is often very different.
 
 

+ 1 - 0
tools/perf/Makefile.perf

@@ -76,6 +76,7 @@ $(OUTPUT)PERF-VERSION-FILE: ../../.git/HEAD
 
 
 CC = $(CROSS_COMPILE)gcc
 CC = $(CROSS_COMPILE)gcc
 AR = $(CROSS_COMPILE)ar
 AR = $(CROSS_COMPILE)ar
+PKG_CONFIG = $(CROSS_COMPILE)pkg-config
 
 
 RM      = rm -f
 RM      = rm -f
 LN      = ln -f
 LN      = ln -f

+ 2 - 2
tools/perf/builtin-record.c

@@ -838,7 +838,7 @@ const struct option record_options[] = {
 		    "record events on existing thread id"),
 		    "record events on existing thread id"),
 	OPT_INTEGER('r', "realtime", &record.realtime_prio,
 	OPT_INTEGER('r', "realtime", &record.realtime_prio,
 		    "collect data with this RT SCHED_FIFO priority"),
 		    "collect data with this RT SCHED_FIFO priority"),
-	OPT_BOOLEAN('D', "no-delay", &record.opts.no_delay,
+	OPT_BOOLEAN(0, "no-buffering", &record.opts.no_buffering,
 		    "collect data without buffering"),
 		    "collect data without buffering"),
 	OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples,
 	OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples,
 		    "collect raw sample records from all opened counters"),
 		    "collect raw sample records from all opened counters"),
@@ -882,7 +882,7 @@ const struct option record_options[] = {
 	OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
 	OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
 		     "monitor event in cgroup name only",
 		     "monitor event in cgroup name only",
 		     parse_cgroups),
 		     parse_cgroups),
-	OPT_UINTEGER(0, "initial-delay", &record.opts.initial_delay,
+	OPT_UINTEGER('D', "delay", &record.opts.initial_delay,
 		  "ms to wait before starting measurement after program start"),
 		  "ms to wait before starting measurement after program start"),
 	OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
 	OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
 		   "user to profile"),
 		   "user to profile"),

+ 3 - 21
tools/perf/builtin-report.c

@@ -75,24 +75,6 @@ static int report__config(const char *var, const char *value, void *cb)
 	return perf_default_config(var, value, cb);
 	return perf_default_config(var, value, cb);
 }
 }
 
 
-static int report__resolve_callchain(struct report *rep, struct symbol **parent,
-				     struct perf_evsel *evsel, struct addr_location *al,
-				     struct perf_sample *sample)
-{
-	if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) {
-		return machine__resolve_callchain(al->machine, evsel, al->thread, sample,
-						  parent, al, rep->max_stack);
-	}
-	return 0;
-}
-
-static int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample)
-{
-	if (!symbol_conf.use_callchain)
-		return 0;
-	return callchain_append(he->callchain, &callchain_cursor, sample->period);
-}
-
 static int report__add_mem_hist_entry(struct perf_tool *tool, struct addr_location *al,
 static int report__add_mem_hist_entry(struct perf_tool *tool, struct addr_location *al,
 				      struct perf_sample *sample, struct perf_evsel *evsel,
 				      struct perf_sample *sample, struct perf_evsel *evsel,
 				      union perf_event *event)
 				      union perf_event *event)
@@ -103,7 +85,7 @@ static int report__add_mem_hist_entry(struct perf_tool *tool, struct addr_locati
 	struct hist_entry *he;
 	struct hist_entry *he;
 	struct mem_info *mi, *mx;
 	struct mem_info *mi, *mx;
 	uint64_t cost;
 	uint64_t cost;
-	int err = report__resolve_callchain(rep, &parent, evsel, al, sample);
+	int err = sample__resolve_callchain(sample, &parent, evsel, al, rep->max_stack);
 
 
 	if (err)
 	if (err)
 		return err;
 		return err;
@@ -155,7 +137,7 @@ static int report__add_branch_hist_entry(struct perf_tool *tool, struct addr_loc
 	unsigned i;
 	unsigned i;
 	struct hist_entry *he;
 	struct hist_entry *he;
 	struct branch_info *bi, *bx;
 	struct branch_info *bi, *bx;
-	int err = report__resolve_callchain(rep, &parent, evsel, al, sample);
+	int err = sample__resolve_callchain(sample, &parent, evsel, al, rep->max_stack);
 
 
 	if (err)
 	if (err)
 		return err;
 		return err;
@@ -208,7 +190,7 @@ static int report__add_hist_entry(struct perf_tool *tool, struct perf_evsel *evs
 	struct report *rep = container_of(tool, struct report, tool);
 	struct report *rep = container_of(tool, struct report, tool);
 	struct symbol *parent = NULL;
 	struct symbol *parent = NULL;
 	struct hist_entry *he;
 	struct hist_entry *he;
-	int err = report__resolve_callchain(rep, &parent, evsel, al, sample);
+	int err = sample__resolve_callchain(sample, &parent, evsel, al, rep->max_stack);
 
 
 	if (err)
 	if (err)
 		return err;
 		return err;

+ 7 - 15
tools/perf/builtin-top.c

@@ -743,15 +743,10 @@ static void perf_event__process_sample(struct perf_tool *tool,
 	if (al.sym == NULL || !al.sym->ignore) {
 	if (al.sym == NULL || !al.sym->ignore) {
 		struct hist_entry *he;
 		struct hist_entry *he;
 
 
-		if ((sort__has_parent || symbol_conf.use_callchain) &&
-		    sample->callchain) {
-			err = machine__resolve_callchain(machine, evsel,
-							 al.thread, sample,
-							 &parent, &al,
-							 top->max_stack);
-			if (err)
-				return;
-		}
+		err = sample__resolve_callchain(sample, &parent, evsel, &al,
+						top->max_stack);
+		if (err)
+			return;
 
 
 		he = perf_evsel__add_hist_entry(evsel, &al, sample);
 		he = perf_evsel__add_hist_entry(evsel, &al, sample);
 		if (he == NULL) {
 		if (he == NULL) {
@@ -759,12 +754,9 @@ static void perf_event__process_sample(struct perf_tool *tool,
 			return;
 			return;
 		}
 		}
 
 
-		if (symbol_conf.use_callchain) {
-			err = callchain_append(he->callchain, &callchain_cursor,
-					       sample->period);
-			if (err)
-				return;
-		}
+		err = hist_entry__append_callchain(he, sample);
+		if (err)
+			return;
 
 
 		if (sort__has_sym)
 		if (sort__has_sym)
 			perf_top__record_precise_ip(top, he, evsel->idx, ip);
 			perf_top__record_precise_ip(top, he, evsel->idx, ip);

+ 1 - 1
tools/perf/builtin-trace.c

@@ -2258,7 +2258,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 			},
 			},
 			.user_freq     = UINT_MAX,
 			.user_freq     = UINT_MAX,
 			.user_interval = ULLONG_MAX,
 			.user_interval = ULLONG_MAX,
-			.no_delay      = true,
+			.no_buffering  = true,
 			.mmap_pages    = 1024,
 			.mmap_pages    = 1024,
 		},
 		},
 		.output = stdout,
 		.output = stdout,

+ 3 - 3
tools/perf/config/Makefile

@@ -372,7 +372,7 @@ ifndef NO_SLANG
 endif
 endif
 
 
 ifndef NO_GTK2
 ifndef NO_GTK2
-  FLAGS_GTK2=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
+  FLAGS_GTK2=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null)
   ifneq ($(feature-gtk2), 1)
   ifneq ($(feature-gtk2), 1)
     msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev);
     msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev);
     NO_GTK2 := 1
     NO_GTK2 := 1
@@ -381,8 +381,8 @@ ifndef NO_GTK2
       GTK_CFLAGS := -DHAVE_GTK_INFO_BAR_SUPPORT
       GTK_CFLAGS := -DHAVE_GTK_INFO_BAR_SUPPORT
     endif
     endif
     CFLAGS += -DHAVE_GTK2_SUPPORT
     CFLAGS += -DHAVE_GTK2_SUPPORT
-    GTK_CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
-    GTK_LIBS := $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
+    GTK_CFLAGS += $(shell $(PKG_CONFIG) --cflags gtk+-2.0 2>/dev/null)
+    GTK_LIBS := $(shell $(PKG_CONFIG) --libs gtk+-2.0 2>/dev/null)
     EXTLIBS += -ldl
     EXTLIBS += -ldl
   endif
   endif
 endif
 endif

+ 5 - 4
tools/perf/config/feature-checks/Makefile

@@ -28,7 +28,8 @@ FILES=					\
 	test-stackprotector-all.bin	\
 	test-stackprotector-all.bin	\
 	test-timerfd.bin
 	test-timerfd.bin
 
 
-CC := $(CC) -MD
+CC := $(CROSS_COMPILE)gcc -MD
+PKG_CONFIG := $(CROSS_COMPILE)pkg-config
 
 
 all: $(FILES)
 all: $(FILES)
 
 
@@ -37,7 +38,7 @@ BUILD = $(CC) $(CFLAGS) -o $(OUTPUT)$@ $(patsubst %.bin,%.c,$@) $(LDFLAGS)
 ###############################
 ###############################
 
 
 test-all.bin:
 test-all.bin:
-	$(BUILD) -Werror -fstack-protector-all -O2 -Werror -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -laudit -I/usr/include/slang -lslang $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl
+	$(BUILD) -Werror -fstack-protector-all -O2 -Werror -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -laudit -I/usr/include/slang -lslang $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl
 
 
 test-hello.bin:
 test-hello.bin:
 	$(BUILD)
 	$(BUILD)
@@ -82,10 +83,10 @@ test-libslang.bin:
 	$(BUILD) -I/usr/include/slang -lslang
 	$(BUILD) -I/usr/include/slang -lslang
 
 
 test-gtk2.bin:
 test-gtk2.bin:
-	$(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
+	$(BUILD) $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null)
 
 
 test-gtk2-infobar.bin:
 test-gtk2-infobar.bin:
-	$(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
+	$(BUILD) $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null)
 
 
 grep-libs  = $(filter -l%,$(1))
 grep-libs  = $(filter -l%,$(1))
 strip-libs = $(filter-out -l%,$(1))
 strip-libs = $(filter-out -l%,$(1))

+ 1 - 1
tools/perf/perf.h

@@ -252,7 +252,7 @@ struct record_opts {
 	int	     call_graph;
 	int	     call_graph;
 	bool	     group;
 	bool	     group;
 	bool	     inherit_stat;
 	bool	     inherit_stat;
-	bool	     no_delay;
+	bool	     no_buffering;
 	bool	     no_inherit;
 	bool	     no_inherit;
 	bool	     no_inherit_set;
 	bool	     no_inherit_set;
 	bool	     no_samples;
 	bool	     no_samples;

+ 4 - 4
tools/perf/tests/open-syscall-tp-fields.c

@@ -11,10 +11,10 @@ int test__syscall_open_tp_fields(void)
 			.uid = UINT_MAX,
 			.uid = UINT_MAX,
 			.uses_mmap = true,
 			.uses_mmap = true,
 		},
 		},
-		.no_delay   = true,
-		.freq	    = 1,
-		.mmap_pages = 256,
-		.raw_samples = true,
+		.no_buffering = true,
+		.freq	      = 1,
+		.mmap_pages   = 256,
+		.raw_samples  = true,
 	};
 	};
 	const char *filename = "/etc/passwd";
 	const char *filename = "/etc/passwd";
 	int flags = O_RDONLY | O_DIRECTORY;
 	int flags = O_RDONLY | O_DIRECTORY;

+ 3 - 3
tools/perf/tests/perf-record.c

@@ -39,9 +39,9 @@ int test__PERF_RECORD(void)
 			.uid = UINT_MAX,
 			.uid = UINT_MAX,
 			.uses_mmap = true,
 			.uses_mmap = true,
 		},
 		},
-		.no_delay   = true,
-		.freq	    = 10,
-		.mmap_pages = 256,
+		.no_buffering = true,
+		.freq	      = 10,
+		.mmap_pages   = 256,
 	};
 	};
 	cpu_set_t cpu_mask;
 	cpu_set_t cpu_mask;
 	size_t cpu_mask_size = sizeof(cpu_mask);
 	size_t cpu_mask_size = sizeof(cpu_mask);

+ 23 - 0
tools/perf/util/callchain.c

@@ -17,6 +17,8 @@
 
 
 #include "hist.h"
 #include "hist.h"
 #include "util.h"
 #include "util.h"
+#include "sort.h"
+#include "machine.h"
 #include "callchain.h"
 #include "callchain.h"
 
 
 __thread struct callchain_cursor callchain_cursor;
 __thread struct callchain_cursor callchain_cursor;
@@ -531,3 +533,24 @@ int callchain_cursor_append(struct callchain_cursor *cursor,
 
 
 	return 0;
 	return 0;
 }
 }
+
+int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent,
+			      struct perf_evsel *evsel, struct addr_location *al,
+			      int max_stack)
+{
+	if (sample->callchain == NULL)
+		return 0;
+
+	if (symbol_conf.use_callchain || sort__has_parent) {
+		return machine__resolve_callchain(al->machine, evsel, al->thread,
+						  sample, parent, al, max_stack);
+	}
+	return 0;
+}
+
+int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample)
+{
+	if (!symbol_conf.use_callchain)
+		return 0;
+	return callchain_append(he->callchain, &callchain_cursor, sample->period);
+}

+ 6 - 0
tools/perf/util/callchain.h

@@ -145,10 +145,16 @@ static inline void callchain_cursor_advance(struct callchain_cursor *cursor)
 }
 }
 
 
 struct option;
 struct option;
+struct hist_entry;
 
 
 int record_parse_callchain(const char *arg, struct record_opts *opts);
 int record_parse_callchain(const char *arg, struct record_opts *opts);
 int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset);
 int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset);
 int record_callchain_opt(const struct option *opt, const char *arg, int unset);
 int record_callchain_opt(const struct option *opt, const char *arg, int unset);
 
 
+int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent,
+			      struct perf_evsel *evsel, struct addr_location *al,
+			      int max_stack);
+int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample);
+
 extern const char record_callchain_help[];
 extern const char record_callchain_help[];
 #endif	/* __PERF_CALLCHAIN_H */
 #endif	/* __PERF_CALLCHAIN_H */

+ 1 - 1
tools/perf/util/evsel.c

@@ -627,7 +627,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
 	if (opts->sample_address)
 	if (opts->sample_address)
 		perf_evsel__set_sample_bit(evsel, DATA_SRC);
 		perf_evsel__set_sample_bit(evsel, DATA_SRC);
 
 
-	if (opts->no_delay) {
+	if (opts->no_buffering) {
 		attr->watermark = 0;
 		attr->watermark = 0;
 		attr->wakeup_events = 1;
 		attr->wakeup_events = 1;
 	}
 	}

+ 11 - 11
tools/perf/util/hist.c

@@ -181,21 +181,21 @@ void hists__output_recalc_col_len(struct hists *hists, int max_rows)
 	}
 	}
 }
 }
 
 
-static void hist_entry__add_cpumode_period(struct hist_entry *he,
-					   unsigned int cpumode, u64 period)
+static void he_stat__add_cpumode_period(struct he_stat *he_stat,
+					unsigned int cpumode, u64 period)
 {
 {
 	switch (cpumode) {
 	switch (cpumode) {
 	case PERF_RECORD_MISC_KERNEL:
 	case PERF_RECORD_MISC_KERNEL:
-		he->stat.period_sys += period;
+		he_stat->period_sys += period;
 		break;
 		break;
 	case PERF_RECORD_MISC_USER:
 	case PERF_RECORD_MISC_USER:
-		he->stat.period_us += period;
+		he_stat->period_us += period;
 		break;
 		break;
 	case PERF_RECORD_MISC_GUEST_KERNEL:
 	case PERF_RECORD_MISC_GUEST_KERNEL:
-		he->stat.period_guest_sys += period;
+		he_stat->period_guest_sys += period;
 		break;
 		break;
 	case PERF_RECORD_MISC_GUEST_USER:
 	case PERF_RECORD_MISC_GUEST_USER:
-		he->stat.period_guest_us += period;
+		he_stat->period_guest_us += period;
 		break;
 		break;
 	default:
 	default:
 		break;
 		break;
@@ -222,10 +222,10 @@ static void he_stat__add_stat(struct he_stat *dest, struct he_stat *src)
 	dest->weight		+= src->weight;
 	dest->weight		+= src->weight;
 }
 }
 
 
-static void hist_entry__decay(struct hist_entry *he)
+static void he_stat__decay(struct he_stat *he_stat)
 {
 {
-	he->stat.period = (he->stat.period * 7) / 8;
-	he->stat.nr_events = (he->stat.nr_events * 7) / 8;
+	he_stat->period = (he_stat->period * 7) / 8;
+	he_stat->nr_events = (he_stat->nr_events * 7) / 8;
 	/* XXX need decay for weight too? */
 	/* XXX need decay for weight too? */
 }
 }
 
 
@@ -236,7 +236,7 @@ static bool hists__decay_entry(struct hists *hists, struct hist_entry *he)
 	if (prev_period == 0)
 	if (prev_period == 0)
 		return true;
 		return true;
 
 
-	hist_entry__decay(he);
+	he_stat__decay(&he->stat);
 
 
 	if (!he->filtered)
 	if (!he->filtered)
 		hists->stats.total_period -= prev_period - he->stat.period;
 		hists->stats.total_period -= prev_period - he->stat.period;
@@ -402,7 +402,7 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
 	rb_link_node(&he->rb_node_in, parent, p);
 	rb_link_node(&he->rb_node_in, parent, p);
 	rb_insert_color(&he->rb_node_in, hists->entries_in);
 	rb_insert_color(&he->rb_node_in, hists->entries_in);
 out:
 out:
-	hist_entry__add_cpumode_period(he, al->cpumode, period);
+	he_stat__add_cpumode_period(&he->stat, al->cpumode, period);
 	return he;
 	return he;
 }
 }
 
 

+ 0 - 2
tools/perf/util/machine.c

@@ -1314,8 +1314,6 @@ static int machine__resolve_callchain_sample(struct machine *machine,
 				*root_al = al;
 				*root_al = al;
 				callchain_cursor_reset(&callchain_cursor);
 				callchain_cursor_reset(&callchain_cursor);
 			}
 			}
-			if (!symbol_conf.use_callchain)
-				break;
 		}
 		}
 
 
 		err = callchain_cursor_append(&callchain_cursor,
 		err = callchain_cursor_append(&callchain_cursor,

+ 2 - 2
tools/perf/util/srcline.c

@@ -129,7 +129,7 @@ static struct a2l_data *addr2line_init(const char *path)
 
 
 out:
 out:
 	if (a2l) {
 	if (a2l) {
-		zfree((void **)&a2l->input);
+		zfree((char **)&a2l->input);
 		free(a2l);
 		free(a2l);
 	}
 	}
 	bfd_close(abfd);
 	bfd_close(abfd);
@@ -140,7 +140,7 @@ static void addr2line_cleanup(struct a2l_data *a2l)
 {
 {
 	if (a2l->abfd)
 	if (a2l->abfd)
 		bfd_close(a2l->abfd);
 		bfd_close(a2l->abfd);
-	zfree((void **)&a2l->input);
+	zfree((char **)&a2l->input);
 	zfree(&a2l->syms);
 	zfree(&a2l->syms);
 	free(a2l);
 	free(a2l);
 }
 }

+ 1 - 1
tools/perf/util/strlist.c

@@ -39,7 +39,7 @@ struct rb_node *strlist__node_new(struct rblist *rblist, const void *entry)
 static void str_node__delete(struct str_node *snode, bool dupstr)
 static void str_node__delete(struct str_node *snode, bool dupstr)
 {
 {
 	if (dupstr)
 	if (dupstr)
-		zfree((void **)&snode->s);
+		zfree((char **)&snode->s);
 	free(snode);
 	free(snode);
 }
 }
 
 

+ 1 - 1
tools/perf/util/trace-event.c

@@ -34,8 +34,8 @@ int trace_event__init(struct trace_event *t)
 
 
 void trace_event__cleanup(struct trace_event *t)
 void trace_event__cleanup(struct trace_event *t)
 {
 {
+	traceevent_unload_plugins(t->plugin_list, t->pevent);
 	pevent_free(t->pevent);
 	pevent_free(t->pevent);
-	traceevent_unload_plugins(t->plugin_list);
 }
 }
 
 
 static struct event_format*
 static struct event_format*