Skip to content

Commit ba5f102

Browse files
Thomas Richteracmel
authored andcommitted
perf ftrace: Use process/session specific trace settings
Executing 'perf ftrace' commands 'ftrace', 'profile' and 'latency' leave tracing disabled as can seen in this output: # echo 1 > /sys/kernel/debug/tracing/tracing_on # cat /sys/kernel/debug/tracing/tracing_on 1 # perf ftrace trace --graph-opts depth=5 sleep 0.1 > /dev/null # cat /sys/kernel/debug/tracing/tracing_on 0 # The 'tracing_on' file is not restored to its value before the command. To fix that this patch uses the .../tracing/instances/XXX subdirectory feature. Each 'perf ftrace' invocation creates its own session/process specific subdirectory and does not change the global state in the .../tracing directory itself. Use rmdir(../tracing/instances/dir) to stop process/session specific tracing and delete all process/session specific setings. Reported-by: Alexander Egorenkov <[email protected]> Suggested-by: Arnaldo Carvalho de Melo <[email protected]> Signed-off-by: Thomas Richter <[email protected]> Cc: Alexander Gordeev <[email protected]> Cc: Heiko Carstens <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Sumanth Korikkar <[email protected]> Cc: Vasily Gorbik <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent e48b92f commit ba5f102

File tree

1 file changed

+87
-14
lines changed

1 file changed

+87
-14
lines changed

tools/perf/builtin-ftrace.c

Lines changed: 87 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <ctype.h>
2020
#include <linux/capability.h>
2121
#include <linux/string.h>
22+
#include <sys/stat.h>
2223

2324
#include "debug.h"
2425
#include <subcmd/pager.h>
@@ -45,6 +46,8 @@ static volatile sig_atomic_t done;
4546

4647
static struct stats latency_stats; /* for tracepoints */
4748

49+
static char tracing_instance[PATH_MAX]; /* Trace instance directory */
50+
4851
static void sig_handler(int sig __maybe_unused)
4952
{
5053
done = true;
@@ -100,6 +103,34 @@ static bool is_ftrace_supported(void)
100103
return supported;
101104
}
102105

