public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/7] perf core: Make some improvements and fixes
@ 2015-02-27 10:21 Yunlong Song
  2015-02-27 10:21 ` [PATCH v3 1/7] perf list: Sort the output of 'perf list' to view more clearly Yunlong Song
                   ` (7 more replies)
  0 siblings, 8 replies; 19+ messages in thread
From: Yunlong Song @ 2015-02-27 10:21 UTC (permalink / raw)
  To: a.p.zijlstra, paulus, mingo, acme; +Cc: linux-kernel, wangnan0

Hi,
  Found some functions to improve and bugs to fix in perf.
  
  This patchset is based on:
  https://git.kernel.org/cgit/linux/kernel/git/acme/linux.git/  perf/core

  For [PATCH v3 4/7] and [PATCH v3 5/7], I have checked that these
  patches do not break shell autocompletion. Besides, for [PATCH v3 4/7],
  --raw-dump without an argument still shows all the events.

Yunlong Song (7):
  perf list: Sort the output of 'perf list' to view more clearly
  perf list: Fix some inaccuracy problem when parsing the argument
  perf list: Clean up the printing functions of hardware/software events
  perf list: Extend raw-dump to certain kind of events
  perf list: Avoid confusion of perf output and the next command prompt
  perf record: Remove the '--(null)' long_name for --list-opts
  perf core: Fix the bash completion problem of 'perf --*'

 tools/perf/Documentation/perf-list.txt |   6 +
 tools/perf/builtin-list.c              |  27 ++---
 tools/perf/perf-completion.sh          |   6 +-
 tools/perf/perf.c                      |  28 +++++
 tools/perf/util/parse-events.c         | 206 ++++++++++++++++++++++++---------
 tools/perf/util/parse-events.h         |  11 +-
 tools/perf/util/parse-options.c        |   5 +-
 7 files changed, 210 insertions(+), 79 deletions(-)

-- 
1.8.5.5


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v3 1/7] perf list: Sort the output of 'perf list' to view more clearly
  2015-02-27 10:21 [PATCH v3 0/7] perf core: Make some improvements and fixes Yunlong Song
@ 2015-02-27 10:21 ` Yunlong Song
  2015-02-27 13:57   ` Arnaldo Carvalho de Melo
  2015-02-28  9:32   ` [tip:perf/core] " tip-bot for Yunlong Song
  2015-02-27 10:21 ` [PATCH v3 2/7] perf list: Fix some inaccuracy problem when parsing the argument Yunlong Song
                   ` (6 subsequent siblings)
  7 siblings, 2 replies; 19+ messages in thread
From: Yunlong Song @ 2015-02-27 10:21 UTC (permalink / raw)
  To: a.p.zijlstra, paulus, mingo, acme; +Cc: linux-kernel, wangnan0

Sort the output according to ASCII character list (using strcmp), which
supports both number sequence and alphabet sequence.

Example:

Before this patch:

 $ perf list

 List of pre-defined events (to be used in -e):
   cpu-cycles OR cycles                               [Hardware event]
   instructions                                       [Hardware event]
   cache-references                                   [Hardware event]
   cache-misses                                       [Hardware event]
   branch-instructions OR branches                    [Hardware event]
   branch-misses                                      [Hardware event]
   bus-cycles                                         [Hardware event]
   ...                                                ...

   jbd2:jbd2_start_commit                             [Tracepoint event]
   jbd2:jbd2_commit_locking                           [Tracepoint event]
   jbd2:jbd2_run_stats                                [Tracepoint event]
   block:block_rq_issue                               [Tracepoint event]
   block:block_bio_complete                           [Tracepoint event]
   block:block_bio_backmerge                          [Tracepoint event]
   block:block_getrq                                  [Tracepoint event]
   ...                                                ...

After this patch:

 $ perf list

 List of pre-defined events (to be used in -e):
   branch-instructions OR branches                    [Hardware event]
   branch-misses                                      [Hardware event]
   bus-cycles                                         [Hardware event]
   cache-misses                                       [Hardware event]
   cache-references                                   [Hardware event]
   cpu-cycles OR cycles                               [Hardware event]
   instructions                                       [Hardware event]
   ...                                                ...

   block:block_bio_backmerge                          [Tracepoint event]
   block:block_bio_complete                           [Tracepoint event]
   block:block_getrq                                  [Tracepoint event]
   block:block_rq_issue                               [Tracepoint event]
   jbd2:jbd2_commit_locking                           [Tracepoint event]
   jbd2:jbd2_run_stats                                [Tracepoint event]
   jbd2:jbd2_start_commit                             [Tracepoint event]
   ...                                                ...

Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
---
 tools/perf/util/parse-events.c | 212 ++++++++++++++++++++++++++++++++++++-----
 1 file changed, 189 insertions(+), 23 deletions(-)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 109ba5c..41e196f 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1089,6 +1089,14 @@ static const char * const event_type_descriptors[] = {
 	"Hardware breakpoint",
 };
 
+static int cmp_string(const void *a, const void *b)
+{
+	const char * const *as = a;
+	const char * const *bs = b;
+
+	return strcmp(*as, *bs);
+}
+
 /*
  * Print the events from <debugfs_mount_point>/tracing/events
  */
@@ -1100,11 +1108,21 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
 	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
 	char evt_path[MAXPATHLEN];
 	char dir_path[MAXPATHLEN];
+	char **evt_list = NULL;
+	unsigned int evt_i = 0, evt_num = 0;
+	bool evt_num_known = false;
 
+restart:
 	sys_dir = opendir(tracing_events_path);
 	if (!sys_dir)
 		return;
 
+	if (evt_num_known) {
+		evt_list = zalloc(sizeof(char *) * evt_num);
+		if (!evt_list)
+			goto out_enomem;
+	}
+
 	for_each_subsystem(sys_dir, sys_dirent, sys_next) {
 		if (subsys_glob != NULL &&
 		    !strglobmatch(sys_dirent.d_name, subsys_glob))
@@ -1121,19 +1139,52 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
 			    !strglobmatch(evt_dirent.d_name, event_glob))
 				continue;
 
-			if (name_only) {
-				printf("%s:%s ", sys_dirent.d_name, evt_dirent.d_name);
+			if (!evt_num_known) {
+				evt_num++;
 				continue;
 			}
 
 			snprintf(evt_path, MAXPATHLEN, "%s:%s",
 				 sys_dirent.d_name, evt_dirent.d_name);
-			printf("  %-50s [%s]\n", evt_path,
-				event_type_descriptors[PERF_TYPE_TRACEPOINT]);
+
+			evt_list[evt_i] = strdup(evt_path);
+			if (evt_list[evt_i] == NULL)
+				goto out_enomem;
+			evt_i++;
 		}
 		closedir(evt_dir);
 	}
 	closedir(sys_dir);
+
+	if (!evt_num_known) {
+		evt_num_known = true;
+		goto restart;
+	}
+	qsort(evt_list, evt_num, sizeof(char *), cmp_string);
+	evt_i = 0;
+	while (evt_i < evt_num) {
+		if (name_only) {
+			printf("%s ", evt_list[evt_i++]);
+			continue;
+		}
+		printf("  %-50s [%s]\n", evt_list[evt_i++],
+				event_type_descriptors[PERF_TYPE_TRACEPOINT]);
+	}
+	if (evt_num)
+		printf("\n");
+
+out_free:
+	evt_num = evt_i;
+	for (evt_i = 0; evt_i < evt_num; evt_i++)
+		zfree(&evt_list[evt_i]);
+	zfree(&evt_list);
+	return;
+
+out_enomem:
+	printf("FATAL: not enough memory to print %s\n",
+			event_type_descriptors[PERF_TYPE_TRACEPOINT]);
+	if (evt_list)
+		goto out_free;
 }
 
 /*
@@ -1218,20 +1269,61 @@ static void __print_events_type(u8 type, struct event_symbol *syms,
 				unsigned max)
 {
 	char name[64];
-	unsigned i;
+	unsigned int i, evt_i = 0, evt_num = 0;
+	char **evt_list = NULL;
+	bool evt_num_known = false;
+
+restart:
+	if (evt_num_known) {
+		evt_list = zalloc(sizeof(char *) * evt_num);
+		if (!evt_list)
+			goto out_enomem;
+		syms -= max;
+	}
 
 	for (i = 0; i < max ; i++, syms++) {
 		if (!is_event_supported(type, i))
 			continue;
 
+		if (!evt_num_known) {
+			evt_num++;
+			continue;
+		}
+
 		if (strlen(syms->alias))
 			snprintf(name, sizeof(name),  "%s OR %s",
 				 syms->symbol, syms->alias);
 		else
 			snprintf(name, sizeof(name), "%s", syms->symbol);
 
-		printf("  %-50s [%s]\n", name, event_type_descriptors[type]);
+		evt_list[evt_i] = strdup(name);
+		if (evt_list[evt_i] == NULL)
+			goto out_enomem;
+		evt_i++;
 	}
+
+	if (!evt_num_known) {
+		evt_num_known = true;
+		goto restart;
+	}
+	qsort(evt_list, evt_num, sizeof(char *), cmp_string);
+	evt_i = 0;
+	while (evt_i < evt_num)
+		printf("  %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]);
+	if (evt_num)
+		printf("\n");
+
+out_free:
+	evt_num = evt_i;
+	for (evt_i = 0; evt_i < evt_num; evt_i++)
+		zfree(&evt_list[evt_i]);
+	zfree(&evt_list);
+	return;
+
+out_enomem:
+	printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]);
+	if (evt_list)
+		goto out_free;
 }
 
 void print_events_type(u8 type)
@@ -1244,8 +1336,17 @@ void print_events_type(u8 type)
 
 int print_hwcache_events(const char *event_glob, bool name_only)
 {
-	unsigned int type, op, i, printed = 0;
+	unsigned int type, op, i, evt_i = 0, evt_num = 0;
 	char name[64];
+	char **evt_list = NULL;
+	bool evt_num_known = false;
+
+restart:
+	if (evt_num_known) {
+		evt_list = zalloc(sizeof(char *) * evt_num);
+		if (!evt_list)
+			goto out_enomem;
+	}
 
 	for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
 		for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
@@ -1263,27 +1364,66 @@ int print_hwcache_events(const char *event_glob, bool name_only)
 							type | (op << 8) | (i << 16)))
 					continue;
 
-				if (name_only)
-					printf("%s ", name);
-				else
-					printf("  %-50s [%s]\n", name,
-					       event_type_descriptors[PERF_TYPE_HW_CACHE]);
-				++printed;
+				if (!evt_num_known) {
+					evt_num++;
+					continue;
+				}
+
+				evt_list[evt_i] = strdup(name);
+				if (evt_list[evt_i] == NULL)
+					goto out_enomem;
+				evt_i++;
 			}
 		}
 	}
 
-	if (printed)
+	if (!evt_num_known) {
+		evt_num_known = true;
+		goto restart;
+	}
+	qsort(evt_list, evt_num, sizeof(char *), cmp_string);
+	evt_i = 0;
+	while (evt_i < evt_num) {
+		if (name_only) {
+			printf("%s ", evt_list[evt_i++]);
+			continue;
+		}
+		printf("  %-50s [%s]\n", evt_list[evt_i++],
+				event_type_descriptors[PERF_TYPE_HW_CACHE]);
+	}
+	if (evt_num)
 		printf("\n");
-	return printed;
+
+out_free:
+	evt_num = evt_i;
+	for (evt_i = 0; evt_i < evt_num; evt_i++)
+		zfree(&evt_list[evt_i]);
+	zfree(&evt_list);
+	return evt_num;
+
+out_enomem:
+	printf("FATAL: not enough memory to print %s\n", event_type_descriptors[PERF_TYPE_HW_CACHE]);
+	if (evt_list)
+		goto out_free;
+	return evt_num;
 }
 
 static void print_symbol_events(const char *event_glob, unsigned type,
 				struct event_symbol *syms, unsigned max,
 				bool name_only)
 {
-	unsigned i, printed = 0;
+	unsigned int i, evt_i = 0, evt_num = 0;
 	char name[MAX_NAME_LEN];
+	char **evt_list = NULL;
+	bool evt_num_known = false;
+
+restart:
+	if (evt_num_known) {
+		evt_list = zalloc(sizeof(char *) * evt_num);
+		if (!evt_list)
+			goto out_enomem;
+		syms -= max;
+	}
 
 	for (i = 0; i < max; i++, syms++) {
 
@@ -1295,23 +1435,49 @@ static void print_symbol_events(const char *event_glob, unsigned type,
 		if (!is_event_supported(type, i))
 			continue;
 
-		if (name_only) {
-			printf("%s ", syms->symbol);
+		if (!evt_num_known) {
+			evt_num++;
 			continue;
 		}
 
-		if (strlen(syms->alias))
+		if (!name_only && strlen(syms->alias))
 			snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias);
 		else
 			strncpy(name, syms->symbol, MAX_NAME_LEN);
 
-		printf("  %-50s [%s]\n", name, event_type_descriptors[type]);
-
-		printed++;
+		evt_list[evt_i] = strdup(name);
+		if (evt_list[evt_i] == NULL)
+			goto out_enomem;
+		evt_i++;
 	}
 
-	if (printed)
+	if (!evt_num_known) {
+		evt_num_known = true;
+		goto restart;
+	}
+	qsort(evt_list, evt_num, sizeof(char *), cmp_string);
+	evt_i = 0;
+	while (evt_i < evt_num) {
+		if (name_only) {
+			printf("%s ", evt_list[evt_i++]);
+			continue;
+		}
+		printf("  %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]);
+	}
+	if (evt_num)
 		printf("\n");
+
+out_free:
+	evt_num = evt_i;
+	for (evt_i = 0; evt_i < evt_num; evt_i++)
+		zfree(&evt_list[evt_i]);
+	zfree(&evt_list);
+	return;
+
+out_enomem:
+	printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]);
+	if (evt_list)
+		goto out_free;
 }
 
 /*
-- 
1.8.5.5


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 2/7] perf list: Fix some inaccuracy problem when parsing the argument
  2015-02-27 10:21 [PATCH v3 0/7] perf core: Make some improvements and fixes Yunlong Song
  2015-02-27 10:21 ` [PATCH v3 1/7] perf list: Sort the output of 'perf list' to view more clearly Yunlong Song
