mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-17 09:43:59 +08:00
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>
This commit is contained in:
parent
1f924c29b5
commit
ab0e48002d
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user