106+
/*
107+
* Wrapper to test if a file in directory .../tracing/instances/XXX
108+
* exists. If so return the .../tracing/instances/XXX file for use.
109+
* Otherwise the file exists only in directory .../tracing and
110+
* is applicable to all instances, for example file available_filter_functions.
111+
* Return that file name in this case.
112+
*
113+
* This functions works similar to get_tracing_file() and expects its caller
114+
* to free the returned file name.
115+
*
116+
* The global variable tracing_instance is set in init_tracing_instance()
117+
* called at the beginning to a process specific tracing subdirectory.
118+
*/
119+
static char *get_tracing_instance_file(const char *name)
120+
{
121+
char *file;
122+
123+
if (asprintf(&file, "%s/%s", tracing_instance, name) < 0)
124+
return NULL;
125+
126+
if (!access(file, F_OK))
127+
return file;
128+
129+
free(file);
130+
file = get_tracing_file(name);
131+
return file;
132+
}
133+
103134
static int __write_tracing_file(const char *name, const char *val, bool append)
104135
{
105136
char *file;
@@ -109,7 +140,7 @@ static int __write_tracing_file(const char *name, const char *val, bool append)
109140
char errbuf[512];
110141
char *val_copy;
111142

112-
file = get_tracing_file(name);
143+
file = get_tracing_instance_file(name);
113144
if (!file) {
114145
pr_debug("cannot get tracing file: %s\n", name);
115146
return -1;
@@ -167,7 +198,7 @@ static int read_tracing_file_to_stdout(const char *name)
167198
int fd;
168199
int ret = -1;
169200

170-
file = get_tracing_file(name);
201+
file = get_tracing_instance_file(name);
171202
if (!file) {
172203
pr_debug("cannot get tracing file: %s\n", name);
173204
return -1;
@@ -209,7 +240,7 @@ static int read_tracing_file_by_line(const char *name,
209240
char *file;
210241
FILE *fp;
211242

212-
file = get_tracing_file(name);
243+
file = get_tracing_instance_file(name);
213244
if (!file) {
214245
pr_debug("cannot get tracing file: %s\n", name);
215246
return -1;
@@ -299,6 +330,39 @@ static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused)
299330
return 0;
300331
}
301332

333+
/* Remove .../tracing/instances/XXX subdirectory created with
334+
* init_tracing_instance().
335+
*/
336+
static void exit_tracing_instance(void)
337+
{
338+
if (rmdir(tracing_instance))
339+
pr_err("failed to delete tracing/instances directory\n");
340+
}
341+
342+
/* Create subdirectory within .../tracing/instances/XXX to have session
343+
* or process specific setup. To delete this setup, simply remove the
344+
* subdirectory.
345+
*/
346+
static int init_tracing_instance(void)
347+
{
348+
char dirname[] = "instances/perf-ftrace-XXXXXX";
349+
char *path;
350+
351+
path = get_tracing_file(dirname);
352+
if (!path)
353+
goto error;
354+
strncpy(tracing_instance, path, sizeof(tracing_instance) - 1);
355+
put_tracing_file(path);
356+
path = mkdtemp(tracing_instance);
357+
if (!path)
358+
goto error;
359+
return 0;
360+
361+
error:
362+
pr_err("failed to create tracing/instances directory\n");
363+
return -1;
364+
}
365+
302366
static int set_tracing_pid(struct perf_ftrace *ftrace)
303367
{
304368
int i;
@@ -629,14 +693,17 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace)
629693

630694
select_tracer(ftrace);
631695

696+
if (init_tracing_instance() < 0)
697+
goto out;
698+
632699
if (reset_tracing_files(ftrace) < 0) {
633700
pr_err("failed to reset ftrace\n");
634-
goto out;
701+
goto out_reset;
635702
}
636703

637704
/* reset ftrace buffer */
638705
if (write_tracing_file("trace", "0") < 0)
639-
goto out;
706+
goto out_reset;
640707

641708
if (set_tracing_options(ftrace) < 0)
642709
goto out_reset;
@@ -648,7 +715,7 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace)
648715

649716
setup_pager();
650717

651-
trace_file = get_tracing_file("trace_pipe");
718+
trace_file = get_tracing_instance_file("trace_pipe");
652719
if (!trace_file) {
653720
pr_err("failed to open trace_pipe\n");
654721
goto out_reset;
@@ -723,7 +790,7 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace)
723790
out_close_fd:
724791
close(trace_fd);
725792
out_reset:
726-
reset_tracing_files(ftrace);
793+
exit_tracing_instance();
727794
out:
728795
return (done && !workload_exec_errno) ? 0 : -1;
729796
}
@@ -924,6 +991,9 @@ static int prepare_func_latency(struct perf_ftrace *ftrace)
924991
if (ftrace->target.use_bpf)
925992
return perf_ftrace__latency_prepare_bpf(ftrace);
926993

994+
if (init_tracing_instance() < 0)
995+
return -1;
996+
927997
if (reset_tracing_files(ftrace) < 0) {
928998
pr_err("failed to reset ftrace\n");
929999
return -1;
@@ -942,7 +1012,7 @@ static int prepare_func_latency(struct perf_ftrace *ftrace)
9421012
return -1;
9431013
}
9441014

945-
trace_file = get_tracing_file("trace_pipe");
1015+
trace_file = get_tracing_instance_file("trace_pipe");
9461016
if (!trace_file) {
9471017
pr_err("failed to open trace_pipe\n");
9481018
return -1;
@@ -993,7 +1063,7 @@ static int cleanup_func_latency(struct perf_ftrace *ftrace)
9931063
if (ftrace->target.use_bpf)
9941064
return perf_ftrace__latency_cleanup_bpf(ftrace);
9951065

996-
reset_tracing_files(ftrace);
1066+
exit_tracing_instance();
9971067
return 0;
9981068
}
9991069

@@ -1304,17 +1374,20 @@ static int __cmd_profile(struct perf_ftrace *ftrace)
13041374
goto out;
13051375
}
13061376

1377+
if (init_tracing_instance() < 0)
1378+
goto out;
1379+
13071380
if (reset_tracing_files(ftrace) < 0) {
13081381
pr_err("failed to reset ftrace\n");
1309-
goto out;
1382+
goto out_reset;
13101383
}
13111384

13121385
/* reset ftrace buffer */
13131386
if (write_tracing_file("trace", "0") < 0)
1314-
goto out;
1387+
goto out_reset;
13151388

13161389
if (set_tracing_options(ftrace) < 0)
1317-
return -1;
1390+
goto out_reset;
13181391

13191392
if (write_tracing_file("current_tracer", ftrace->tracer) < 0) {
13201393
pr_err("failed to set current_tracer to %s\n", ftrace->tracer);
@@ -1323,7 +1396,7 @@ static int __cmd_profile(struct perf_ftrace *ftrace)
13231396

13241397
setup_pager();
13251398

1326-
trace_file = get_tracing_file("trace_pipe");
1399+
trace_file = get_tracing_instance_file("trace_pipe");
13271400
if (!trace_file) {
13281401
pr_err("failed to open trace_pipe\n");
13291402
goto out_reset;
@@ -1385,7 +1458,7 @@ static int __cmd_profile(struct perf_ftrace *ftrace)
13851458
out_close_fd:
13861459
close(trace_fd);
13871460
out_reset:
1388-
reset_tracing_files(ftrace);
1461+
exit_tracing_instance();
13891462
out:
13901463
return (done && !workload_exec_errno) ? 0 : -1;
13911464
}

0 commit comments

Comments
 (0)