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:
parent
c9d492378f
commit
d790ead8a6
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user