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 improvements and fixes from Arnaldo Carvalho de Melo:

User visible changes:

  - Fix a segfault in 'perf probe' when removing uprobe events. (Masami Hiramatsu)

  - Synthesize COMM event for workloads started from the command line in 'perf
    record' so that we can have the pid->comm mapping before we get the real
    PERF_RECORD_COMM switching from perf to the workload. (Namhyung Kim)

  - Fix build tools/vm/ due to removal of tools/lib/api/fs/debugfs.h.
    (Arnaldo Carvalho de Melo)

Infrastructure changes:

  - Fix the make tarball targets by including the recently added err.h header in
    the perf MANIFEST file. (Jiri Olsa)

  - Don't assume that the event parser returns a non empty evlist. (Wang Nan)

  - Add way to disambiguate feature detection state files, needed to use
    tools/build feature detection for multiple components in a single O= output
    dir, which will be the case with tools/perf/ and tools/lib/bpf/.
    (Arnaldo Carvalho de Melo)

  - Fixup FEATURE_{TESTS,DISPLAY} inversion in tools/lib/bpf/. (Arnaldo Carvalho de Melo)

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

+ 5 - 4
tools/build/Makefile.feature

@@ -121,8 +121,9 @@ define feature_print_text_code
     MSG = $(shell printf '...%30s: %s' $(1) $(2))
     MSG = $(shell printf '...%30s: %s' $(1) $(2))
 endef
 endef
 
 
+FEATURE_DUMP_FILENAME = $(OUTPUT)FEATURE-DUMP$(FEATURE_USER)
 FEATURE_DUMP := $(foreach feat,$(FEATURE_DISPLAY),feature-$(feat)($(feature-$(feat))))
 FEATURE_DUMP := $(foreach feat,$(FEATURE_DISPLAY),feature-$(feat)($(feature-$(feat))))
-FEATURE_DUMP_FILE := $(shell touch $(OUTPUT)FEATURE-DUMP; cat $(OUTPUT)FEATURE-DUMP)
+FEATURE_DUMP_FILE := $(shell touch $(FEATURE_DUMP_FILENAME); cat $(FEATURE_DUMP_FILENAME))
 
 
 ifeq ($(dwarf-post-unwind),1)
 ifeq ($(dwarf-post-unwind),1)
   FEATURE_DUMP += dwarf-post-unwind($(dwarf-post-unwind-text))
   FEATURE_DUMP += dwarf-post-unwind($(dwarf-post-unwind-text))
@@ -131,16 +132,16 @@ endif
 # The $(feature_display) controls the default detection message
 # The $(feature_display) controls the default detection message
 # output. It's set if:
 # output. It's set if:
 # - detected features differes from stored features from
 # - detected features differes from stored features from
-#   last build (in FEATURE-DUMP file)
+#   last build (in $(FEATURE_DUMP_FILENAME) file)
 # - one of the $(FEATURE_DISPLAY) is not detected
 # - one of the $(FEATURE_DISPLAY) is not detected
 # - VF is enabled
 # - VF is enabled
 
 
 ifneq ("$(FEATURE_DUMP)","$(FEATURE_DUMP_FILE)")
 ifneq ("$(FEATURE_DUMP)","$(FEATURE_DUMP_FILE)")
-  $(shell echo "$(FEATURE_DUMP)" > $(OUTPUT)FEATURE-DUMP)
+  $(shell echo "$(FEATURE_DUMP)" > $(FEATURE_DUMP_FILENAME))
   feature_display := 1
   feature_display := 1
 endif
 endif
 
 
-feature_display_check = $(eval $(feature_check_code))
+feature_display_check = $(eval $(feature_check_display_code))
 define feature_display_check_code
 define feature_display_check_code
   ifneq ($(feature-$(1)), 1)
   ifneq ($(feature-$(1)), 1)
     feature_display := 1
     feature_display := 1

+ 3 - 2
tools/lib/bpf/Makefile

@@ -64,8 +64,9 @@ srctree := $(patsubst %/,%,$(dir $(srctree)))
 #$(info Determined 'srctree' to be $(srctree))
 #$(info Determined 'srctree' to be $(srctree))
 endif
 endif
 
 
