[PATCH 03/14] perf trace: Move vfs_getname storage to per thread area

From: Arnaldo Carvalho de Melo
Date: Mon Aug 17 2015 - 15:16:07 EST


From: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>

We were storing the vfs_getname payload (i.e. ptr->string) into
the trace wide storage area (struct trace), so that we could use the
last payload when setting up the fd->pathname per thread tables, oops,
not a good idea for multi cpu tracing sessions...

Fix it by moving it to the per thread area (struct thread_trace).

Cc: Adrian Hunter <adrian.hunter@xxxxxxxxx>
Cc: Borislav Petkov <bp@xxxxxxx>
Cc: David Ahern <dsahern@xxxxxxxxx>
Cc: Frederic Weisbecker <fweisbec@xxxxxxxxx>
Cc: Jiri Olsa <jolsa@xxxxxxxxxx>
Cc: Namhyung Kim <namhyung@xxxxxxxxxx>
Cc: Stephane Eranian <eranian@xxxxxxxxxx>
Link: http://lkml.kernel.org/n/tip-3j05ttqyaem7kh7oubvr1keo@xxxxxxxxxxxxxx
Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
---
tools/perf/builtin-trace.c | 38 +++++++++++++++++++++++++++-----------
1 file changed, 27 insertions(+), 11 deletions(-)

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 489cc118a36a..2f1162daa3c5 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1315,7 +1315,10 @@ struct thread_trace {
double runtime_ms;
struct {
unsigned long ptr;
- int entry_str_pos;
+ short int entry_str_pos;
+ bool pending_open;
+ unsigned int namelen;
+ char *name;
} filename;
struct {
int max;
@@ -1391,7 +1394,6 @@ struct trace {
size_t nr;
int *entries;
} ev_qualifier_ids;
- const char *last_vfs_getname;
struct intlist *tid_list;
struct intlist *pid_list;
struct {
@@ -1966,8 +1968,11 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
trace__fprintf_entry_head(trace, thread, 1, sample->time, trace->output);
fprintf(trace->output, "%-70s\n", ttrace->entry_str);
}
- } else
+ } else {
ttrace->entry_pending = true;
+ /* See trace__vfs_getname & trace__sys_exit */
+ ttrace->filename.pending_open = false;
+ }

if (trace->current != thread) {
thread__put(trace->current);
@@ -2003,9 +2008,9 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,

ret = perf_evsel__sc_tp_uint(evsel, ret, sample);

- if (id == trace->audit.open_id && ret >= 0 && trace->last_vfs_getname) {
- trace__set_fd_pathname(thread, ret, trace->last_vfs_getname);
- trace->last_vfs_getname = NULL;
+ if (id == trace->audit.open_id && ret >= 0 && ttrace->filename.pending_open) {
+ trace__set_fd_pathname(thread, ret, ttrace->filename.name);
+ ttrace->filename.pending_open = false;
++trace->stats.vfs_getname;
}

@@ -2065,9 +2070,7 @@ static int trace__vfs_getname(struct trace *trace, struct perf_evsel *evsel,
size_t filename_len, entry_str_len, to_move;
ssize_t remaining_space;
char *pos;
- const char *filename;
-
- trace->last_vfs_getname = perf_evsel__rawptr(evsel, sample, "pathname");
+ const char *filename = perf_evsel__rawptr(evsel, sample, "pathname");

if (!thread)
goto out;
@@ -2076,6 +2079,21 @@ static int trace__vfs_getname(struct trace *trace, struct perf_evsel *evsel,
if (!ttrace)
goto out;

+ filename_len = strlen(filename);
+
+ if (ttrace->filename.namelen < filename_len) {
+ char *f = realloc(ttrace->filename.name, filename_len + 1);
+
+ if (f == NULL)
+ goto out;
+
+ ttrace->filename.namelen = filename_len;
+ ttrace->filename.name = f;
+ }
+
+ strcpy(ttrace->filename.name, filename);
+ ttrace->filename.pending_open = true;
+
if (!ttrace->filename.ptr)
goto out;

@@ -2084,8 +2102,6 @@ static int trace__vfs_getname(struct trace *trace, struct perf_evsel *evsel,
if (remaining_space <= 0)
goto out;

- filename = trace->last_vfs_getname;
- filename_len = strlen(filename);
if (filename_len > (size_t)remaining_space) {
filename += filename_len - remaining_space;
filename_len = remaining_space;
--
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/