@ 2015-02-27 10:21 ` Yunlong Song
  2015-02-28  9:33   ` [tip:perf/core] perf list: Allow listing events with 'tracepoint' prefix tip-bot for Yunlong Song
  2015-02-27 10:21 ` [PATCH v3 3/7] perf list: Clean up the printing functions of hardware/software events Yunlong Song
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 19+ messages in thread
From: Yunlong Song @ 2015-02-27 10:21 UTC (permalink / raw)
  To: a.p.zijlstra, paulus, mingo, acme; +Cc: linux-kernel, wangnan0

If somebody happens to name an event with the beginning of 'tracepoint'
(e.g. tracepoint_foo), then it will never be showed with perf list
event_glob, thus we parse the argument 'tracepoint' more carefully for
accuracy.

Example:

Before this patch:

 $ perf list tracepoint_foo:*

   jbd2:jbd2_start_commit                             [Tracepoint event]
   jbd2:jbd2_commit_locking                           [Tracepoint event]
   jbd2:jbd2_run_stats                                [Tracepoint event]
   block:block_rq_issue                               [Tracepoint event]
   block:block_bio_complete                           [Tracepoint event]
   block:block_bio_backmerge                          [Tracepoint event]
   block:block_getrq                                  [Tracepoint event]
   ...                                                ...

As shown above, all of the tracepoint events are printed. In fact, the
command's real intention is to print the events of tracepoint_foo.

After this patch:

 $ perf list tracepoint_foo:*

   tracepoint_foo:tp_foo_enter                        [Tracepoint event]
   tracepoint_foo:tp_foo_exit                         [Tracepoint event]

As shown above, only the events of tracepoint_foo are printed.

Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
---
 tools/perf/builtin-list.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index ad8018e..2acbcf0 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -50,9 +50,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
 	}
 
 	for (i = 0; i < argc; ++i) {
-		if (i)
-			putchar('\n');
-		if (strncmp(argv[i], "tracepoint", 10) == 0)
+		if (strcmp(argv[i], "tracepoint") == 0)
 			print_tracepoint_events(NULL, NULL, false);
 		else if (strcmp(argv[i], "hw") == 0 ||
 			 strcmp(argv[i], "hardware") == 0)
-- 
1.8.5.5


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 3/7] perf list: Clean up the printing functions of hardware/software events
  2015-02-27 10:21 [PATCH v3 0/7] perf core: Make some improvements and fixes Yunlong Song
  2015-02-27 10:21 ` [PATCH v3 1/7] perf list: Sort the output of 'perf list' to view more clearly Yunlong Song
  2015-02-27 10:21 ` [PATCH v3 2/7] perf list: Fix some inaccuracy problem when parsing the argument Yunlong Song
@ 2015-02-27 10:21 ` Yunlong Song
  2015-02-28  9:34   ` [tip:perf/core] " tip-bot for Yunlong Song
  2015-02-27 10:21 ` [PATCH v3 4/7] perf list: Extend raw-dump to certain kind of events Yunlong Song
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 19+ messages in thread
From: Yunlong Song @ 2015-02-27 10:21 UTC (permalink / raw)
  To: a.p.zijlstra, paulus, mingo, acme; +Cc: linux-kernel, wangnan0

Do not need print_events_type or __print_events_type for listing hw/sw
events, let print_symbol_events do its job instead. Moreover,
print_symbol_events can also handle event_glob and name_only.

Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
---
 tools/perf/builtin-list.c      |  6 ++--
 tools/perf/util/parse-events.c | 80 ++----------------------------------------
 tools/perf/util/parse-events.h | 11 +++++-
 3 files changed, 17 insertions(+), 80 deletions(-)

diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index 2acbcf0..8b323e0 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -54,10 +54,12 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
 			print_tracepoint_events(NULL, NULL, false);
 		else if (strcmp(argv[i], "hw") == 0 ||
 			 strcmp(argv[i], "hardware") == 0)
-			print_events_type(PERF_TYPE_HARDWARE);
+			print_symbol_events(NULL, PERF_TYPE_HARDWARE,
+					event_symbols_hw, PERF_COUNT_HW_MAX, false);
 		else if (strcmp(argv[i], "sw") == 0 ||
 			 strcmp(argv[i], "software") == 0)
-			print_events_type(PERF_TYPE_SOFTWARE);
+			print_symbol_events(NULL, PERF_TYPE_SOFTWARE,
+					event_symbols_sw, PERF_COUNT_SW_MAX, false);
 		else if (strcmp(argv[i], "cache") == 0 ||
 			 strcmp(argv[i], "hwcache") == 0)
 			print_hwcache_events(NULL, false);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 41e196f..a6465de 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -20,11 +20,6 @@
 
 #define MAX_NAME_LEN 100
 
-struct event_symbol {
-	const char	*symbol;
-	const char	*alias;
-};
-
 #ifdef PARSER_DEBUG
 extern int parse_events_debug;
 #endif
@@ -39,7 +34,7 @@ static struct perf_pmu_event_symbol *perf_pmu_events_list;
  */
 static int perf_pmu_events_list_num;
 
