diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 93ac724fb635..e90c29ed9e0f 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1330,6 +1330,11 @@ static size_t fprintf_duration(unsigned long t, FILE *fp) return printed + fprintf(fp, "): "); } +struct file { + char *path; + bool eventfd; +}; + /** * filename.ptr: The filename char pointer that will be vfs_getname'd * filename.entry_str_pos: Where to insert the string translated from @@ -1351,9 +1356,9 @@ struct thread_trace { char *name; } filename; struct { - int max; - char **table; - } paths; + int max; + struct file *table; + } files; struct intlist *syscall_stats; }; @@ -1363,7 +1368,7 @@ static struct thread_trace *thread_trace__new(void) struct thread_trace *ttrace = zalloc(sizeof(struct thread_trace)); if (ttrace) - ttrace->paths.max = -1; + ttrace->files.max = -1; ttrace->syscall_stats = intlist__new(NULL); @@ -1403,6 +1408,7 @@ struct trace { struct { int machine; int open_id; + int eventfd_id; } audit; struct { int max; @@ -1451,30 +1457,47 @@ struct trace { int trace_pgfaults; }; +static int thread_trace__extend_files(struct thread_trace *ttrace, int fd) +{ + struct file *ntable = realloc(ttrace->files.table, (fd + 1) * sizeof(ttrace->files.table[0])); + + if (ntable == NULL) + return -1; + + if (ttrace->files.max != -1) { + memset(ntable + ttrace->files.max + 1, 0, + (fd - ttrace->files.max) * sizeof(ttrace->files.table[0])); + } else { + memset(ntable, 0, (fd + 1) * sizeof(ttrace->files.table[0])); + } + + ttrace->files.table = ntable; + ttrace->files.max = fd; + memset(&ttrace->files.table[fd], 0, sizeof(ttrace->files.table[fd])); + return 0; +} + static int trace__set_fd_pathname(struct thread *thread, int fd, const char *pathname) { struct thread_trace *ttrace = thread__priv(thread); - if (fd > ttrace->paths.max) { - char **npath = realloc(ttrace->paths.table, (fd + 1) * sizeof(char *)); + if (fd > ttrace->files.max && thread_trace__extend_files(ttrace, fd) < 0) + return -1; - if (npath == NULL) - return -1; + ttrace->files.table[fd].path = strdup(pathname); - if (ttrace->paths.max != -1) { - memset(npath + ttrace->paths.max + 1, 0, - (fd - ttrace->paths.max) * sizeof(char *)); - } else { - memset(npath, 0, (fd + 1) * sizeof(char *)); - } + return ttrace->files.table[fd].path != NULL ? 0 : -1; +} - ttrace->paths.table = npath; - ttrace->paths.max = fd; - } +static int trace__set_eventfd(struct thread *thread, int fd) +{ + struct thread_trace *ttrace = thread__priv(thread); - ttrace->paths.table[fd] = strdup(pathname); + if (fd > ttrace->files.max && thread_trace__extend_files(ttrace, fd) < 0) + return -1; - return ttrace->paths.table[fd] != NULL ? 0 : -1; + ttrace->files.table[fd].eventfd = true; + return 0; } static int thread__read_fd_path(struct thread *thread, int fd) @@ -1514,7 +1537,7 @@ static const char *thread__fd_path(struct thread *thread, int fd, if (fd < 0) return NULL; - if ((fd > ttrace->paths.max || ttrace->paths.table[fd] == NULL)) { + if ((fd > ttrace->files.max || ttrace->files.table[fd].path == NULL)) { if (!trace->live) return NULL; ++trace->stats.proc_getname; @@ -1522,7 +1545,7 @@ static const char *thread__fd_path(struct thread *thread, int fd, return NULL; } - return ttrace->paths.table[fd]; + return ttrace->files.table[fd].path; } static size_t syscall_arg__scnprintf_fd(char *bf, size_t size, @@ -1545,8 +1568,8 @@ static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size, size_t printed = syscall_arg__scnprintf_fd(bf, size, arg); struct thread_trace *ttrace = thread__priv(arg->thread); - if (ttrace && fd >= 0 && fd <= ttrace->paths.max) - zfree(&ttrace->paths.table[fd]); + if (ttrace && fd >= 0 && fd <= ttrace->files.max) + zfree(&ttrace->files.table[fd].path); return printed; } @@ -1786,6 +1809,17 @@ out: return err; } +static struct format_field *syscall__find_argument(struct syscall *sc, const char *name) +{ + struct format_field *field; + + for (field = sc->args; field; field = field->next) + if (strcmp(field->name, name) == 0) + return field; + + return NULL; +} + /* * args is to be interpreted as a series of longs but we need to handle * 8-byte unaligned accesses. args points to raw_data within the event @@ -1974,6 +2008,8 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, if (sc == NULL) return -1; + if (sc->has_fd && + thread = machine__findnew_thread(trace->host, sample->pid, sample->tid); ttrace = thread__trace(thread, trace->output); if (ttrace == NULL) @@ -2046,6 +2082,8 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, trace__set_fd_pathname(thread, ret, ttrace->filename.name); ttrace->filename.pending_open = false; ++trace->stats.vfs_getname; + } else if (id == trace->audit.eventfd_id && ret >= 0) { + trace__set_eventfd(thread, ret); } ttrace->exit_time = sample->time; @@ -3073,6 +3111,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) .audit = { .machine = audit_detect_machine(), .open_id = audit_name_to_syscall("open", trace.audit.machine), + .eventfd_id = audit_name_to_syscall("eventfd", trace.audit.machine), }, .syscalls = { . max = -1,