Skip to content

Commit b169637

Browse files
Daniel Bristot de Oliveirarostedt
authored andcommitted
rtla: Helper functions for rtla
This is a set of utils and tracer helper functions. They are used by rtla mostly to parse config, display data and some trace operations that are not part of libtracefs (because they are only useful it for this case). Link: https://lkml.kernel.org/r/a94c128aba9e6e66d502b7094f2e8c7ac95b12e5.1639158831.git.bristot@kernel.org Cc: Tao Zhou <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Tom Zanussi <[email protected]> Cc: Masami Hiramatsu <[email protected]> Cc: Juri Lelli <[email protected]> Cc: Clark Williams <[email protected]> Cc: John Kacur <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Sebastian Andrzej Siewior <[email protected]> Cc: Daniel Bristot de Oliveira <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Signed-off-by: Daniel Bristot de Oliveira <[email protected]> Signed-off-by: Steven Rostedt <[email protected]>
1 parent 79ce8f4 commit b169637

File tree

4 files changed

+708
-0
lines changed

4 files changed

+708
-0
lines changed

tools/tracing/rtla/src/trace.c

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#define _GNU_SOURCE
3+
#include <sys/sendfile.h>
4+
#include <tracefs.h>
5+
#include <signal.h>
6+
#include <stdlib.h>
7+
#include <unistd.h>
8+
#include <errno.h>
9+
10+
#include "trace.h"
11+
#include "utils.h"
12+
13+
/*
14+
* enable_tracer_by_name - enable a tracer on the given instance
15+
*/
16+
int enable_tracer_by_name(struct tracefs_instance *inst, const char *tracer_name)
17+
{
18+
enum tracefs_tracers tracer;
19+
int retval;
20+
21+
tracer = TRACEFS_TRACER_CUSTOM;
22+
23+
debug_msg("enabling %s tracer\n", tracer_name);
24+
25+
retval = tracefs_tracer_set(inst, tracer, tracer_name);
26+
if (retval < 0) {
27+
if (errno == ENODEV)
28+
err_msg("tracer %s not found!\n", tracer_name);
29+
30+
err_msg("failed to enable the tracer %s\n", tracer_name);
31+
return -1;
32+
}
33+
34+
return 0;
35+
}
36+
37+
/*
38+
* disable_tracer - set nop tracer to the insta
39+
*/
40+
void disable_tracer(struct tracefs_instance *inst)
41+
{
42+
enum tracefs_tracers t = TRACEFS_TRACER_NOP;
43+
int retval;
44+
45+
retval = tracefs_tracer_set(inst, t);
46+
if (retval < 0)
47+
err_msg("oops, error disabling tracer\n");
48+
}
49+
50+
/*
51+
* create_instance - create a trace instance with *instance_name
52+
*/
53+
struct tracefs_instance *create_instance(char *instance_name)
54+
{
55+
return tracefs_instance_create(instance_name);
56+
}
57+
58+
/*
59+
* destroy_instance - remove a trace instance and free the data
60+
*/
61+
void destroy_instance(struct tracefs_instance *inst)
62+
{
63+
tracefs_instance_destroy(inst);
64+
tracefs_instance_free(inst);
65+
}
66+
67+
/*
68+
* save_trace_to_file - save the trace output of the instance to the file
69+
*/
70+
int save_trace_to_file(struct tracefs_instance *inst, const char *filename)
71+
{
72+
const char *file = "trace";
73+
mode_t mode = 0644;
74+
char buffer[4096];
75+
int out_fd, in_fd;
76+
int retval = -1;
77+
78+
in_fd = tracefs_instance_file_open(inst, file, O_RDONLY);
79+
if (in_fd < 0) {
80+
err_msg("Failed to open trace file\n");
81+
return -1;
82+
}
83+
84+
out_fd = creat(filename, mode);
85+
if (out_fd < 0) {
86+
err_msg("Failed to create output file %s\n", filename);
87+
goto out_close_in;
88+
}
89+
90+
do {
91+
retval = read(in_fd, buffer, sizeof(buffer));
92+
if (retval <= 0)
93+
goto out_close;
94+
95+
retval = write(out_fd, buffer, retval);
96+
if (retval < 0)
97+
goto out_close;
98+
} while (retval > 0);
99+
100+
retval = 0;
101+
out_close:
102+
close(out_fd);
103+
out_close_in:
104+
close(in_fd);
105+
return retval;
106+
}
107+
108+
/*
109+
* collect_registered_events - call the existing callback function for the event
110+
*
111+
* If an event has a registered callback function, call it.
112+
* Otherwise, ignore the event.
113+
*/
114+
int
115+
collect_registered_events(struct tep_event *event, struct tep_record *record,
116+
int cpu, void *context)
117+
{
118+
struct trace_instance *trace = context;
119+
struct trace_seq *s = trace->seq;
120+
121+
if (!event->handler)
122+
return 0;
123+
124+
event->handler(s, record, event, context);
125+
126+
return 0;
127+
}
128+
129+
/*
130+
* trace_instance_destroy - destroy and free a rtla trace instance
131+
*/
132+
void trace_instance_destroy(struct trace_instance *trace)
133+
{
134+
if (trace->inst) {
135+
disable_tracer(trace->inst);
136+
destroy_instance(trace->inst);
137+
}
138+
139+
if (trace->seq)
140+
free(trace->seq);
141+
142+
if (trace->tep)
143+
tep_free(trace->tep);
144+
}
145+
146+
/*
147+
* trace_instance_init - create an rtla trace instance
148+
*
149+
* It is more than the tracefs instance, as it contains other
150+
* things required for the tracing, such as the local events and
151+
* a seq file.
152+
*
153+
* Note that the trace instance is returned disabled. This allows
154+
* the tool to apply some other configs, like setting priority
155+
* to the kernel threads, before starting generating trace entries.
156+
*/
157+
int trace_instance_init(struct trace_instance *trace, char *tool_name)
158+
{
159+
trace->seq = calloc(1, sizeof(*trace->seq));
160+
if (!trace->seq)
161+
goto out_err;
162+
163+
trace_seq_init(trace->seq);
164+
165+
trace->inst = create_instance(tool_name);
166+
if (!trace->inst)
167+
goto out_err;
168+
169+
trace->tep = tracefs_local_events(NULL);
170+
if (!trace->tep)
171+
goto out_err;
172+
173+
/*
174+
* Let the main enable the record after setting some other
175+
* things such as the priority of the tracer's threads.
176+
*/
177+
tracefs_trace_off(trace->inst);
178+
179+
return 0;
180+
181+
out_err:
182+
trace_instance_destroy(trace);
183+
return 1;
184+
}
185+
186+
/*
187+
* trace_instance_start - start tracing a given rtla instance
188+
*/
189+
int trace_instance_start(struct trace_instance *trace)
190+
{
191+
return tracefs_trace_on(trace->inst);
192+
}

tools/tracing/rtla/src/trace.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#include <tracefs.h>
3+
#include <stddef.h>
4+
5+
struct trace_instance {
6+
struct tracefs_instance *inst;
7+
struct tep_handle *tep;
8+
struct trace_seq *seq;
9+
};
10+
11+
int trace_instance_init(struct trace_instance *trace, char *tool_name);
12+
int trace_instance_start(struct trace_instance *trace);
13+
void trace_instance_destroy(struct trace_instance *trace);
14+
15+
struct trace_seq *get_trace_seq(void);
16+
int enable_tracer_by_name(struct tracefs_instance *inst, const char *tracer_name);
17+
void disable_tracer(struct tracefs_instance *inst);
18+
19+
int enable_osnoise(struct trace_instance *trace);
20+
int enable_timerlat(struct trace_instance *trace);
21+
22+
struct tracefs_instance *create_instance(char *instance_name);
23+
void destroy_instance(struct tracefs_instance *inst);
24+
25+
int save_trace_to_file(struct tracefs_instance *inst, const char *filename);
26+
int collect_registered_events(struct tep_event *tep, struct tep_record *record,
27+
int cpu, void *context);

0 commit comments

Comments
 (0)