-static struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = {
+struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = {
 	[PERF_COUNT_HW_CPU_CYCLES] = {
 		.symbol = "cpu-cycles",
 		.alias  = "cycles",
@@ -82,7 +77,7 @@ static struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = {
 	},
 };
 
-static struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = {
+struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = {
 	[PERF_COUNT_SW_CPU_CLOCK] = {
 		.symbol = "cpu-clock",
 		.alias  = "",
@@ -1265,75 +1260,6 @@ static bool is_event_supported(u8 type, unsigned config)
 	return ret;
 }
 
-static void __print_events_type(u8 type, struct event_symbol *syms,
-				unsigned max)
-{
-	char name[64];
-	unsigned int i, evt_i = 0, evt_num = 0;
-	char **evt_list = NULL;
-	bool evt_num_known = false;
-
-restart:
-	if (evt_num_known) {
-		evt_list = zalloc(sizeof(char *) * evt_num);
-		if (!evt_list)
-			goto out_enomem;
-		syms -= max;
-	}
-
-	for (i = 0; i < max ; i++, syms++) {
-		if (!is_event_supported(type, i))
-			continue;
-
-		if (!evt_num_known) {
-			evt_num++;
-			continue;
-		}
-
-		if (strlen(syms->alias))
-			snprintf(name, sizeof(name),  "%s OR %s",
-				 syms->symbol, syms->alias);
-		else
-			snprintf(name, sizeof(name), "%s", syms->symbol);
-
-		evt_list[evt_i] = strdup(name);
-		if (evt_list[evt_i] == NULL)
-			goto out_enomem;
-		evt_i++;
-	}
-
-	if (!evt_num_known) {
-		evt_num_known = true;
-		goto restart;
-	}
-	qsort(evt_list, evt_num, sizeof(char *), cmp_string);
-	evt_i = 0;
-	while (evt_i < evt_num)
-		printf("  %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]);
-	if (evt_num)
-		printf("\n");
-
-out_free:
-	evt_num = evt_i;
-	for (evt_i = 0; evt_i < evt_num; evt_i++)
-		zfree(&evt_list[evt_i]);
-	zfree(&evt_list);
-	return;
-
-out_enomem:
-	printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]);
-	if (evt_list)
-		goto out_free;
-}
-
-void print_events_type(u8 type)
-{
-	if (type == PERF_TYPE_SOFTWARE)
-		__print_events_type(type, event_symbols_sw, PERF_COUNT_SW_MAX);
-	else
-		__print_events_type(type, event_symbols_hw, PERF_COUNT_HW_MAX);
-}
-
 int print_hwcache_events(const char *event_glob, bool name_only)
 {
 	unsigned int type, op, i, evt_i = 0, evt_num = 0;
@@ -1408,7 +1334,7 @@ out_enomem:
 	return evt_num;
 }
 
-static void print_symbol_events(const char *event_glob, unsigned type,
+void print_symbol_events(const char *event_glob, unsigned type,
 				struct event_symbol *syms, unsigned max,
 				bool name_only)
 {
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 39c3b57..52a2dda 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -116,7 +116,16 @@ void parse_events_update_lists(struct list_head *list_event,
 void parse_events_error(void *data, void *scanner, char const *msg);
 
 void print_events(const char *event_glob, bool name_only);
-void print_events_type(u8 type);
+
+struct event_symbol {
+	const char	*symbol;
+	const char	*alias;
+};
+extern struct event_symbol event_symbols_hw[];
+extern struct event_symbol event_symbols_sw[];
+void print_symbol_events(const char *event_glob, unsigned type,
+				struct event_symbol *syms, unsigned max,
+				bool name_only);
 void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
 			     bool name_only);
 int print_hwcache_events(const char *event_glob, bool name_only);
-- 
1.8.5.5


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 4/7] perf list: Extend raw-dump to certain kind of events
  2015-02-27 10:21 [PATCH v3 0/7] perf core: Make some improvements and fixes Yunlong Song
                   ` (2 preceding siblings ...)
  2015-02-27 10:21 ` [PATCH v3 3/7] perf list: Clean up the printing functions of hardware/software events Yunlong Song
@ 2015-02-27 10:21 ` Yunlong Song
  2015-02-27 15:20   ` Arnaldo Carvalho de Melo
  2015-02-28  9:34   ` [tip:perf/core] " tip-bot for Yunlong Song
  2015-02-27 10:21 ` [PATCH v3 5/7] perf list: Avoid confusion of perf output and the next command prompt Yunlong Song
                   ` (3 subsequent siblings)
  7 siblings, 2 replies; 19+ messages in thread
From: Yunlong Song @ 2015-02-27 10:21 UTC (permalink / raw)
  To: a.p.zijlstra, paulus, mingo, acme; +Cc: linux-kernel, wangnan0

Extend 'perf list --raw-dump' to 'perf list --raw-dump [hw|sw|cache
|tracepoint|pmu|event_glob]' in order to show the raw-dump of a
certain kind of events rather than all of the events.

Example:

Before this patch:

 $ perf list --raw-dump hw
 branch-instructions branch-misses bus-cycles cache-misses
 cache-references cpu-cycles instructions stalled-cycles-backend
 stalled-cycles-frontend
 alignment-faults context-switches cpu-clock cpu-migrations
 emulation-faults major-faults minor-faults page-faults task-clock
 ...
 ...
 writeback:writeback_thread_start writeback:writeback_thread_stop
 writeback:writeback_wait_iff_congested
 writeback:writeback_wake_background writeback:writeback_wake_thread

As shown above, all of the events are printed.

After this patch:

 $ perf list --raw-dump hw
 branch-instructions branch-misses bus-cycles cache-misses
 cache-references cpu-cycles instructions stalled-cycles-backend
 stalled-cycles-frontend

As shown above, only the hw events are printed.

Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
---
 tools/perf/Documentation/perf-list.txt |  6 ++++++
 tools/perf/builtin-list.c              | 21 ++++++++-------------
 2 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index 3e2aec9..4692d27 100644
--- a/tools/perf/Documentation/perf-list.txt
+++ b/tools/perf/Documentation/perf-list.txt
@@ -127,6 +127,12 @@ To limit the list use:
 One or more types can be used at the same time, listing the events for the
 types specified.
 
+Support raw format:
+
+. '--raw-dump', shows the raw-dump of all the events.
+. '--raw-dump [hw|sw|cache|tracepoint|pmu|event_glob]', shows the raw-dump of
+  a certain kind of events.
+
 SEE ALSO
 --------
 linkperf:perf-stat[1], linkperf:perf-top[1],
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index 8b323e0..af5bd05 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -36,41 +36,36 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
 
 	setup_pager();
 
-	if (raw_dump) {
-		print_events(NULL, true);
-		return 0;
-	}
-
 	if (!raw_dump)
 		printf("\nList of pre-defined events (to be used in -e):\n\n");
 
 	if (argc == 0) {
-		print_events(NULL, false);
+		print_events(NULL, raw_dump);
 		return 0;
 	}
 
 	for (i = 0; i < argc; ++i) {
 		if (strcmp(argv[i], "tracepoint") == 0)
-			print_tracepoint_events(NULL, NULL, false);
+			print_tracepoint_events(NULL, NULL, raw_dump);
 		else if (strcmp(argv[i], "hw") == 0 ||
 			 strcmp(argv[i], "hardware") == 0)
 			print_symbol_events(NULL, PERF_TYPE_HARDWARE,
-					event_symbols_hw, PERF_COUNT_HW_MAX, false);
+					event_symbols_hw, PERF_COUNT_HW_MAX, raw_dump);
 		else if (strcmp(argv[i], "sw") == 0 ||
 			 strcmp(argv[i], "software") == 0)
 			print_symbol_events(NULL, PERF_TYPE_SOFTWARE,
-					event_symbols_sw, PERF_COUNT_SW_MAX, false);
+					event_symbols_sw, PERF_COUNT_SW_MAX, raw_dump);
 		else if (strcmp(argv[i], "cache") == 0 ||
 			 strcmp(argv[i], "hwcache") == 0)
-			print_hwcache_events(NULL, false);
+			print_hwcache_events(NULL, raw_dump);
 		else if (strcmp(argv[i], "pmu") == 0)
-			print_pmu_events(NULL, false);
+			print_pmu_events(NULL, raw_dump);
 		else {
 			char *sep = strchr(argv[i], ':'), *s;
 			int sep_idx;
 
 			if (sep == NULL) {
-				print_events(argv[i], false);
+				print_events(argv[i], raw_dump);
 				continue;
 			}
 			sep_idx = sep - argv[i];
@@ -79,7 +74,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
 				return -1;
 
 			s[sep_idx] = '\0';
-			print_tracepoint_events(s, s + sep_idx + 1, false);
+			print_tracepoint_events(s, s + sep_idx + 1, raw_dump);
 			free(s);
 		}
 	}
-- 
1.8.5.5


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 5/7] perf list: Avoid confusion of perf output and the next command prompt
  2015-02-27 10:21 [PATCH v3 0/7] perf core: Make some improvements and fixes Yunlong Song
                   ` (3 preceding siblings ...)
  2015-02-27 10:21 ` [PATCH v3 4/7] perf list: Extend raw-dump to certain kind of events Yunlong Song
@ 2015-02-27 10:21 ` Yunlong Song
  2015-02-28  9:33   ` [tip:perf/core] " tip-bot for Yunlong Song
  2015-02-27 10:21 ` [PATCH v3 6/7] perf record: Remove the '--(null)' long_name for --list-opts Yunlong Song
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 19+ messages in thread
From: Yunlong Song @ 2015-02-27 10:21 UTC (permalink / raw)
  To: a.p.zijlstra, paulus, mingo, acme; +Cc: linux-kernel, wangnan0

Distinguish the output of 'perf list --list-opts' or 'perf --list-cmds'
with the next command prompt, which also happens in other cases (e.g.
record, report ...).

Example:

Before this patch:

 $perf list --list-opts
 --raw-dump $          <-- the output and the next command prompt are at
                           the same line

After this patch:

 $perf list --list-opts
 --raw-dump
 $                     <-- the new line

Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
---
 tools/perf/perf.c               | 1 +
 tools/perf/util/parse-options.c | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index f3c66b8..3df2665 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -223,6 +223,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
 				struct cmd_struct *p = commands+i;
 				printf("%s ", p->cmd);
 			}
+			putchar('\n');
 			exit(0);
 		} else if (!strcmp(cmd, "--debug")) {
 			if (*argc < 2) {
diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c
index 4ee9a86..b0ef2d8 100644
--- a/tools/perf/util/parse-options.c
+++ b/tools/perf/util/parse-options.c
@@ -508,12 +508,14 @@ int parse_options_subcommand(int argc, const char **argv, const struct option *o
 			printf("--%s ", options->long_name);
 			options++;
 		}
+		putchar('\n');
 		exit(130);
 	case PARSE_OPT_LIST_SUBCMDS:
 		if (subcommands) {
 			for (int i = 0; subcommands[i]; i++)
 				printf("%s ", subcommands[i]);
 		}
+		putchar('\n');
 		exit(130);
 	default: /* PARSE_OPT_UNKNOWN */
 		if (ctx.argv[0][1] == '-') {
-- 
1.8.5.5


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 6/7] perf record: Remove the '--(null)' long_name for --list-opts
  2015-02-27 10:21 [PATCH v3 0/7] perf core: Make some improvements and fixes Yunlong Song
                   ` (4 preceding siblings ...)
  2015-02-27 10:21 ` [PATCH v3 5/7] perf list: Avoid confusion of perf output and the next command prompt Yunlong Song
@ 2015-02-27 10:21 ` Yunlong Song
  2015-02-28  9:33   ` [tip:perf/core] perf tools: " tip-bot for Yunlong Song
  2015-02-27 10:21 ` [PATCH v3 7/7] perf core: Fix the bash completion problem of 'perf --*' Yunlong Song
  2015-02-27 15:27 ` [PATCH v3 0/7] perf core: Make some improvements and fixes Arnaldo Carvalho de Melo
  7 siblings, 1 reply; 19+ messages in thread
From: Yunlong Song @ 2015-02-27 10:21 UTC (permalink / raw)
  To: a.p.zijlstra, paulus, mingo, acme; +Cc: linux-kernel, wangnan0

If the long_name of a 'struct option' is defined as NULL, --list-opts
will incorrectly print '--(null)' in its output. As a result, '--(null)'
will finally appear in the case of bash completion, e.g. 'perf record --'.

Example:

Before this patch:

 $ perf record --list-opts

 --event --filter --pid --tid --realtime --no-buffering --raw-samples
 --all-cpus --cpu --count --output --no-inherit --freq --mmap-pages
 --group --(null) --call-graph --verbose --quiet --stat --data
 --timestamp --period --no-samples --no-buildid-cache --no-buildid
 --cgroup --delay --uid --branch-any --branch-filter --weight
 --transaction --per-thread --intr-regs

After this patch:

 $ perf record --list-opts

 --event --filter --pid --tid --realtime --no-buffering --raw-samples
 --all-cpus --cpu --count --output --no-inherit --freq --mmap-pages
 --group --call-graph --verbose --quiet --stat --data --timestamp
 --period --no-samples --no-buildid-cache --no-buildid --cgroup --delay
 --uid --branch-any --branch-filter --weight --transaction --per-thread
 --intr-regs

Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
---
 tools/perf/util/parse-options.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c
index b0ef2d8..1457d66 100644
--- a/tools/perf/util/parse-options.c
+++ b/tools/perf/util/parse-options.c
@@ -505,7 +505,8 @@ int parse_options_subcommand(int argc, const char **argv, const struct option *o
 		break;
 	case PARSE_OPT_LIST_OPTS:
 		while (options->type != OPTION_END) {
-			printf("--%s ", options->long_name);
+			if (options->long_name)
+				printf("--%s ", options->long_name);
 			options++;
 		}
 		putchar('\n');
-- 
1.8.5.5


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 7/7] perf core: Fix the bash completion problem of 'perf --*'
  2015-02-27 10:21 [PATCH v3 0/7] perf core: Make some improvements and fixes Yunlong Song
                   ` (5 preceding siblings ...)
  2015-02-27 10:21 ` [PATCH v3 6/7] perf record: Remove the '--(null)' long_name for --list-opts Yunlong Song
@ 2015-02-27 10:21 ` Yunlong Song
  2015-02-28  9:34   ` [tip:perf/core] perf tools: Fix the bash completion problem of ' perf --*' tip-bot for Yunlong Song
  2015-02-27 15:27 ` [PATCH v3 0/7] perf core: Make some improvements and fixes Arnaldo Carvalho de Melo
  7 siblings, 1 reply; 19+ messages in thread
From: Yunlong Song @ 2015-02-27 10:21 UTC (permalink / raw)
  To: a.p.zijlstra, paulus, mingo, acme; +Cc: linux-kernel, wangnan0

The perf-completion.sh uses a predefined string '--help --version
--exec-path --html-path --paginate --no-pager --perf-dir --work-tree
--debugfs-dir' for the bash completion of 'perf --*', which has two
problems:

 Problem 1: If the options of perf are changed (see handle_options() in
 perf.c), the perf-completion.sh has to be changed at the same time. If
 not, the bash completion of 'perf --*' and the options which perf
 really supports will be inconsistent.

 Problem 2: When typing another single character after 'perf --', e.g.
 'h', and hit TAB key to get the bash completion of 'perf --h', the
 character 'h' disappears at once. This is not what we want, we wish the
 bash completion can return '--help --html-path' and then we can
 continue to choose one.

 To solve this problem, we add '--list-opts' to perf, which now supports
 'perf --list-opts' directly, and its result can be used in bash
 completion now.

Example:

 Before this patch:

 $ perf --h                 <-- hit TAB key after character 'h'
 $ perf --                  <-- 'h' disappears and no required result

 After this patch:

 $ perf --h                 <-- hit TAB key after character 'h'
 --help       --html-path   <-- the required result

Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
---
 tools/perf/perf-completion.sh |  6 ++----
 tools/perf/perf.c             | 27 +++++++++++++++++++++++++++
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/tools/perf/perf-completion.sh b/tools/perf/perf-completion.sh
index 3356984..c2595e9 100644
--- a/tools/perf/perf-completion.sh
+++ b/tools/perf/perf-completion.sh
@@ -110,13 +110,11 @@ __perf_main ()
 	# List perf subcommands or long options
 	if [ $cword -eq 1 ]; then
 		if [[ $cur == --* ]]; then
-			__perfcomp '--help --version \
-			--exec-path --html-path --paginate --no-pager \
-			--perf-dir --work-tree --debugfs-dir' -- "$cur"
+			cmds=$($cmd --list-opts)
 		else
 			cmds=$($cmd --list-cmds)
-			__perfcomp "$cmds" "$cur"
 		fi
+		__perfcomp "$cmds" "$cur"
 	# List possible events for -e option
 	elif [[ $prev == "-e" && "${words[1]}" == @(record|stat|top) ]]; then
 		evts=$($cmd list --raw-dump)
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 3df2665..b857fcb 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -13,6 +13,7 @@
 #include "util/quote.h"
 #include "util/run-command.h"
 #include "util/parse-events.h"
+#include "util/parse-options.h"
 #include "util/debug.h"
 #include <api/fs/debugfs.h>
 #include <pthread.h>
@@ -125,6 +126,23 @@ static void commit_pager_choice(void)
 	}
 }
 
+struct option options[] = {
+	OPT_ARGUMENT("help", "help"),
+	OPT_ARGUMENT("version", "version"),
+	OPT_ARGUMENT("exec-path", "exec-path"),
+	OPT_ARGUMENT("html-path", "html-path"),
+	OPT_ARGUMENT("paginate", "paginate"),
+	OPT_ARGUMENT("no-pager", "no-pager"),
+	OPT_ARGUMENT("perf-dir", "perf-dir"),
+	OPT_ARGUMENT("work-tree", "work-tree"),
+	OPT_ARGUMENT("debugfs-dir", "debugfs-dir"),
+	OPT_ARGUMENT("buildid-dir", "buildid-dir"),
+	OPT_ARGUMENT("list-cmds", "list-cmds"),
+	OPT_ARGUMENT("list-opts", "list-opts"),
+	OPT_ARGUMENT("debug", "debug"),
+	OPT_END()
+};
+
 static int handle_options(const char ***argv, int *argc, int *envchanged)
 {
 	int handled = 0;
@@ -225,6 +243,15 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
 			}
 			putchar('\n');
 			exit(0);
+		} else if (!strcmp(cmd, "--list-opts")) {
+			unsigned int i;
+
+			for (i = 0; i < ARRAY_SIZE(options)-1; i++) {
+				struct option *p = options+i;
+				printf("--%s ", p->long_name);
+			}
+			putchar('\n');
+			exit(0);
 		} else if (!strcmp(cmd, "--debug")) {
 			if (*argc < 2) {
 				fprintf(stderr, "No variable specified for --debug.\n");
-- 
1.8.5.5


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 1/7] perf list: Sort the output of 'perf list' to view more clearly
  2015-02-27 10:21 ` [PATCH v3 1/7] perf list: Sort the output of 'perf list' to view more clearly Yunlong Song
@ 2015-02-27 13:57   ` Arnaldo Carvalho de Melo
  2015-02-28  9:32   ` [tip:perf/core] " tip-bot for Yunlong Song
  1 sibling, 0 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-02-27 13:57 UTC (permalink / raw)
  To: Yunlong Song; +Cc: a.p.zijlstra, paulus, mingo, linux-kernel, wangnan0

Em Fri, Feb 27, 2015 at 06:21:25PM +0800, Yunlong Song escreveu:
> Sort the output according to ASCII character list (using strcmp), which
> supports both number sequence and alphabet sequence.

That is a great feature to have, thanks!

But you are not calling closedir() if zalloc fails, I am fixing that for
you this time, please check those kinds of things in the future.

- Arnaldo
> @@ -1100,11 +1108,21 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
>  	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
>  	char evt_path[MAXPATHLEN];
>  	char dir_path[MAXPATHLEN];
> +	char **evt_list = NULL;
> +	unsigned int evt_i = 0, evt_num = 0;
> +	bool evt_num_known = false;
>  
> +restart:
>  	sys_dir = opendir(tracing_events_path);
>  	if (!sys_dir)
>  		return;
>  
> +	if (evt_num_known) {
> +		evt_list = zalloc(sizeof(char *) * evt_num);
> +		if (!evt_list)
> +			goto out_enomem;

Here, zalloc fails, goto out_enomem, closedir() not called.

> +out_free:
> +	evt_num = evt_i;
> +	for (evt_i = 0; evt_i < evt_num; evt_i++)
> +		zfree(&evt_list[evt_i]);
> +	zfree(&evt_list);
> +	return;
> +
> +out_enomem:
> +	printf("FATAL: not enough memory to print %s\n",
> +			event_type_descriptors[PERF_TYPE_TRACEPOINT]);
> +	if (evt_list)
> +		goto out_free;
>  }

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 4/7] perf list: Extend raw-dump to certain kind of events
  2015-02-27 10:21 ` [PATCH v3 4/7] perf list: Extend raw-dump to certain kind of events Yunlong Song
@ 2015-02-27 15:20   ` Arnaldo Carvalho de Melo
  2015-02-27 15:23     ` Arnaldo Carvalho de Melo
  2015-02-28  9:34   ` [tip:perf/core] " tip-bot for Yunlong Song
  1 sibling, 1 reply; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-02-27 15:20 UTC (permalink / raw)
  To: Yunlong Song; +Cc: a.p.zijlstra, paulus, mingo, linux-kernel, wangnan0

Em Fri, Feb 27, 2015 at 06:21:28PM +0800, Yunlong Song escreveu:
> Extend 'perf list --raw-dump' to 'perf list --raw-dump [hw|sw|cache
> |tracepoint|pmu|event_glob]' in order to show the raw-dump of a
> certain kind of events rather than all of the events.
> 
> Example:
> 
> Before this patch:
> 
>  $ perf list --raw-dump hw
>  branch-instructions branch-misses bus-cycles cache-misses
>  cache-references cpu-cycles instructions stalled-cycles-backend
>  stalled-cycles-frontend
>  alignment-faults context-switches cpu-clock cpu-migrations
>  emulation-faults major-faults minor-faults page-faults task-clock
>  ...
>  ...
>  writeback:writeback_thread_start writeback:writeback_thread_stop
>  writeback:writeback_wait_iff_congested
>  writeback:writeback_wake_background writeback:writeback_wake_thread
> 
> As shown above, all of the events are printed.

This patch doesn't apply, please check later in my perf/core branch to
resolve this issue, ok? I am processing the other patches in this
series.

- Arnaldo

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 4/7] perf list: Extend raw-dump to certain kind of events
  2015-02-27 15:20   ` Arnaldo Carvalho de Melo
@ 2015-02-27 15:23     ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-02-27 15:23 UTC (permalink / raw)
  To: Yunlong Song; +Cc: a.p.zijlstra, paulus, mingo, linux-kernel, wangnan0

Em Fri, Feb 27, 2015 at 12:20:46PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Fri, Feb 27, 2015 at 06:21:28PM +0800, Yunlong Song escreveu:
> > Extend 'perf list --raw-dump' to 'perf list --raw-dump [hw|sw|cache
> > |tracepoint|pmu|event_glob]' in order to show the raw-dump of a
> > certain kind of events rather than all of the events.
> > 
> > Example:
> > 
> > Before this patch:
> > 
> >  $ perf list --raw-dump hw
> >  branch-instructions branch-misses bus-cycles cache-misses
> >  cache-references cpu-cycles instructions stalled-cycles-backend
> >  stalled-cycles-frontend
> >  alignment-faults context-switches cpu-clock cpu-migrations
> >  emulation-faults major-faults minor-faults page-faults task-clock
> >  ...
> >  ...
> >  writeback:writeback_thread_start writeback:writeback_thread_stop
> >  writeback:writeback_wait_iff_congested
> >  writeback:writeback_wake_background writeback:writeback_wake_thread
> > 
> > As shown above, all of the events are printed.
> 
> This patch doesn't apply, please check later in my perf/core branch to
> resolve this issue, ok? I am processing the other patches in this
> series.

My bad, the patches came out of order and I forgot to use threaded view
in mutt, nevermind, applying...

- Arnaldo

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 0/7] perf core: Make some improvements and fixes
  2015-02-27 10:21 [PATCH v3 0/7] perf core: Make some improvements and fixes Yunlong Song
                   ` (6 preceding siblings ...)
  2015-02-27 10:21 ` [PATCH v3 7/7] perf core: Fix the bash completion problem of 'perf --*' Yunlong Song
@ 2015-02-27 15:27 ` Arnaldo Carvalho de Melo
  7 siblings, 0 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-02-27 15:27 UTC (permalink / raw)
  To: Yunlong Song; +Cc: a.p.zijlstra, paulus, mingo, linux-kernel, wangnan0

Em Fri, Feb 27, 2015 at 06:21:24PM +0800, Yunlong Song escreveu:
> Hi,
>   Found some functions to improve and bugs to fix in perf.
>   
>   This patchset is based on:
>   https://git.kernel.org/cgit/linux/kernel/git/acme/linux.git/  perf/core
> 
>   For [PATCH v3 4/7] and [PATCH v3 5/7], I have checked that these
>   patches do not break shell autocompletion. Besides, for [PATCH v3 4/7],
>   --raw-dump without an argument still shows all the events.

Thanks, all applied (and tested).

- Arnaldo

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [tip:perf/core] perf list: Sort the output of 'perf list' to view more clearly
  2015-02-27 10:21 ` [PATCH v3 1/7] perf list: Sort the output of 'perf list' to view more clearly Yunlong Song
  2015-02-27 13:57   ` Arnaldo Carvalho de Melo
@ 2015-02-28  9:32   ` tip-bot for Yunlong Song
  1 sibling, 0 replies; 19+ messages in thread
From: tip-bot for Yunlong Song @ 2015-02-28  9:32 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, paulus, linux-kernel, yunlong.song, a.p.zijlstra, tglx,
	mingo, wangnan0, acme

Commit-ID:  ab0e48002db818c1937f105cd18001dfdd3ce056
Gitweb:     http://git.kernel.org/tip/ab0e48002db818c1937f105cd18001dfdd3ce056
Author:     Yunlong Song <yunlong.song@huawei.com>
AuthorDate: Fri, 27 Feb 2015 18:21:25 +0800
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 27 Feb 2015 15:51:44 -0300

perf list: Sort the output of 'perf list' to view more clearly

Sort the output according to ASCII character list (using strcmp), which
supports both number sequence and alphabet sequence.

Example:

Before this patch:

 $ perf list

 List of pre-defined events (to be used in -e):
   cpu-cycles OR cycles                               [Hardware event]
   instructions                                       [Hardware event]
   cache-references                                   [Hardware event]
   cache-misses                                       [Hardware event]
   branch-instructions OR branches                    [Hardware event]
   branch-misses                                      [Hardware event]
   bus-cycles                                         [Hardware event]
   ...                                                ...

   jbd2:jbd2_start_commit                             [Tracepoint event]
   jbd2:jbd2_commit_locking                           [Tracepoint event]
   jbd2:jbd2_run_stats                                [Tracepoint event]
   block:block_rq_issue                               [Tracepoint event]
   block:block_bio_complete                           [Tracepoint event]
   block:block_bio_backmerge                          [Tracepoint event]
   block:block_getrq                                  [Tracepoint event]
   ...                                                ...

After this patch:

 $ perf list

 List of pre-defined events (to be used in -e):
   branch-instructions OR branches                    [Hardware event]
   branch-misses                                      [Hardware event]
   bus-cycles                                         [Hardware event]
   cache-misses                                       [Hardware event]
   cache-references                                   [Hardware event]
   cpu-cycles OR cycles                               [Hardware event]
   instructions                                       [Hardware event]
   ...                                                ...

   block:block_bio_backmerge                          [Tracepoint event]
   block:block_bio_complete                           [Tracepoint event]
   block:block_getrq                                  [Tracepoint event]
   block:block_rq_issue                               [Tracepoint event]
   jbd2:jbd2_commit_locking                           [Tracepoint event]
   jbd2:jbd2_run_stats                                [Tracepoint event]
   jbd2:jbd2_start_commit                             [Tracepoint event]
   ...                                                ...

Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1425032491-20224-2-git-send-email-yunlong.song@huawei.com
[ Don't forget closedir({sys,evt}_dir) when handling errors ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/parse-events.c | 216 ++++++++++++++++++++++++++++++++++++-----
 1 file changed, 193 insertions(+), 23 deletions(-)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 109ba5c..f6822d9 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1089,6 +1089,14 @@ static const char * const event_type_descriptors[] = {
 	"Hardware breakpoint",
 };
 
+static int cmp_string(const void *a, const void *b)
+{
+	const char * const *as = a;
+	const char * const *bs = b;
+
+	return strcmp(*as, *bs);
+}
+
 /*
  * Print the events from <debugfs_mount_point>/tracing/events
  */
@@ -1100,11 +1108,21 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
 	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
 	char evt_path[MAXPATHLEN];
 	char dir_path[MAXPATHLEN];
+	char **evt_list = NULL;
+	unsigned int evt_i = 0, evt_num = 0;
+	bool evt_num_known = false;
 
+restart:
 	sys_dir = opendir(tracing_events_path);
 	if (!sys_dir)
 		return;
 
+	if (evt_num_known) {
+		evt_list = zalloc(sizeof(char *) * evt_num);
+		if (!evt_list)
+			goto out_close_sys_dir;
+	}
+
 	for_each_subsystem(sys_dir, sys_dirent, sys_next) {
 		if (subsys_glob != NULL &&
 		    !strglobmatch(sys_dirent.d_name, subsys_glob))
@@ -1121,19 +1139,56 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
 			    !strglobmatch(evt_dirent.d_name, event_glob))
 				continue;
 
-			if (name_only) {
-				printf("%s:%s ", sys_dirent.d_name, evt_dirent.d_name);
+			if (!evt_num_known) {
+				evt_num++;
 				continue;
 			}
 
 			snprintf(evt_path, MAXPATHLEN, "%s:%s",
 				 sys_dirent.d_name, evt_dirent.d_name);
-			printf("  %-50s [%s]\n", evt_path,
-				event_type_descriptors[PERF_TYPE_TRACEPOINT]);
+
+			evt_list[evt_i] = strdup(evt_path);
+			if (evt_list[evt_i] == NULL)
+				goto out_close_evt_dir;
+			evt_i++;
 		}
 		closedir(evt_dir);
 	}
 	closedir(sys_dir);
+
+	if (!evt_num_known) {
+		evt_num_known = true;
+		goto restart;
+	}
+	qsort(evt_list, evt_num, sizeof(char *), cmp_string);
+	evt_i = 0;
+	while (evt_i < evt_num) {
+		if (name_only) {
+			printf("%s ", evt_list[evt_i++]);
+			continue;
+		}
+		printf("  %-50s [%s]\n", evt_list[evt_i++],
+				event_type_descriptors[PERF_TYPE_TRACEPOINT]);
+	}
+	if (evt_num)
+		printf("\n");
+
+out_free:
+	evt_num = evt_i;
+	for (evt_i = 0; evt_i < evt_num; evt_i++)
+		zfree(&evt_list[evt_i]);
+	zfree(&evt_list);
+	return;
+
+out_close_evt_dir:
+	closedir(evt_dir);
+out_close_sys_dir:
+	closedir(sys_dir);
+
+	printf("FATAL: not enough memory to print %s\n",
+			event_type_descriptors[PERF_TYPE_TRACEPOINT]);
+	if (evt_list)
+		goto out_free;
 }
 
 /*
@@ -1218,20 +1273,61 @@ static void __print_events_type(u8 type, struct event_symbol *syms,
 				unsigned max)
 {
 	char name[64];
-	unsigned i;
+	unsigned int i, evt_i = 0, evt_num = 0;
+	char **evt_list = NULL;
+	bool evt_num_known = false;
+
+restart:
+	if (evt_num_known) {
+		evt_list = zalloc(sizeof(char *) * evt_num);
+		if (!evt_list)
+			goto out_enomem;
+		syms -= max;
+	}
 
 	for (i = 0; i < max ; i++, syms++) {
 		if (!is_event_supported(type, i))
 			continue;
 
+		if (!evt_num_known) {
+			evt_num++;
+			continue;
+		}
+
 		if (strlen(syms->alias))
 			snprintf(name, sizeof(name),  "%s OR %s",
 				 syms->symbol, syms->alias);
 		else
 			snprintf(name, sizeof(name), "%s", syms->symbol);
 
-		printf("  %-50s [%s]\n", name, event_type_descriptors[type]);
+		evt_list[evt_i] = strdup(name);
+		if (evt_list[evt_i] == NULL)
+			goto out_enomem;
+		evt_i++;
+	}
+
+	if (!evt_num_known) {
+		evt_num_known = true;
+		goto restart;
 	}
+	qsort(evt_list, evt_num, sizeof(char *), cmp_string);
+	evt_i = 0;
+	while (evt_i < evt_num)
+		printf("  %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]);
+	if (evt_num)
+		printf("\n");
+
+out_free:
+	evt_num = evt_i;
+	for (evt_i = 0; evt_i < evt_num; evt_i++)
+		zfree(&evt_list[evt_i]);
+	zfree(&evt_list);
+	return;
+
+out_enomem:
+	printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]);
+	if (evt_list)
+		goto out_free;
 }
 
 void print_events_type(u8 type)
@@ -1244,8 +1340,17 @@ void print_events_type(u8 type)
 
 int print_hwcache_events(const char *event_glob, bool name_only)
 {
-	unsigned int type, op, i, printed = 0;
+	unsigned int type, op, i, evt_i = 0, evt_num = 0;
 	char name[64];
+	char **evt_list = NULL;
+	bool evt_num_known = false;
+
+restart:
+	if (evt_num_known) {
+		evt_list = zalloc(sizeof(char *) * evt_num);
+		if (!evt_list)
+			goto out_enomem;
+	}
 
 	for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
 		for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
@@ -1263,27 +1368,66 @@ int print_hwcache_events(const char *event_glob, bool name_only)
 							type | (op << 8) | (i << 16)))
 					continue;
 
-				if (name_only)
-					printf("%s ", name);
-				else
-					printf("  %-50s [%s]\n", name,
-					       event_type_descriptors[PERF_TYPE_HW_CACHE]);
-				++printed;
+				if (!evt_num_known) {
+					evt_num++;
+					continue;
+				}
+
+				evt_list[evt_i] = strdup(name);
+				if (evt_list[evt_i] == NULL)
+					goto out_enomem;
+				evt_i++;
 			}
 		}
 	}
 
-	if (printed)
+	if (!evt_num_known) {
+		evt_num_known = true;
+		goto restart;
+	}
+	qsort(evt_list, evt_num, sizeof(char *), cmp_string);
+	evt_i = 0;
+	while (evt_i < evt_num) {
+		if (name_only) {
+			printf("%s ", evt_list[evt_i++]);
+			continue;
+		}
+		printf("  %-50s [%s]\n", evt_list[evt_i++],
+				event_type_descriptors[PERF_TYPE_HW_CACHE]);
+	}
+	if (evt_num)
 		printf("\n");
-	return printed;
+
+out_free:
+	evt_num = evt_i;
+	for (evt_i = 0; evt_i < evt_num; evt_i++)
+		zfree(&evt_list[evt_i]);
+	zfree(&evt_list);
+	return evt_num;
+
+out_enomem:
+	printf("FATAL: not enough memory to print %s\n", event_type_descriptors[PERF_TYPE_HW_CACHE]);
+	if (evt_list)
+		goto out_free;
+	return evt_num;
 }
 
 static void print_symbol_events(const char *event_glob, unsigned type,
 				struct event_symbol *syms, unsigned max,
 				bool name_only)
 {
-	unsigned i, printed = 0;
+	unsigned int i, evt_i = 0, evt_num = 0;
 	char name[MAX_NAME_LEN];
+	char **evt_list = NULL;
+	bool evt_num_known = false;
+
+restart:
+	if (evt_num_known) {
+		evt_list = zalloc(sizeof(char *) * evt_num);
+		if (!evt_list)
+			goto out_enomem;
+		syms -= max;
+	}
 
 	for (i = 0; i < max; i++, syms++) {
 
@@ -1295,23 +1439,49 @@ static void print_symbol_events(const char *event_glob, unsigned type,
 		if (!is_event_supported(type, i))
 			continue;
 
-		if (name_only) {
-			printf("%s ", syms->symbol);
+		if (!evt_num_known) {
+			evt_num++;
 			continue;
 		}
 
-		if (strlen(syms->alias))
+		if (!name_only && strlen(syms->alias))
 			snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias);
 		else
 			strncpy(name, syms->symbol, MAX_NAME_LEN);
 
-		printf("  %-50s [%s]\n", name, event_type_descriptors[type]);
-
-		printed++;
+		evt_list[evt_i] = strdup(name);
+		if (evt_list[evt_i] == NULL)
+			goto out_enomem;
+		evt_i++;
 	}
 
-	if (printed)
+	if (!evt_num_known) {
+		evt_num_known = true;
+		goto restart;
+	}
+	qsort(evt_list, evt_num, sizeof(char *), cmp_string);
+	evt_i = 0;
+	while (evt_i < evt_num) {
+		if (name_only) {
+			printf("%s ", evt_list[evt_i++]);
+			continue;
+		}
+		printf("  %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]);
+	}
+	if (evt_num)
 		printf("\n");
+
+out_free:
+	evt_num = evt_i;
+	for (evt_i = 0; evt_i < evt_num; evt_i++)
+		zfree(&evt_list[evt_i]);
+	zfree(&evt_list);
+	return;
+
+out_enomem:
+	printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]);
+	if (evt_list)
+		goto out_free;
 }
 
 /*

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [tip:perf/core] perf list: Allow listing events with 'tracepoint' prefix
  2015-02-27 10:21 ` [PATCH v3 2/7] perf list: Fix some inaccuracy problem when parsing the argument Yunlong Song
@ 2015-02-28  9:33   ` tip-bot for Yunlong Song
  0 siblings, 0 replies; 19+ messages in thread
From: tip-bot for Yunlong Song @ 2015-02-28  9:33 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, acme, mingo, linux-kernel, paulus, wangnan0, yunlong.song,
	tglx, a.p.zijlstra, mingo

Commit-ID:  161149513b3570ebd7fe14fc2ddc42cb46557e37
Gitweb:     http://git.kernel.org/tip/161149513b3570ebd7fe14fc2ddc42cb46557e37
Author:     Yunlong Song <yunlong.song@huawei.com>
AuthorDate: Fri, 27 Feb 2015 18:21:26 +0800
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 27 Feb 2015 15:51:51 -0300

perf list: Allow listing events with 'tracepoint' prefix

If somebody happens to name an event with the beginning of 'tracepoint'
(e.g. tracepoint_foo), then it will never be showed with perf list
event_glob, thus we parse the argument 'tracepoint' more carefully for
accuracy.

Example:

Before this patch:

 $ perf list tracepoint_foo:*

   jbd2:jbd2_start_commit                             [Tracepoint event]
   jbd2:jbd2_commit_locking                           [Tracepoint event]
   jbd2:jbd2_run_stats                                [Tracepoint event]
   block:block_rq_issue                               [Tracepoint event]
   block:block_bio_complete                           [Tracepoint event]
   block:block_bio_backmerge                          [Tracepoint event]
   block:block_getrq                                  [Tracepoint event]
   ...                                                ...

As shown above, all of the tracepoint events are printed. In fact, the
command's real intention is to print the events of tracepoint_foo.

After this patch:

 $ perf list tracepoint_foo:*

   tracepoint_foo:tp_foo_enter                        [Tracepoint event]
   tracepoint_foo:tp_foo_exit                         [Tracepoint event]

As shown above, only the events of tracepoint_foo are printed.

Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1425032491-20224-3-git-send-email-yunlong.song@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-list.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index ad8018e..2acbcf0 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -50,9 +50,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
 	}
 
 	for (i = 0; i < argc; ++i) {
-		if (i)
-			putchar('\n');
-		if (strncmp(argv[i], "tracepoint", 10) == 0)
+		if (strcmp(argv[i], "tracepoint") == 0)
 			print_tracepoint_events(NULL, NULL, false);
 		else if (strcmp(argv[i], "hw") == 0 ||
 			 strcmp(argv[i], "hardware") == 0)

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [tip:perf/core] perf list: Avoid confusion of perf output and the next command prompt
  2015-02-27 10:21 ` [PATCH v3 5/7] perf list: Avoid confusion of perf output and the next command prompt Yunlong Song
@ 2015-02-28  9:33   ` tip-bot for Yunlong Song
  0 siblings, 0 replies; 19+ messages in thread
From: tip-bot for Yunlong Song @ 2015-02-28  9:33 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, mingo, paulus, linux-kernel, tglx, wangnan0, acme,
	yunlong.song, a.p.zijlstra

Commit-ID:  ed45752061be11a40f57df4304296147dbda2da9
Gitweb:     http://git.kernel.org/tip/ed45752061be11a40f57df4304296147dbda2da9
Author:     Yunlong Song <yunlong.song@huawei.com>
AuthorDate: Fri, 27 Feb 2015 18:21:29 +0800
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 27 Feb 2015 15:52:09 -0300

perf list: Avoid confusion of perf output and the next command prompt

Distinguish the output of 'perf list --list-opts' or 'perf --list-cmds'
with the next command prompt, which also happens in other cases (e.g.
record, report ...).

Example:

Before this patch:

 $perf list --list-opts
 --raw-dump $          <-- the output and the next command prompt are at
                           the same line

After this patch:

 $perf list --list-opts
 --raw-dump
 $                     <-- the new line

Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1425032491-20224-6-git-send-email-yunlong.song@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/perf.c               | 1 +
 tools/perf/util/parse-options.c | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index f3c66b8..3df2665 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -223,6 +223,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
 				struct cmd_struct *p = commands+i;
 				printf("%s ", p->cmd);
 			}
+			putchar('\n');
 			exit(0);
 		} else if (!strcmp(cmd, "--debug")) {
 			if (*argc < 2) {
diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c
index 4ee9a86..b0ef2d8 100644
--- a/tools/perf/util/parse-options.c
+++ b/tools/perf/util/parse-options.c
@@ -508,12 +508,14 @@ int parse_options_subcommand(int argc, const char **argv, const struct option *o
 			printf("--%s ", options->long_name);
 			options++;
 		}
+		putchar('\n');
 		exit(130);
 	case PARSE_OPT_LIST_SUBCMDS:
 		if (subcommands) {
 			for (int i = 0; subcommands[i]; i++)
 				printf("%s ", subcommands[i]);
 		}
+		putchar('\n');
 		exit(130);
 	default: /* PARSE_OPT_UNKNOWN */
 		if (ctx.argv[0][1] == '-') {

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [tip:perf/core] perf tools: Remove the '--(null)' long_name for --list-opts
  2015-02-27 10:21 ` [PATCH v3 6/7] perf record: Remove the '--(null)' long_name for --list-opts Yunlong Song
@ 2015-02-28  9:33   ` tip-bot for Yunlong Song
  0 siblings, 0 replies; 19+ messages in thread
From: tip-bot for Yunlong Song @ 2015-02-28  9:33 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: wangnan0, linux-kernel, mingo, a.p.zijlstra, hpa, yunlong.song,
	tglx, acme, paulus

Commit-ID:  3ef1e65c829c86ffaa94a4ed59fed5da37f9610a
Gitweb:     http://git.kernel.org/tip/3ef1e65c829c86ffaa94a4ed59fed5da37f9610a
Author:     Yunlong Song <yunlong.song@huawei.com>
AuthorDate: Fri, 27 Feb 2015 18:21:30 +0800
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 27 Feb 2015 15:52:14 -0300

perf tools: Remove the '--(null)' long_name for --list-opts

If the long_name of a 'struct option' is defined as NULL, --list-opts
will incorrectly print '--(null)' in its output. As a result, '--(null)'
will finally appear in the case of bash completion, e.g. 'perf record
--'.

Example:

Before this patch:

 $ perf record --list-opts

 --event --filter --pid --tid --realtime --no-buffering --raw-samples
 --all-cpus --cpu --count --output --no-inherit --freq --mmap-pages
 --group --(null) --call-graph --verbose --quiet --stat --data
 --timestamp --period --no-samples --no-buildid-cache --no-buildid
 --cgroup --delay --uid --branch-any --branch-filter --weight
 --transaction --per-thread --intr-regs

After this patch:

 $ perf record --list-opts

 --event --filter --pid --tid --realtime --no-buffering --raw-samples
 --all-cpus --cpu --count --output --no-inherit --freq --mmap-pages
 --group --call-graph --verbose --quiet --stat --data --timestamp
 --period --no-samples --no-buildid-cache --no-buildid --cgroup --delay
 --uid --branch-any --branch-filter --weight --transaction --per-thread
 --intr-regs

Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1425032491-20224-7-git-send-email-yunlong.song@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/parse-options.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c
index b0ef2d8..1457d66 100644
--- a/tools/perf/util/parse-options.c
+++ b/tools/perf/util/parse-options.c
@@ -505,7 +505,8 @@ int parse_options_subcommand(int argc, const char **argv, const struct option *o
 		break;
 	case PARSE_OPT_LIST_OPTS:
 		while (options->type != OPTION_END) {
-			printf("--%s ", options->long_name);
+			if (options->long_name)
+				printf("--%s ", options->long_name);
 			options++;
 		}
 		putchar('\n');

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [tip:perf/core] perf list: Clean up the printing functions of hardware/software events
  2015-02-27 10:21 ` [PATCH v3 3/7] perf list: Clean up the printing functions of hardware/software events Yunlong Song
@ 2015-02-28  9:34   ` tip-bot for Yunlong Song
  0 siblings, 0 replies; 19+ messages in thread
From: tip-bot for Yunlong Song @ 2015-02-28  9:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, wangnan0, tglx, hpa, a.p.zijlstra, mingo,
	yunlong.song, paulus, acme, mingo

Commit-ID:  705750f2d6e283ba2856ba8eda60dce2d405b387
Gitweb:     http://git.kernel.org/tip/705750f2d6e283ba2856ba8eda60dce2d405b387
Author:     Yunlong Song <yunlong.song@huawei.com>
AuthorDate: Fri, 27 Feb 2015 18:21:27 +0800
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 27 Feb 2015 15:52:18 -0300

perf list: Clean up the printing functions of hardware/software events

Do not need print_events_type or __print_events_type for listing hw/sw
events, let print_symbol_events do its job instead. Moreover,
print_symbol_events can also handle event_glob and name_only.

Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1425032491-20224-4-git-send-email-yunlong.song@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-list.c      |  6 ++--
 tools/perf/util/parse-events.c | 80 ++----------------------------------------
 tools/perf/util/parse-events.h | 11 +++++-
 3 files changed, 17 insertions(+), 80 deletions(-)

diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index 2acbcf0..8b323e0 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -54,10 +54,12 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
 			print_tracepoint_events(NULL, NULL, false);
 		else if (strcmp(argv[i], "hw") == 0 ||
 			 strcmp(argv[i], "hardware") == 0)
-			print_events_type(PERF_TYPE_HARDWARE);
+			print_symbol_events(NULL, PERF_TYPE_HARDWARE,
+					event_symbols_hw, PERF_COUNT_HW_MAX, false);
 		else if (strcmp(argv[i], "sw") == 0 ||
 			 strcmp(argv[i], "software") == 0)
-			print_events_type(PERF_TYPE_SOFTWARE);
+			print_symbol_events(NULL, PERF_TYPE_SOFTWARE,
+					event_symbols_sw, PERF_COUNT_SW_MAX, false);
 		else if (strcmp(argv[i], "cache") == 0 ||
 			 strcmp(argv[i], "hwcache") == 0)
 			print_hwcache_events(NULL, false);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index f6822d9..fe07573 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -20,11 +20,6 @@
 
 #define MAX_NAME_LEN 100
 
-struct event_symbol {
-	const char	*symbol;
-	const char	*alias;
-};
-
 #ifdef PARSER_DEBUG
 extern int parse_events_debug;
 #endif
@@ -39,7 +34,7 @@ static struct perf_pmu_event_symbol *perf_pmu_events_list;
  */
 static int perf_pmu_events_list_num;
 
-static struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = {
+struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = {
 	[PERF_COUNT_HW_CPU_CYCLES] = {
 		.symbol = "cpu-cycles",
 		.alias  = "cycles",
@@ -82,7 +77,7 @@ static struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = {
 	},
 };
 
-static struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = {
+struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = {
 	[PERF_COUNT_SW_CPU_CLOCK] = {
 		.symbol = "cpu-clock",
 		.alias  = "",
@@ -1269,75 +1264,6 @@ static bool is_event_supported(u8 type, unsigned config)
 	return ret;
 }
 
-static void __print_events_type(u8 type, struct event_symbol *syms,
-				unsigned max)
-{
-	char name[64];
-	unsigned int i, evt_i = 0, evt_num = 0;
-	char **evt_list = NULL;
-	bool evt_num_known = false;
-
-restart:
-	if (evt_num_known) {
-		evt_list = zalloc(sizeof(char *) * evt_num);
-		if (!evt_list)
-			goto out_enomem;
-		syms -= max;
-	}
-
-	for (i = 0; i < max ; i++, syms++) {
-		if (!is_event_supported(type, i))
-			continue;
-
-		if (!evt_num_known) {
-			evt_num++;
-			continue;
-		}
-
-		if (strlen(syms->alias))
-			snprintf(name, sizeof(name),  "%s OR %s",
-				 syms->symbol, syms->alias);
-		else
-			snprintf(name, sizeof(name), "%s", syms->symbol);
-
-		evt_list[evt_i] = strdup(name);
-		if (evt_list[evt_i] == NULL)
-			goto out_enomem;
-		evt_i++;
-	}
-
-	if (!evt_num_known) {
-		evt_num_known = true;
-		goto restart;
-	}
-	qsort(evt_list, evt_num, sizeof(char *), cmp_string);
-	evt_i = 0;
-	while (evt_i < evt_num)
-		printf("  %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]);
-	if (evt_num)
-		printf("\n");
-
-out_free:
-	evt_num = evt_i;
-	for (evt_i = 0; evt_i < evt_num; evt_i++)
-		zfree(&evt_list[evt_i]);
-	zfree(&evt_list);
-	return;
-
-out_enomem:
-	printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]);
-	if (evt_list)
-		goto out_free;
-}
-
-void print_events_type(u8 type)
-{
-	if (type == PERF_TYPE_SOFTWARE)
-		__print_events_type(type, event_symbols_sw, PERF_COUNT_SW_MAX);
-	else
-		__print_events_type(type, event_symbols_hw, PERF_COUNT_HW_MAX);
-}
-
 int print_hwcache_events(const char *event_glob, bool name_only)
 {
 	unsigned int type, op, i, evt_i = 0, evt_num = 0;
@@ -1412,7 +1338,7 @@ out_enomem:
 	return evt_num;
 }
 
-static void print_symbol_events(const char *event_glob, unsigned type,
+void print_symbol_events(const char *event_glob, unsigned type,
 				struct event_symbol *syms, unsigned max,
 				bool name_only)
 {
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 39c3b57..52a2dda 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -116,7 +116,16 @@ void parse_events_update_lists(struct list_head *list_event,
 void parse_events_error(void *data, void *scanner, char const *msg);
 
 void print_events(const char *event_glob, bool name_only);
-void print_events_type(u8 type);
+
+struct event_symbol {
+	const char	*symbol;
+	const char	*alias;
+};
+extern struct event_symbol event_symbols_hw[];
+extern struct event_symbol event_symbols_sw[];
+void print_symbol_events(const char *event_glob, unsigned type,
+				struct event_symbol *syms, unsigned max,
+				bool name_only);
 void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
 			     bool name_only);
 int print_hwcache_events(const char *event_glob, bool name_only);

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [tip:perf/core] perf list: Extend raw-dump to certain kind of events
  2015-02-27 10:21 ` [PATCH v3 4/7] perf list: Extend raw-dump to certain kind of events Yunlong Song
  2015-02-27 15:20   ` Arnaldo Carvalho de Melo
@ 2015-02-28  9:34   ` tip-bot for Yunlong Song
  1 sibling, 0 replies; 19+ messages in thread
From: tip-bot for Yunlong Song @ 2015-02-28  9:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, tglx, linux-kernel, mingo, hpa, wangnan0, paulus,
	yunlong.song, a.p.zijlstra

Commit-ID:  5ef803ee02d67ad0b49f357cb7feb7d5e6b0015d
Gitweb:     http://git.kernel.org/tip/5ef803ee02d67ad0b49f357cb7feb7d5e6b0015d
Author:     Yunlong Song <yunlong.song@huawei.com>
AuthorDate: Fri, 27 Feb 2015 18:21:28 +0800
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 27 Feb 2015 15:52:24 -0300

perf list: Extend raw-dump to certain kind of events

Extend 'perf list --raw-dump' to 'perf list --raw-dump [hw|sw|cache
|tracepoint|pmu|event_glob]' in order to show the raw-dump of a certain
kind of events rather than all of the events.

