Commit 63cd02d8 authored by Changbin Du's avatar Changbin Du Committed by Arnaldo Carvalho de Melo

perf ftrace: Append an EOL when write tracing files

Before this change, the '--graph-funcs', '--nograph-funcs' and
'--trace-funcs' options didn't work as expected when the <func> doesn't
exist. Because the kernel side hid possible errors.

  $ sudo ./perf ftrace -a --graph-depth 1 --graph-funcs abcdefg
   0)   0.140 us    |  rcu_all_qs();
   3)   0.304 us    |  mutex_unlock();
   0)   0.153 us    |  find_vma();
   3)   0.088 us    |  __fsnotify_parent();
   0)   6.145 us    |  handle_mm_fault();
   3)   0.089 us    |  fsnotify();
   3)   0.161 us    |  __sb_end_write();
   3)   0.710 us    |  SyS_close();
   3)   7.848 us    |  exit_to_usermode_loop();

On the example above, I specified the function filter 'abcdefg' but all
functions are enabled. The expected result is for all functions to be
filtered, since there is no such function ('abcdefg')

The original fix is to make the kernel support '\0' as end of string:
https://lkml.org/lkml/2018/1/16/116

But above fix cannot be compatible with old kernels. Then Namhyung Kim
suggest adding a space after function name.

This patch will append an '\n' when write tracing file. After this fix,
the perf will report correct error state. Also let it print an error if
reset_tracing_files() fails.

Committer testing:

Now it prints:

  # perf ftrace -a --graph-depth 1 --graph-funcs abcdefg
  failed to set tracing filters
  #

And for an existing function:

  # perf ftrace -a --graph-depth 1 --graph-funcs SyS_open
   3)               |  SyS_open() {
   3) ! 494.899 us  |  }
   0) + 23.910 us   |  SyS_open();
   1) + 17.115 us   |  SyS_open();
   1) + 13.900 us   |  SyS_open();
   ------------------------------------------
   3)  qemu-sy-2817  =>  pickup-1290
   ------------------------------------------

   3) + 20.021 us   |  SyS_open();
  #
Signed-off-by: default avatarChangbin Du <changbin.du@intel.com>
Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1519007609-14551-1-git-send-email-changbin.du@intel.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 1d12cec6
...@@ -72,6 +72,7 @@ static int __write_tracing_file(const char *name, const char *val, bool append) ...@@ -72,6 +72,7 @@ static int __write_tracing_file(const char *name, const char *val, bool append)
ssize_t size = strlen(val); ssize_t size = strlen(val);
int flags = O_WRONLY; int flags = O_WRONLY;
char errbuf[512]; char errbuf[512];
char *val_copy;
file = get_tracing_file(name); file = get_tracing_file(name);
if (!file) { if (!file) {
...@@ -91,12 +92,23 @@ static int __write_tracing_file(const char *name, const char *val, bool append) ...@@ -91,12 +92,23 @@ static int __write_tracing_file(const char *name, const char *val, bool append)
goto out; goto out;
} }
if (write(fd, val, size) == size) /*
* Copy the original value and append a '\n'. Without this,
* the kernel can hide possible errors.
*/
val_copy = strdup(val);
if (!val_copy)
goto out_close;
val_copy[size] = '\n';
if (write(fd, val_copy, size + 1) == size + 1)
ret = 0; ret = 0;
else else
pr_debug("write '%s' to tracing/%s failed: %s\n", pr_debug("write '%s' to tracing/%s failed: %s\n",
val, name, str_error_r(errno, errbuf, sizeof(errbuf))); val, name, str_error_r(errno, errbuf, sizeof(errbuf)));
free(val_copy);
out_close:
close(fd); close(fd);
out: out:
put_tracing_file(file); put_tracing_file(file);
...@@ -280,8 +292,10 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv) ...@@ -280,8 +292,10 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv)
signal(SIGCHLD, sig_handler); signal(SIGCHLD, sig_handler);
signal(SIGPIPE, sig_handler); signal(SIGPIPE, sig_handler);
if (reset_tracing_files(ftrace) < 0) if (reset_tracing_files(ftrace) < 0) {
pr_err("failed to reset ftrace\n");
goto out; goto out;
}
/* reset ftrace buffer */ /* reset ftrace buffer */
if (write_tracing_file("trace", "0") < 0) if (write_tracing_file("trace", "0") < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment