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

Commit 1341f3e4 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge tag 'perf-core-for-mingo' of...

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

 into perf/core

Pull perf updates from Arnaldo Carvalho de Melo:

User visible changes:

Improvements:

 * Support showing source code, asking for variables to be collected
   at probe time and other 'perf probe' operations that use DWARF information.

   This supports only binaries with debugging information at this time, detached
   debuginfo (aka debuginfo packages) support should come in later patches.
   (Masami Hiramatsu)

 * Add a perf.data file header window in the 'perf report' TUI, associated
   with the 'i' hotkey, providing a counterpart to the --header option in the
   stdio UI. (Namhyung Kim)

 * Guest related improvements to 'perf kvm', including allowing to
   specify a directory with guest specific /proc information. (Dongsheng Yang)

 * Print session information only if --stdio is given (Namhyung Kim)

Developer stuff:

Fixes:

 * Get rid of a duplicate va_end() in error reporting (Namhyung Kim)

 * If a hist entry doesn't have symbol information, compare it with its
   address. Affects upcoming new feature (--cumulate) (Namhyung Kim)

Improvements:

 * Make libtraceevent install target quieter (Jiri Olsa)

 * Make tests/make output more compact (Jiri Olsa)

 * Ignore generated files in feature-checks (Chunwei Chen)

New APIs:

 * Introduce pevent_filter_strerror() in libtraceevent, similar in
   purpose to libc's strerror() function. (Namhyung Kim)

Refactorings:

 * Use perf_data_file methods to write output file in 'record' and
   'inject' (Jiri Olsa)

 * Use pr_*() functions where applicable in 'report' (Namhyumg Kim)

 * Add 'machine' 'addr_location' struct to have full picture (machine,
   thread, map, symbol, addr) for a (partially) resolved address, reducing
   function signatures (Arnaldo Carvalho de Melo)

 * Reduce code duplication in the histogram entry creation/insertion. (Arnaldo Carvalho de Melo)

 * Auto allocate annotation histogram data structures, (Arnaldo Carvalho de Melo)

 * No need to test against NULL before calling free, also set
   freed memory in struct pointers to NULL, to help fixing use after
   free bugs. (Arnaldo Carvalho de Melo>

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents a21b0b35 74cf249d
Loading
Loading
Loading
Loading
+28 −57
Original line number Diff line number Diff line
@@ -67,6 +67,8 @@ PLUGIN_DIR = -DPLUGIN_DIR="$(DESTDIR)/$(plugin_dir)"
PLUGIN_DIR_SQ = '$(subst ','\'',$(PLUGIN_DIR))'
endif

include $(if $(BUILD_SRC),$(BUILD_SRC)/)../../scripts/Makefile.include

# copy a bit from Linux kbuild

ifeq ("$(origin V)", "command line")
@@ -81,18 +83,13 @@ ifeq ("$(origin O)", "command line")
endif

ifeq ($(BUILD_SRC),)
ifneq ($(BUILD_OUTPUT),)
ifneq ($(OUTPUT),)

define build_output
	$(if $(VERBOSE:1=),@)+$(MAKE) -C $(BUILD_OUTPUT) 	\
	BUILD_SRC=$(CURDIR) -f $(CURDIR)/Makefile $1
	$(if $(VERBOSE:1=),@)+$(MAKE) -C $(OUTPUT) \
	BUILD_SRC=$(CURDIR)/ -f $(CURDIR)/Makefile $1
endef

saved-output := $(BUILD_OUTPUT)
BUILD_OUTPUT := $(shell cd $(BUILD_OUTPUT) && /bin/pwd)
$(if $(BUILD_OUTPUT),, \
     $(error output directory "$(saved-output)" does not exist))

all: sub-make

$(MAKECMDGOALS): sub-make
@@ -104,7 +101,7 @@ sub-make: force
# Leave processing to above invocation of make
skip-makefile := 1

endif # BUILD_OUTPUT
endif # OUTPUT
endif # BUILD_SRC

# We process the rest of the Makefile if this is the final invocation of make
@@ -150,41 +147,14 @@ override CFLAGS += $(udis86-flags) -D_GNU_SOURCE

ifeq ($(VERBOSE),1)
  Q =
  print_compile =
  print_app_build =
  print_fpic_compile =
  print_shared_lib_compile =
  print_plugin_obj_compile =
  print_plugin_build =
  print_install =