Example:

Before this patch:

 $ perf list --raw-dump hw
 branch-instructions branch-misses bus-cycles cache-misses
 cache-references cpu-cycles instructions stalled-cycles-backend
 stalled-cycles-frontend
 alignment-faults context-switches cpu-clock cpu-migrations
 emulation-faults major-faults minor-faults page-faults task-clock
 ...
 ...
 writeback:writeback_thread_start writeback:writeback_thread_stop
 writeback:writeback_wait_iff_congested
 writeback:writeback_wake_background writeback:writeback_wake_thread

As shown above, all of the events are printed.

After this patch:

 $ perf list --raw-dump hw
 branch-instructions branch-misses bus-cycles cache-misses
 cache-references cpu-cycles instructions stalled-cycles-backend
 stalled-cycles-frontend

As shown above, only the hw events are printed.

Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1425032491-20224-5-git-send-email-yunlong.song@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-list.txt |  6 ++++++
 tools/perf/builtin-list.c              | 21 ++++++++-------------
 2 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index 3e2aec9..4692d27 100644
--- a/tools/perf/Documentation/perf-list.txt
+++ b/tools/perf/Documentation/perf-list.txt
@@ -127,6 +127,12 @@ To limit the list use:
 One or more types can be used at the same time, listing the events for the
 types specified.
 