-FEATURE_DISPLAY = libelf libelf-getphdrnum libelf-mmap bpf
-FEATURE_TESTS = libelf bpf
+FEATURE_USER = .libbpf
+FEATURE_TESTS = libelf libelf-getphdrnum libelf-mmap bpf
+FEATURE_DISPLAY = libelf bpf
 
 
 INCLUDES = -I. -I$(srctree)/tools/include -I$(srctree)/arch/$(ARCH)/include/uapi -I$(srctree)/include/uapi
 INCLUDES = -I. -I$(srctree)/tools/include -I$(srctree)/arch/$(ARCH)/include/uapi -I$(srctree)/include/uapi
 FEATURE_CHECK_CFLAGS-bpf = $(INCLUDES)
 FEATURE_CHECK_CFLAGS-bpf = $(INCLUDES)

+ 1 - 0
tools/perf/MANIFEST

@@ -50,6 +50,7 @@ tools/include/linux/poison.h
 tools/include/linux/rbtree.h
 tools/include/linux/rbtree.h
 tools/include/linux/rbtree_augmented.h
 tools/include/linux/rbtree_augmented.h
 tools/include/linux/types.h
 tools/include/linux/types.h
+tools/include/linux/err.h
 include/asm-generic/bitops/arch_hweight.h
 include/asm-generic/bitops/arch_hweight.h
 include/asm-generic/bitops/const_hweight.h
 include/asm-generic/bitops/const_hweight.h
 include/asm-generic/bitops/fls64.h
 include/asm-generic/bitops/fls64.h

+ 5 - 2
tools/perf/builtin-probe.c

@@ -380,8 +380,11 @@ static int perf_del_probe_events(struct strfilter *filter)
 		goto out;
 		goto out;
 
 
 	klist = strlist__new(NULL, NULL);
 	klist = strlist__new(NULL, NULL);