else
  Q = @
  print_compile =		echo '  CC       '$(OBJ);
  print_app_build =		echo '  BUILD    '$(OBJ);
  print_fpic_compile =		echo '  CC FPIC  '$(OBJ);
  print_shared_lib_compile =	echo '  BUILD    SHARED LIB '$(OBJ);
  print_plugin_obj_compile =	echo '  CC FPIC  '$(OBJ);
  print_plugin_build =		echo '  BUILD    PLUGIN '$(OBJ);
  print_static_lib_build =	echo '  BUILD    STATIC LIB '$(OBJ);
  print_install =		echo '  INSTALL  '$1;
endif

do_fpic_compile =					\
	($(print_fpic_compile)				\
	$(CC) -c $(CFLAGS) $(EXT) -fPIC $< -o $@)

do_app_build =						\
	($(print_app_build)				\
	$(CC) $^ -rdynamic -o $@ $(CONFIG_LIBS) $(LIBS))

do_compile_shared_library =			\
	($(print_shared_lib_compile)		\
	$(CC) --shared $^ -o $@)

do_compile_plugin_obj =				\
	($(print_plugin_obj_compile)		\
	$(CC) -c $(CFLAGS) -fPIC -o $@ $<)

do_plugin_build =				\
	($(print_plugin_build)			\
	$(CC) $(CFLAGS) -shared -nostartfiles -o $@ $<)
@@ -194,16 +164,13 @@ do_build_static_lib = \
	$(RM) $@;  $(AR) rcs $@ $^)


define do_compile
	$(print_compile)						\
	$(CC) -c $(CFLAGS) $(EXT) $< -o $(obj)/$@;
endef
do_compile = $(QUIET_CC)$(CC) -c $(CFLAGS) $(EXT) $< -o $(obj)/$@;

$(obj)/%.o: $(src)/%.c
	$(Q)$(call do_compile)
	$(call do_compile)

%.o: $(src)/%.c
	$(Q)$(call do_compile)
	$(call do_compile)

PEVENT_LIB_OBJS  = event-parse.o
PEVENT_LIB_OBJS += event-plugin.o
@@ -237,21 +204,21 @@ all: all_cmd
all_cmd: $(CMD_TARGETS)

libtraceevent.so: $(PEVENT_LIB_OBJS)
	$(Q)$(do_compile_shared_library)
	$(QUIET_LINK)$(CC) --shared $^ -o $@