+Support raw format:
+
+. '--raw-dump', shows the raw-dump of all the events.
+. '--raw-dump [hw|sw|cache|tracepoint|pmu|event_glob]', shows the raw-dump of
+  a certain kind of events.
+
 SEE ALSO
 --------
 linkperf:perf-stat[1], linkperf:perf-top[1],
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index 8b323e0..af5bd05 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -36,41 +36,36 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
 
 	setup_pager();
 
-	if (raw_dump) {
-		print_events(NULL, true);
-		return 0;
-	}
-
 	if (!raw_dump)
 		printf("\nList of pre-defined events (to be used in -e):\n\n");
 
 	if (argc == 0) {
-		print_events(NULL, false);
+		print_events(NULL, raw_dump);
 		return 0;
 	}
 
 	for (i = 0; i < argc; ++i) {
 		if (strcmp(argv[i], "tracepoint") == 0)
-			print_tracepoint_events(NULL, NULL, false);
+			print_tracepoint_events(NULL, NULL, raw_dump);
 		else if (strcmp(argv[i], "hw") == 0 ||
 			 strcmp(argv[i], "hardware") == 0)
 			print_symbol_events(NULL, PERF_TYPE_HARDWARE,
-					event_symbols_hw, PERF_COUNT_HW_MAX, false);
+					event_symbols_hw, PERF_COUNT_HW_MAX, raw_dump);
 		else if (strcmp(argv[i], "sw") == 0 ||
 			 strcmp(argv[i], "software") == 0)
 			print_symbol_events(NULL, PERF_TYPE_SOFTWARE,
-					event_symbols_sw, PERF_COUNT_SW_MAX, false);
+					event_symbols_sw, PERF_COUNT_SW_MAX, raw_dump);
 		else if (strcmp(argv[i], "cache") == 0 ||
 			 strcmp(argv[i], "hwcache") == 0)