-	if (!klist)
-		return -ENOMEM;
+	ulist = strlist__new(NULL, NULL);
+	if (!klist || !ulist) {
+		ret = -ENOMEM;
+		goto out;
+	}
 
 
 	ret = probe_file__get_events(kfd, filter, klist);
 	ret = probe_file__get_events(kfd, filter, klist);
 	if (ret == 0) {
 	if (ret == 0) {

+ 14 - 1
tools/perf/builtin-record.c

@@ -636,8 +636,21 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
 	/*
 	/*
 	 * Let the child rip
 	 * Let the child rip
 	 */
 	 */
-	if (forks)
+	if (forks) {
+		union perf_event event;
+		/*
+		 * Some H/W events are generated before COMM event
+		 * which is emitted during exec(), so perf script
+		 * cannot see a correct process name for those events.
+		 * Synthesize COMM event to prevent it.
+		 */
+		perf_event__synthesize_comm(tool, &event,
+					    rec->evlist->workload.pid,
+					    process_synthesized_event,
+					    machine);
+
 		perf_evlist__start_workload(rec->evlist);
 		perf_evlist__start_workload(rec->evlist);
+	}
 
 
 	if (opts->initial_delay) {
 	if (opts->initial_delay) {
 		usleep(opts->initial_delay * 1000);
 		usleep(opts->initial_delay * 1000);

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

@@ -167,7 +167,7 @@ static int perf_event__prepare_comm(union perf_event *event, pid_t pid,
 	return 0;
 	return 0;
 }
 }
 
 
-static pid_t perf_event__synthesize_comm(struct perf_tool *tool,
+pid_t perf_event__synthesize_comm(struct perf_tool *tool,
 					 union perf_event *event, pid_t pid,
 					 union perf_event *event, pid_t pid,
 					 perf_event__handler_t process,
 					 perf_event__handler_t process,
 					 struct machine *machine)
 					 struct machine *machine)

+ 5 - 0
tools/perf/util/event.h

@@ -478,6 +478,11 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type,
 				  const struct perf_sample *sample,
 				  const struct perf_sample *sample,
 				  bool swapped);
 				  bool swapped);
 
 
+pid_t perf_event__synthesize_comm(struct perf_tool *tool,
+				  union perf_event *event, pid_t pid,
+				  perf_event__handler_t process,
+				  struct machine *machine);
+
 int perf_event__synthesize_mmap_events(struct perf_tool *tool,
 int perf_event__synthesize_mmap_events(struct perf_tool *tool,
 				       union perf_event *event,
 				       union perf_event *event,
 				       pid_t pid, pid_t tgid,
 				       pid_t pid, pid_t tgid,

+ 16 - 0
tools/perf/util/parse-events.c

@@ -827,6 +827,11 @@ void parse_events__set_leader(char *name, struct list_head *list)
 {
 {
 	struct perf_evsel *leader;
 	struct perf_evsel *leader;
 
 
+	if (list_empty(list)) {
+		WARN_ONCE(true, "WARNING: failed to set leader: empty list");
+		return;
+	}
+
 	__perf_evlist__set_leader(list);
 	__perf_evlist__set_leader(list);
 	leader = list_entry(list->next, struct perf_evsel, node);
 	leader = list_entry(list->next, struct perf_evsel, node);
 	leader->group_name = name ? strdup(name) : NULL;
 	leader->group_name = name ? strdup(name) : NULL;
@@ -1176,6 +1181,11 @@ int parse_events(struct perf_evlist *evlist, const char *str,
 	if (!ret) {
 	if (!ret) {
 		struct perf_evsel *last;
 		struct perf_evsel *last;
 
 
+		if (list_empty(&data.list)) {
+			WARN_ONCE(true, "WARNING: event parser found nothing");
+			return -1;
+		}
+
 		perf_evlist__splice_list_tail(evlist, &data.list);
 		perf_evlist__splice_list_tail(evlist, &data.list);
 		evlist->nr_groups += data.nr_groups;
 		evlist->nr_groups += data.nr_groups;
 		last = perf_evlist__last(evlist);
 		last = perf_evlist__last(evlist);
@@ -1285,6 +1295,12 @@ foreach_evsel_in_last_glob(struct perf_evlist *evlist,
 	struct perf_evsel *last = NULL;
 	struct perf_evsel *last = NULL;
 	int err;
 	int err;
 
 
+	/*
+	 * Don't return when list_empty, give func a chance to report
+	 * error when it found last == NULL.
+	 *
+	 * So no need to WARN here, let *func do this.
+	 */
 	if (evlist->nr_entries > 0)
 	if (evlist->nr_entries > 0)
 		last = perf_evlist__last(evlist);
 		last = perf_evlist__last(evlist);
 
 

+ 3 - 3
tools/vm/page-types.c

@@ -42,7 +42,7 @@
 #include <sys/mman.h>
 #include <sys/mman.h>
 #include "../../include/uapi/linux/magic.h"
 #include "../../include/uapi/linux/magic.h"
 #include "../../include/uapi/linux/kernel-page-flags.h"
 #include "../../include/uapi/linux/kernel-page-flags.h"
-#include <api/fs/debugfs.h>
+#include <api/fs/fs.h>
 
 
 #ifndef MAX_PATH
 #ifndef MAX_PATH
 # define MAX_PATH 256
 # define MAX_PATH 256
@@ -188,7 +188,7 @@ static int		kpageflags_fd;
 static int		opt_hwpoison;
 static int		opt_hwpoison;
 static int		opt_unpoison;
 static int		opt_unpoison;
 
 
-static char		*hwpoison_debug_fs;
+static const char	*hwpoison_debug_fs;
 static int		hwpoison_inject_fd;
 static int		hwpoison_inject_fd;
 static int		hwpoison_forget_fd;
 static int		hwpoison_forget_fd;
 
 
@@ -487,7 +487,7 @@ static void prepare_hwpoison_fd(void)
 {
 {
 	char buf[MAX_PATH + 1];
 	char buf[MAX_PATH + 1];
 
 
-	hwpoison_debug_fs = debugfs_mount(NULL);
+	hwpoison_debug_fs = debugfs__mount();
 	if (!hwpoison_debug_fs) {
 	if (!hwpoison_debug_fs) {
 		perror("mount debugfs");
 		perror("mount debugfs");
 		exit(EXIT_FAILURE);
 		exit(EXIT_FAILURE);