perf tracepoint: Don't scan all tracepoints to test if one exists

In is_valid_tracepoint, rather than scanning
"/sys/kernel/tracing/events/*/*" skipping any path where
"/sys/kernel/tracing/events/*/*/id" doesn't exist, and then testing if
"*:*" matches the tracepoint name, just use the given tracepoint name
replace the ':' with '/' and see if the id file exists.

This turns a nested directory search into a single file available test.

Rather than return 1 for valid and 0 for invalid, return true and false.

Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240509153245.1990426-1-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Ian Rogers 2024-05-09 08:32:45 -07:00 committed by Arnaldo Carvalho de Melo
parent c9d492378f
commit d790ead8a6
2 changed files with 21 additions and 32 deletions

View file

@ -4,10 +4,12 @@
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/param.h>
#include <unistd.h>
#include <api/fs/tracing_path.h>
#include "fncache.h"
int tp_event_has_id(const char *dir_path, struct dirent *evt_dir)
{
@ -26,39 +28,25 @@ int tp_event_has_id(const char *dir_path, struct dirent *evt_dir)
/*
* Check whether event is in <debugfs_mount_point>/tracing/events
*/
int is_valid_tracepoint(const char *event_string)
bool is_valid_tracepoint(const char *event_string)
{
DIR *sys_dir, *evt_dir;
struct dirent *sys_dirent, *evt_dirent;
char evt_path[MAXPATHLEN];
char *dir_path;
char *dst, *path = malloc(strlen(event_string) + 4); /* Space for "/id\0". */
bool have_file = false; /* Conservatively return false if memory allocation failed. */
const char *src;
sys_dir = tracing_events__opendir();
if (!sys_dir)
return 0;
if (!path)
return false;
for_each_subsystem(sys_dir, sys_dirent) {
dir_path = get_events_file(sys_dirent->d_name);
if (!dir_path)
continue;
evt_dir = opendir(dir_path);
if (!evt_dir)
goto next;
/* Copy event_string replacing the ':' with '/'. */
for (src = event_string, dst = path; *src; src++, dst++)
*dst = (*src == ':') ? '/' : *src;
/* Add "/id\0". */
memcpy(dst, "/id", 4);
for_each_event(dir_path, evt_dir, evt_dirent) {
snprintf(evt_path, MAXPATHLEN, "%s:%s",
sys_dirent->d_name, evt_dirent->d_name);
if (!strcmp(evt_path, event_string)) {
closedir(evt_dir);
put_events_file(dir_path);
closedir(sys_dir);
return 1;
}
}
closedir(evt_dir);
next:
put_events_file(dir_path);
}
closedir(sys_dir);
return 0;
dst = get_events_file(path);
if (dst)
have_file = file_available(dst);
free(dst);
free(path);
return have_file;
}

View file

@ -4,6 +4,7 @@
#include <dirent.h>
#include <string.h>
#include <stdbool.h>
int tp_event_has_id(const char *dir_path, struct dirent *evt_dir);
@ -20,6 +21,6 @@ int tp_event_has_id(const char *dir_path, struct dirent *evt_dir);
(strcmp(sys_dirent->d_name, ".")) && \
(strcmp(sys_dirent->d_name, "..")))
int is_valid_tracepoint(const char *event_string);
bool is_valid_tracepoint(const char *event_string);
#endif /* __PERF_TRACEPOINT_H */