-			print_hwcache_events(NULL, false);
+			print_hwcache_events(NULL, raw_dump);
 		else if (strcmp(argv[i], "pmu") == 0)
-			print_pmu_events(NULL, false);
+			print_pmu_events(NULL, raw_dump);
 		else {
 			char *sep = strchr(argv[i], ':'), *s;
 			int sep_idx;
 
 			if (sep == NULL) {
-				print_events(argv[i], false);
+				print_events(argv[i], raw_dump);
 				continue;
 			}
 			sep_idx = sep - argv[i];
@@ -79,7 +74,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
 				return -1;
 
 			s[sep_idx] = '\0';
-			print_tracepoint_events(s, s + sep_idx + 1, false);
+			print_tracepoint_events(s, s + sep_idx + 1, raw_dump);
 			free(s);
 		}
 	}

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [tip:perf/core] perf tools: Fix the bash completion problem of ' perf --*'
  2015-02-27 10:21 ` [PATCH v3 7/7] perf core: Fix the bash completion problem of 'perf --*' Yunlong Song
@ 2015-02-28  9:34   ` tip-bot for Yunlong Song
  0 siblings, 0 replies; 19+ messages in thread
From: tip-bot for Yunlong Song @ 2015-02-28  9:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, paulus, wangnan0, mingo, linux-kernel, acme, yunlong.song,
	a.p.zijlstra, tglx, hpa