libtraceevent.a: $(PEVENT_LIB_OBJS)
	$(Q)$(do_build_static_lib)
	$(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^

plugins: $(PLUGINS)

$(PEVENT_LIB_OBJS): %.o: $(src)/%.c TRACEEVENT-CFLAGS
	$(Q)$(do_fpic_compile)
	$(QUIET_CC_FPIC)$(CC) -c $(CFLAGS) $(EXT) -fPIC $< -o $@

$(PLUGIN_OBJS): %.o : $(src)/%.c
	$(Q)$(do_compile_plugin_obj)
	$(QUIET_CC_FPIC)$(CC) -c $(CFLAGS) -fPIC -o $@ $<

$(PLUGINS): %.so: %.o
	$(Q)$(do_plugin_build)
	$(QUIET_LINK)$(CC) $(CFLAGS) -shared -nostartfiles -o $@ $<

define make_version.h
	(echo '/* This file is automatically generated. Do not modify. */';		\
@@ -333,27 +300,31 @@ TAGS: force
	--regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/'

define do_install
	$(print_install)				\
	if [ ! -d '$(DESTDIR_SQ)$2' ]; then		\
		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2';	\
	fi;						\
	$(INSTALL) $1 '$(DESTDIR_SQ)$2'
endef

install_lib: all_cmd install_plugins
	$(Q)$(call do_install,$(LIB_FILE),$(bindir_SQ))

PLUGINS_INSTALL = $(subst .so,.install,$(PLUGINS))
define do_install_plugins
	for plugin in $1; do				\
	  $(call do_install,$$plugin,$(plugin_dir_SQ));	\
	done
endef

$(PLUGINS_INSTALL): %.install : %.so force
	$(Q)$(call do_install,$<,$(plugin_dir_SQ))
install_lib: all_cmd install_plugins
	$(call QUIET_INSTALL, $(LIB_FILE)) \
		$(call do_install,$(LIB_FILE),$(bindir_SQ))

install_plugins: $(PLUGINS_INSTALL)
install_plugins: $(PLUGINS)
	$(call QUIET_INSTALL, trace_plugins) \
		$(call do_install_plugins, $(PLUGINS))

install: install_lib

clean:
	$(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d
	$(call QUIET_CLEAN, libtraceevent) \
		$(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d \
		$(RM) TRACEEVENT-CFLAGS tags TAGS

endif # skip-makefile
+1 −16
Original line number Diff line number Diff line
@@ -5230,22 +5230,7 @@ int pevent_strerror(struct pevent *pevent __maybe_unused,

	idx = errnum - __PEVENT_ERRNO__START - 1;
	msg = pevent_error_str[idx];

	switch (errnum) {
	case PEVENT_ERRNO__MEM_ALLOC_FAILED:
	case PEVENT_ERRNO__PARSE_EVENT_FAILED:
	case PEVENT_ERRNO__READ_ID_FAILED:
	case PEVENT_ERRNO__READ_FORMAT_FAILED:
	case PEVENT_ERRNO__READ_PRINT_FAILED:
	case PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED:
	case PEVENT_ERRNO__INVALID_ARG_TYPE:
	snprintf(buf, buflen, "%s", msg);
		break;

	default:
		/* cannot reach here */
		break;
	}

	return 0;
}
+6 −1
Original line number Diff line number Diff line
@@ -851,10 +851,13 @@ struct filter_type {
	struct filter_arg	*filter;
};

#define PEVENT_FILTER_ERROR_BUFSZ  1024

struct event_filter {
	struct pevent		*pevent;
	int			filters;
	struct filter_type	*event_filters;
	char			error_buffer[PEVENT_FILTER_ERROR_BUFSZ];
};

struct event_filter *pevent_filter_alloc(struct pevent *pevent);
@@ -874,10 +877,12 @@ enum filter_trivial_type {
enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter,
					       const char *filter_str);


enum pevent_errno pevent_filter_match(struct event_filter *filter,
				      struct pevent_record *record);

int pevent_filter_strerror(struct event_filter *filter, enum pevent_errno err,
			   char *buf, size_t buflen);

int pevent_event_filtered(struct event_filter *filter,
			  int event_id);

+54 −44
Original line number Diff line number Diff line
@@ -38,55 +38,31 @@ struct event_list {
	struct event_format	*event;
};

#define MAX_ERR_STR_SIZE 256

static void show_error(char **error_str, const char *fmt, ...)
static void show_error(char *error_buf, const char *fmt, ...)
{
	unsigned long long index;
	const char *input;
	char *error;
	va_list ap;
	int len;
	int i;

	if (!error_str)
		return;

	input = pevent_get_input_buf();
	index = pevent_get_input_buf_ptr();
	len = input ? strlen(input) : 0;

	error = malloc(MAX_ERR_STR_SIZE + (len*2) + 3);
	if (error == NULL) {
		/*
		 * Maybe it's due to len is too long.
		 * Retry without the input buffer part.
		 */
		len = 0;

		error = malloc(MAX_ERR_STR_SIZE);
		if (error == NULL) {
			/* no memory */
			*error_str = NULL;
			return;
		}
	}

	if (len) {
		strcpy(error, input);
		error[len] = '\n';
		strcpy(error_buf, input);
		error_buf[len] = '\n';
		for (i = 1; i < len && i < index; i++)
			error[len+i] = ' ';
		error[len + i] = '^';
		error[len + i + 1] = '\n';
			error_buf[len+i] = ' ';
		error_buf[len + i] = '^';
		error_buf[len + i + 1] = '\n';
		len += i+2;
	}

	va_start(ap, fmt);
	vsnprintf(error + len, MAX_ERR_STR_SIZE, fmt, ap);
	vsnprintf(error_buf + len, PEVENT_FILTER_ERROR_BUFSZ - len, fmt, ap);
	va_end(ap);

	*error_str = error;
}

static void free_token(char *token)
@@ -370,7 +346,7 @@ static void free_events(struct event_list *events)

static enum pevent_errno
create_arg_item(struct event_format *event, const char *token,
		enum event_type type, struct filter_arg **parg, char **error_str)
		enum event_type type, struct filter_arg **parg, char *error_str)
{
	struct format_field *field;
	struct filter_arg *arg;
@@ -474,7 +450,7 @@ create_arg_cmp(enum filter_exp_type etype)
}

static enum pevent_errno
add_right(struct filter_arg *op, struct filter_arg *arg, char **error_str)
add_right(struct filter_arg *op, struct filter_arg *arg, char *error_str)
{
	struct filter_arg *left;
	char *str;
@@ -786,7 +762,7 @@ enum filter_vals {

static enum pevent_errno
reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child,
		struct filter_arg *arg, char **error_str)
		struct filter_arg *arg, char *error_str)
{
	struct filter_arg *other_child;
	struct filter_arg **ptr;
@@ -838,7 +814,7 @@ reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child,

/* Returns either filter_vals (success) or pevent_errno (failfure) */
static int test_arg(struct filter_arg *parent, struct filter_arg *arg,
		    char **error_str)
		    char *error_str)
{
	int lval, rval;

@@ -938,7 +914,7 @@ static int test_arg(struct filter_arg *parent, struct filter_arg *arg,

/* Remove any unknown event fields */
static int collapse_tree(struct filter_arg *arg,
			 struct filter_arg **arg_collapsed, char **error_str)
			 struct filter_arg **arg_collapsed, char *error_str)
{
	int ret;

@@ -973,7 +949,7 @@ static int collapse_tree(struct filter_arg *arg,

static enum pevent_errno
process_filter(struct event_format *event, struct filter_arg **parg,
	       char **error_str, int not)
	       char *error_str, int not)
{
	enum event_type type;
	char *token = NULL;
@@ -1211,7 +1187,7 @@ process_filter(struct event_format *event, struct filter_arg **parg,

static enum pevent_errno
process_event(struct event_format *event, const char *filter_str,
	      struct filter_arg **parg, char **error_str)
	      struct filter_arg **parg, char *error_str)
{
	int ret;

@@ -1236,7 +1212,7 @@ process_event(struct event_format *event, const char *filter_str,

static enum pevent_errno
filter_event(struct event_filter *filter, struct event_format *event,
	     const char *filter_str, char **error_str)
	     const char *filter_str, char *error_str)
{
	struct filter_type *filter_type;
	struct filter_arg *arg;
@@ -1268,13 +1244,21 @@ filter_event(struct event_filter *filter, struct event_format *event,
	return 0;
}

static void filter_init_error_buf(struct event_filter *filter)
{
	/* clear buffer to reset show error */
	pevent_buffer_init("", 0);
	filter->error_buffer[0] = '\0';
}

/**
 * pevent_filter_add_filter_str - add a new filter
 * @filter: the event filter to add to
 * @filter_str: the filter string that contains the filter
 *
 * Returns 0 if the filter was successfully added or a
 * negative error code.
 * negative error code.  Use pevent_filter_strerror() to see
 * actual error message in case of error.
 */
enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter,
					       const char *filter_str)
@@ -1291,10 +1275,8 @@ enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter,
	enum pevent_errno rtn = 0; /* PEVENT_ERRNO__SUCCESS */
	int len;
	int ret;
	char *error_str = NULL;

	/* clear buffer to reset show error */
	pevent_buffer_init("", 0);
	filter_init_error_buf(filter);

	filter_start = strchr(filter_str, ':');
	if (filter_start)
@@ -1353,7 +1335,7 @@ enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter,
	/* filter starts here */
	for (event = events; event; event = event->next) {
		ret = filter_event(filter, event->event, filter_start,
				   &error_str);
				   filter->error_buffer);
		/* Failures are returned if a parse error happened */
		if (ret < 0)
			rtn = ret;
@@ -1381,6 +1363,32 @@ static void free_filter_type(struct filter_type *filter_type)
	free_arg(filter_type->filter);
}

/**
 * pevent_filter_strerror - fill error message in a buffer
 * @filter: the event filter contains error
 * @err: the error code
 * @buf: the buffer to be filled in
 * @buflen: the size of the buffer
 *
 * Returns 0 if message was filled successfully, -1 if error
 */
int pevent_filter_strerror(struct event_filter *filter, enum pevent_errno err,
			   char *buf, size_t buflen)
{
	if (err <= __PEVENT_ERRNO__START || err >= __PEVENT_ERRNO__END)
		return -1;

	if (strlen(filter->error_buffer) > 0) {
		size_t len = snprintf(buf, buflen, "%s", filter->error_buffer);

		if (len > buflen)
			return -1;
		return 0;
	}

	return pevent_strerror(filter->pevent, err, buf, buflen);
}

/**
 * pevent_filter_remove_event - remove a filter for an event
 * @filter: the event filter to remove from
@@ -2027,6 +2035,8 @@ enum pevent_errno pevent_filter_match(struct event_filter *filter,
	int ret;
	enum pevent_errno err = 0;

	filter_init_error_buf(filter);

	if (!filter->filters)
		return PEVENT_ERRNO__NO_FILTER;

+1 −0
Original line number Diff line number Diff line
@@ -489,6 +489,7 @@ ifndef NO_SLANG
  LIB_OBJS += $(OUTPUT)ui/browsers/hists.o
  LIB_OBJS += $(OUTPUT)ui/browsers/map.o
  LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o
  LIB_OBJS += $(OUTPUT)ui/browsers/header.o
  LIB_OBJS += $(OUTPUT)ui/tui/setup.o
  LIB_OBJS += $(OUTPUT)ui/tui/util.o
  LIB_OBJS += $(OUTPUT)ui/tui/helpline.o
Loading