Commit-ID:  7335399a6a4bead9ef8b59ce7d811fc4e99ca98c
Gitweb:     http://git.kernel.org/tip/7335399a6a4bead9ef8b59ce7d811fc4e99ca98c
Author:     Yunlong Song <yunlong.song@huawei.com>
AuthorDate: Fri, 27 Feb 2015 18:21:31 +0800
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 27 Feb 2015 15:52:28 -0300

perf tools: Fix the bash completion problem of 'perf --*'

The perf-completion.sh uses a predefined string '--help --version
--exec-path --html-path --paginate --no-pager --perf-dir --work-tree
--debugfs-dir' for the bash completion of 'perf --*', which has two
problems:

 Problem 1: If the options of perf are changed (see handle_options() in
 perf.c), the perf-completion.sh has to be changed at the same time. If
 not, the bash completion of 'perf --*' and the options which perf
 really supports will be inconsistent.

 Problem 2: When typing another single character after 'perf --', e.g.
 'h', and hit TAB key to get the bash completion of 'perf --h', the
 character 'h' disappears at once. This is not what we want, we wish the
 bash completion can return '--help --html-path' and then we can
 continue to choose one.

 To solve this problem, we add '--list-opts' to perf, which now supports
 'perf --list-opts' directly, and its result can be used in bash
 completion now.

Example:

 Before this patch:

 $ perf --h                 <-- hit TAB key after character 'h'
 $ perf --                  <-- 'h' disappears and no required result

 After this patch:

 $ perf --h                 <-- hit TAB key after character 'h'
 --help       --html-path   <-- the required result

Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1425032491-20224-8-git-send-email-yunlong.song@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/perf-completion.sh |  6 ++----
 tools/perf/perf.c             | 27 +++++++++++++++++++++++++++
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/tools/perf/perf-completion.sh b/tools/perf/perf-completion.sh
index 3356984..c2595e9 100644
--- a/tools/perf/perf-completion.sh
+++ b/tools/perf/perf-completion.sh
@@ -110,13 +110,11 @@ __perf_main ()
 	# List perf subcommands or long options
 	if [ $cword -eq 1 ]; then
 		if [[ $cur == --* ]]; then
-			__perfcomp '--help --version \
-			--exec-path --html-path --paginate --no-pager \
-			--perf-dir --work-tree --debugfs-dir' -- "$cur"
+			cmds=$($cmd --list-opts)
 		else
 			cmds=$($cmd --list-cmds)
-			__perfcomp "$cmds" "$cur"
 		fi
+		__perfcomp "$cmds" "$cur"
 	# List possible events for -e option
 	elif [[ $prev == "-e" && "${words[1]}" == @(record|stat|top) ]]; then
 		evts=$($cmd list --raw-dump)
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 3df2665..b857fcb 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -13,6 +13,7 @@
 #include "util/quote.h"
 #include "util/run-command.h"
 #include "util/parse-events.h"
+#include "util/parse-options.h"
 #include "util/debug.h"
 #include <api/fs/debugfs.h>
 #include <pthread.h>
@@ -125,6 +126,23 @@ static void commit_pager_choice(void)
 	}
 }
 
+struct option options[] = {
+	OPT_ARGUMENT("help", "help"),
+	OPT_ARGUMENT("version", "version"),
+	OPT_ARGUMENT("exec-path", "exec-path"),
+	OPT_ARGUMENT("html-path", "html-path"),
+	OPT_ARGUMENT("paginate", "paginate"),
+	OPT_ARGUMENT("no-pager", "no-pager"),
+	OPT_ARGUMENT("perf-dir", "perf-dir"),
+	OPT_ARGUMENT("work-tree", "work-tree"),
+	OPT_ARGUMENT("debugfs-dir", "debugfs-dir"),
+	OPT_ARGUMENT("buildid-dir", "buildid-dir"),
+	OPT_ARGUMENT("list-cmds", "list-cmds"),
+	OPT_ARGUMENT("list-opts", "list-opts"),
+	OPT_ARGUMENT("debug", "debug"),
+	OPT_END()
+};
+
 static int handle_options(const char ***argv, int *argc, int *envchanged)
 {
 	int handled = 0;
@@ -225,6 +243,15 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
 			}
 			putchar('\n');
 			exit(0);
+		} else if (!strcmp(cmd, "--list-opts")) {
+			unsigned int i;
+
+			for (i = 0; i < ARRAY_SIZE(options)-1; i++) {
+				struct option *p = options+i;
+				printf("--%s ", p->long_name);
+			}
+			putchar('\n');
+			exit(0);
 		} else if (!strcmp(cmd, "--debug")) {
 			if (*argc < 2) {
 				fprintf(stderr, "No variable specified for --debug.\n");

^ permalink raw reply related	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2015-02-28  9:35 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-27 10:21 [PATCH v3 0/7] perf core: Make some improvements and fixes Yunlong Song
2015-02-27 10:21 ` [PATCH v3 1/7] perf list: Sort the output of 'perf list' to view more clearly Yunlong Song
2015-02-27 13:57   ` Arnaldo Carvalho de Melo
2015-02-28  9:32   ` [tip:perf/core] " tip-bot for Yunlong Song
2015-02-27 10:21 ` [PATCH v3 2/7] perf list: Fix some inaccuracy problem when parsing the argument Yunlong Song
2015-02-28  9:33   ` [tip:perf/core] perf list: Allow listing events with 'tracepoint' prefix tip-bot for Yunlong Song
2015-02-27 10:21 ` [PATCH v3 3/7] perf list: Clean up the printing functions of hardware/software events Yunlong Song
2015-02-28  9:34   ` [tip:perf/core] " tip-bot for Yunlong Song
2015-02-27 10:21 ` [PATCH v3 4/7] perf list: Extend raw-dump to certain kind of events Yunlong Song
2015-02-27 15:20   ` Arnaldo Carvalho de Melo
2015-02-27 15:23     ` Arnaldo Carvalho de Melo
2015-02-28  9:34   ` [tip:perf/core] " tip-bot for Yunlong Song
2015-02-27 10:21 ` [PATCH v3 5/7] perf list: Avoid confusion of perf output and the next command prompt Yunlong Song
2015-02-28  9:33   ` [tip:perf/core] " tip-bot for Yunlong Song
2015-02-27 10:21 ` [PATCH v3 6/7] perf record: Remove the '--(null)' long_name for --list-opts Yunlong Song
2015-02-28  9:33   ` [tip:perf/core] perf tools: " tip-bot for Yunlong Song
2015-02-27 10:21 ` [PATCH v3 7/7] perf core: Fix the bash completion problem of 'perf --*' Yunlong Song
2015-02-28  9:34   ` [tip:perf/core] perf tools: Fix the bash completion problem of ' perf --*' tip-bot for Yunlong Song
2015-02-27 15:27 ` [PATCH v3 0/7] perf core: Make some improvements and fixes Arnaldo Carvalho de Melo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox