xref: /openbmc/linux/tools/tracing/rtla/src/trace.c (revision 336c92b26cf9aee6c5d5907ef49b90d2665e9d70)
1b1696371SDaniel Bristot de Oliveira // SPDX-License-Identifier: GPL-2.0
2b1696371SDaniel Bristot de Oliveira #define _GNU_SOURCE
3b1696371SDaniel Bristot de Oliveira #include <sys/sendfile.h>
4b1696371SDaniel Bristot de Oliveira #include <tracefs.h>
5b1696371SDaniel Bristot de Oliveira #include <signal.h>
6b1696371SDaniel Bristot de Oliveira #include <stdlib.h>
7b1696371SDaniel Bristot de Oliveira #include <unistd.h>
8b1696371SDaniel Bristot de Oliveira #include <errno.h>
9b1696371SDaniel Bristot de Oliveira 
10b1696371SDaniel Bristot de Oliveira #include "trace.h"
11b1696371SDaniel Bristot de Oliveira #include "utils.h"
12b1696371SDaniel Bristot de Oliveira 
13b1696371SDaniel Bristot de Oliveira /*
14b1696371SDaniel Bristot de Oliveira  * enable_tracer_by_name - enable a tracer on the given instance
15b1696371SDaniel Bristot de Oliveira  */
16b1696371SDaniel Bristot de Oliveira int enable_tracer_by_name(struct tracefs_instance *inst, const char *tracer_name)
17b1696371SDaniel Bristot de Oliveira {
18b1696371SDaniel Bristot de Oliveira 	enum tracefs_tracers tracer;
19b1696371SDaniel Bristot de Oliveira 	int retval;
20b1696371SDaniel Bristot de Oliveira 
21b1696371SDaniel Bristot de Oliveira 	tracer = TRACEFS_TRACER_CUSTOM;
22b1696371SDaniel Bristot de Oliveira 
231a622909SDaniel Bristot de Oliveira 	debug_msg("Enabling %s tracer\n", tracer_name);
24b1696371SDaniel Bristot de Oliveira 
25b1696371SDaniel Bristot de Oliveira 	retval = tracefs_tracer_set(inst, tracer, tracer_name);
26b1696371SDaniel Bristot de Oliveira 	if (retval < 0) {
27b1696371SDaniel Bristot de Oliveira 		if (errno == ENODEV)
281a622909SDaniel Bristot de Oliveira 			err_msg("Tracer %s not found!\n", tracer_name);
29b1696371SDaniel Bristot de Oliveira 
301a622909SDaniel Bristot de Oliveira 		err_msg("Failed to enable the %s tracer\n", tracer_name);
31b1696371SDaniel Bristot de Oliveira 		return -1;
32b1696371SDaniel Bristot de Oliveira 	}
33b1696371SDaniel Bristot de Oliveira 
34b1696371SDaniel Bristot de Oliveira 	return 0;
35b1696371SDaniel Bristot de Oliveira }
36b1696371SDaniel Bristot de Oliveira 
37b1696371SDaniel Bristot de Oliveira /*
38b1696371SDaniel Bristot de Oliveira  * disable_tracer - set nop tracer to the insta
39b1696371SDaniel Bristot de Oliveira  */
40b1696371SDaniel Bristot de Oliveira void disable_tracer(struct tracefs_instance *inst)
41b1696371SDaniel Bristot de Oliveira {
42b1696371SDaniel Bristot de Oliveira 	enum tracefs_tracers t = TRACEFS_TRACER_NOP;
43b1696371SDaniel Bristot de Oliveira 	int retval;
44b1696371SDaniel Bristot de Oliveira 
45b1696371SDaniel Bristot de Oliveira 	retval = tracefs_tracer_set(inst, t);
46b1696371SDaniel Bristot de Oliveira 	if (retval < 0)
471a622909SDaniel Bristot de Oliveira 		err_msg("Oops, error disabling tracer\n");
48b1696371SDaniel Bristot de Oliveira }
49b1696371SDaniel Bristot de Oliveira 
50b1696371SDaniel Bristot de Oliveira /*
51b1696371SDaniel Bristot de Oliveira  * create_instance - create a trace instance with *instance_name
52b1696371SDaniel Bristot de Oliveira  */
53b1696371SDaniel Bristot de Oliveira struct tracefs_instance *create_instance(char *instance_name)
54b1696371SDaniel Bristot de Oliveira {
55b1696371SDaniel Bristot de Oliveira 	return tracefs_instance_create(instance_name);
56b1696371SDaniel Bristot de Oliveira }
57b1696371SDaniel Bristot de Oliveira 
58b1696371SDaniel Bristot de Oliveira /*
59b1696371SDaniel Bristot de Oliveira  * destroy_instance - remove a trace instance and free the data
60b1696371SDaniel Bristot de Oliveira  */
61b1696371SDaniel Bristot de Oliveira void destroy_instance(struct tracefs_instance *inst)
62b1696371SDaniel Bristot de Oliveira {
63b1696371SDaniel Bristot de Oliveira 	tracefs_instance_destroy(inst);
64b1696371SDaniel Bristot de Oliveira 	tracefs_instance_free(inst);
65b1696371SDaniel Bristot de Oliveira }
66b1696371SDaniel Bristot de Oliveira 
67b1696371SDaniel Bristot de Oliveira /*
68b1696371SDaniel Bristot de Oliveira  * save_trace_to_file - save the trace output of the instance to the file
69b1696371SDaniel Bristot de Oliveira  */
70b1696371SDaniel Bristot de Oliveira int save_trace_to_file(struct tracefs_instance *inst, const char *filename)
71b1696371SDaniel Bristot de Oliveira {
72b1696371SDaniel Bristot de Oliveira 	const char *file = "trace";
73b1696371SDaniel Bristot de Oliveira 	mode_t mode = 0644;
74b1696371SDaniel Bristot de Oliveira 	char buffer[4096];
75b1696371SDaniel Bristot de Oliveira 	int out_fd, in_fd;
76b1696371SDaniel Bristot de Oliveira 	int retval = -1;
77b1696371SDaniel Bristot de Oliveira 
78b1696371SDaniel Bristot de Oliveira 	in_fd = tracefs_instance_file_open(inst, file, O_RDONLY);
79b1696371SDaniel Bristot de Oliveira 	if (in_fd < 0) {
80b1696371SDaniel Bristot de Oliveira 		err_msg("Failed to open trace file\n");
81b1696371SDaniel Bristot de Oliveira 		return -1;
82b1696371SDaniel Bristot de Oliveira 	}
83b1696371SDaniel Bristot de Oliveira 
84b1696371SDaniel Bristot de Oliveira 	out_fd = creat(filename, mode);
85b1696371SDaniel Bristot de Oliveira 	if (out_fd < 0) {
86b1696371SDaniel Bristot de Oliveira 		err_msg("Failed to create output file %s\n", filename);
87b1696371SDaniel Bristot de Oliveira 		goto out_close_in;
88b1696371SDaniel Bristot de Oliveira 	}
89b1696371SDaniel Bristot de Oliveira 
90b1696371SDaniel Bristot de Oliveira 	do {
91b1696371SDaniel Bristot de Oliveira 		retval = read(in_fd, buffer, sizeof(buffer));
92b1696371SDaniel Bristot de Oliveira 		if (retval <= 0)
93b1696371SDaniel Bristot de Oliveira 			goto out_close;
94b1696371SDaniel Bristot de Oliveira 
95b1696371SDaniel Bristot de Oliveira 		retval = write(out_fd, buffer, retval);
96b1696371SDaniel Bristot de Oliveira 		if (retval < 0)
97b1696371SDaniel Bristot de Oliveira 			goto out_close;
98b1696371SDaniel Bristot de Oliveira 	} while (retval > 0);
99b1696371SDaniel Bristot de Oliveira 
100b1696371SDaniel Bristot de Oliveira 	retval = 0;
101b1696371SDaniel Bristot de Oliveira out_close:
102b1696371SDaniel Bristot de Oliveira 	close(out_fd);
103b1696371SDaniel Bristot de Oliveira out_close_in:
104b1696371SDaniel Bristot de Oliveira 	close(in_fd);
105b1696371SDaniel Bristot de Oliveira 	return retval;
106b1696371SDaniel Bristot de Oliveira }
107b1696371SDaniel Bristot de Oliveira 
108b1696371SDaniel Bristot de Oliveira /*
109b1696371SDaniel Bristot de Oliveira  * collect_registered_events - call the existing callback function for the event
110b1696371SDaniel Bristot de Oliveira  *
111b1696371SDaniel Bristot de Oliveira  * If an event has a registered callback function, call it.
112b1696371SDaniel Bristot de Oliveira  * Otherwise, ignore the event.
113b1696371SDaniel Bristot de Oliveira  */
114b1696371SDaniel Bristot de Oliveira int
115b1696371SDaniel Bristot de Oliveira collect_registered_events(struct tep_event *event, struct tep_record *record,
116b1696371SDaniel Bristot de Oliveira 			  int cpu, void *context)
117b1696371SDaniel Bristot de Oliveira {
118b1696371SDaniel Bristot de Oliveira 	struct trace_instance *trace = context;
119b1696371SDaniel Bristot de Oliveira 	struct trace_seq *s = trace->seq;
120b1696371SDaniel Bristot de Oliveira 
121b1696371SDaniel Bristot de Oliveira 	if (!event->handler)
122b1696371SDaniel Bristot de Oliveira 		return 0;
123b1696371SDaniel Bristot de Oliveira 
124b1696371SDaniel Bristot de Oliveira 	event->handler(s, record, event, context);
125b1696371SDaniel Bristot de Oliveira 
126b1696371SDaniel Bristot de Oliveira 	return 0;
127b1696371SDaniel Bristot de Oliveira }
128b1696371SDaniel Bristot de Oliveira 
129b1696371SDaniel Bristot de Oliveira /*
130b1696371SDaniel Bristot de Oliveira  * trace_instance_destroy - destroy and free a rtla trace instance
131b1696371SDaniel Bristot de Oliveira  */
132b1696371SDaniel Bristot de Oliveira void trace_instance_destroy(struct trace_instance *trace)
133b1696371SDaniel Bristot de Oliveira {
134b1696371SDaniel Bristot de Oliveira 	if (trace->inst) {
135b1696371SDaniel Bristot de Oliveira 		disable_tracer(trace->inst);
136b1696371SDaniel Bristot de Oliveira 		destroy_instance(trace->inst);
137b1696371SDaniel Bristot de Oliveira 	}
138b1696371SDaniel Bristot de Oliveira 
139b1696371SDaniel Bristot de Oliveira 	if (trace->seq)
140b1696371SDaniel Bristot de Oliveira 		free(trace->seq);
141b1696371SDaniel Bristot de Oliveira 
142b1696371SDaniel Bristot de Oliveira 	if (trace->tep)
143b1696371SDaniel Bristot de Oliveira 		tep_free(trace->tep);
144b1696371SDaniel Bristot de Oliveira }
145b1696371SDaniel Bristot de Oliveira 
146b1696371SDaniel Bristot de Oliveira /*
147b1696371SDaniel Bristot de Oliveira  * trace_instance_init - create an rtla trace instance
148b1696371SDaniel Bristot de Oliveira  *
149b1696371SDaniel Bristot de Oliveira  * It is more than the tracefs instance, as it contains other
150b1696371SDaniel Bristot de Oliveira  * things required for the tracing, such as the local events and
151b1696371SDaniel Bristot de Oliveira  * a seq file.
152b1696371SDaniel Bristot de Oliveira  *
153b1696371SDaniel Bristot de Oliveira  * Note that the trace instance is returned disabled. This allows
154b1696371SDaniel Bristot de Oliveira  * the tool to apply some other configs, like setting priority
155b1696371SDaniel Bristot de Oliveira  * to the kernel threads, before starting generating trace entries.
156b1696371SDaniel Bristot de Oliveira  */
157b1696371SDaniel Bristot de Oliveira int trace_instance_init(struct trace_instance *trace, char *tool_name)
158b1696371SDaniel Bristot de Oliveira {
159b1696371SDaniel Bristot de Oliveira 	trace->seq = calloc(1, sizeof(*trace->seq));
160b1696371SDaniel Bristot de Oliveira 	if (!trace->seq)
161b1696371SDaniel Bristot de Oliveira 		goto out_err;
162b1696371SDaniel Bristot de Oliveira 
163b1696371SDaniel Bristot de Oliveira 	trace_seq_init(trace->seq);
164b1696371SDaniel Bristot de Oliveira 
165b1696371SDaniel Bristot de Oliveira 	trace->inst = create_instance(tool_name);
166b1696371SDaniel Bristot de Oliveira 	if (!trace->inst)
167b1696371SDaniel Bristot de Oliveira 		goto out_err;
168b1696371SDaniel Bristot de Oliveira 
169b1696371SDaniel Bristot de Oliveira 	trace->tep = tracefs_local_events(NULL);
170b1696371SDaniel Bristot de Oliveira 	if (!trace->tep)
171b1696371SDaniel Bristot de Oliveira 		goto out_err;
172b1696371SDaniel Bristot de Oliveira 
173b1696371SDaniel Bristot de Oliveira 	/*
174b1696371SDaniel Bristot de Oliveira 	 * Let the main enable the record after setting some other
175b1696371SDaniel Bristot de Oliveira 	 * things such as the priority of the tracer's threads.
176b1696371SDaniel Bristot de Oliveira 	 */
177b1696371SDaniel Bristot de Oliveira 	tracefs_trace_off(trace->inst);
178b1696371SDaniel Bristot de Oliveira 
179b1696371SDaniel Bristot de Oliveira 	return 0;
180b1696371SDaniel Bristot de Oliveira 
181b1696371SDaniel Bristot de Oliveira out_err:
182b1696371SDaniel Bristot de Oliveira 	trace_instance_destroy(trace);
183b1696371SDaniel Bristot de Oliveira 	return 1;
184b1696371SDaniel Bristot de Oliveira }
185b1696371SDaniel Bristot de Oliveira 
186b1696371SDaniel Bristot de Oliveira /*
187b1696371SDaniel Bristot de Oliveira  * trace_instance_start - start tracing a given rtla instance
188b1696371SDaniel Bristot de Oliveira  */
189b1696371SDaniel Bristot de Oliveira int trace_instance_start(struct trace_instance *trace)
190b1696371SDaniel Bristot de Oliveira {
191b1696371SDaniel Bristot de Oliveira 	return tracefs_trace_on(trace->inst);
192b1696371SDaniel Bristot de Oliveira }
193b5aa0be2SDaniel Bristot de Oliveira 
194b5aa0be2SDaniel Bristot de Oliveira /*
195b5aa0be2SDaniel Bristot de Oliveira  * trace_events_free - free a list of trace events
196b5aa0be2SDaniel Bristot de Oliveira  */
197b5aa0be2SDaniel Bristot de Oliveira static void trace_events_free(struct trace_events *events)
198b5aa0be2SDaniel Bristot de Oliveira {
199b5aa0be2SDaniel Bristot de Oliveira 	struct trace_events *tevent = events;
200b5aa0be2SDaniel Bristot de Oliveira 	struct trace_events *free_event;
201b5aa0be2SDaniel Bristot de Oliveira 
202b5aa0be2SDaniel Bristot de Oliveira 	while (tevent) {
203b5aa0be2SDaniel Bristot de Oliveira 		free_event = tevent;
204b5aa0be2SDaniel Bristot de Oliveira 
205b5aa0be2SDaniel Bristot de Oliveira 		tevent = tevent->next;
206b5aa0be2SDaniel Bristot de Oliveira 
207*336c92b2SDaniel Bristot de Oliveira 		if (free_event->trigger)
208*336c92b2SDaniel Bristot de Oliveira 			free(free_event->trigger);
209b5aa0be2SDaniel Bristot de Oliveira 		free(free_event->system);
210b5aa0be2SDaniel Bristot de Oliveira 		free(free_event);
211b5aa0be2SDaniel Bristot de Oliveira 	}
212b5aa0be2SDaniel Bristot de Oliveira }
213b5aa0be2SDaniel Bristot de Oliveira 
214b5aa0be2SDaniel Bristot de Oliveira /*
215b5aa0be2SDaniel Bristot de Oliveira  * trace_event_alloc - alloc and parse a single trace event
216b5aa0be2SDaniel Bristot de Oliveira  */
217b5aa0be2SDaniel Bristot de Oliveira struct trace_events *trace_event_alloc(const char *event_string)
218b5aa0be2SDaniel Bristot de Oliveira {
219b5aa0be2SDaniel Bristot de Oliveira 	struct trace_events *tevent;
220b5aa0be2SDaniel Bristot de Oliveira 
221b5aa0be2SDaniel Bristot de Oliveira 	tevent = calloc(1, sizeof(*tevent));
222b5aa0be2SDaniel Bristot de Oliveira 	if (!tevent)
223b5aa0be2SDaniel Bristot de Oliveira 		return NULL;
224b5aa0be2SDaniel Bristot de Oliveira 
225b5aa0be2SDaniel Bristot de Oliveira 	tevent->system = strdup(event_string);
226b5aa0be2SDaniel Bristot de Oliveira 	if (!tevent->system) {
227b5aa0be2SDaniel Bristot de Oliveira 		free(tevent);
228b5aa0be2SDaniel Bristot de Oliveira 		return NULL;
229b5aa0be2SDaniel Bristot de Oliveira 	}
230b5aa0be2SDaniel Bristot de Oliveira 
231b5aa0be2SDaniel Bristot de Oliveira 	tevent->event = strstr(tevent->system, ":");
232b5aa0be2SDaniel Bristot de Oliveira 	if (tevent->event) {
233b5aa0be2SDaniel Bristot de Oliveira 		*tevent->event = '\0';
234b5aa0be2SDaniel Bristot de Oliveira 		tevent->event = &tevent->event[1];
235b5aa0be2SDaniel Bristot de Oliveira 	}
236b5aa0be2SDaniel Bristot de Oliveira 
237b5aa0be2SDaniel Bristot de Oliveira 	return tevent;
238b5aa0be2SDaniel Bristot de Oliveira }
239b5aa0be2SDaniel Bristot de Oliveira 
240b5aa0be2SDaniel Bristot de Oliveira /*
241*336c92b2SDaniel Bristot de Oliveira  * trace_event_add_trigger - record an event trigger action
242*336c92b2SDaniel Bristot de Oliveira  */
243*336c92b2SDaniel Bristot de Oliveira int trace_event_add_trigger(struct trace_events *event, char *trigger)
244*336c92b2SDaniel Bristot de Oliveira {
245*336c92b2SDaniel Bristot de Oliveira 	if (event->trigger)
246*336c92b2SDaniel Bristot de Oliveira 		free(event->trigger);
247*336c92b2SDaniel Bristot de Oliveira 
248*336c92b2SDaniel Bristot de Oliveira 	event->trigger = strdup(trigger);
249*336c92b2SDaniel Bristot de Oliveira 	if (!event->trigger)
250*336c92b2SDaniel Bristot de Oliveira 		return 1;
251*336c92b2SDaniel Bristot de Oliveira 
252*336c92b2SDaniel Bristot de Oliveira 	return 0;
253*336c92b2SDaniel Bristot de Oliveira }
254*336c92b2SDaniel Bristot de Oliveira 
255*336c92b2SDaniel Bristot de Oliveira /*
256*336c92b2SDaniel Bristot de Oliveira  * trace_event_disable_trigger - disable an event trigger
257*336c92b2SDaniel Bristot de Oliveira  */
258*336c92b2SDaniel Bristot de Oliveira static void trace_event_disable_trigger(struct trace_instance *instance,
259*336c92b2SDaniel Bristot de Oliveira 					struct trace_events *tevent)
260*336c92b2SDaniel Bristot de Oliveira {
261*336c92b2SDaniel Bristot de Oliveira 	char trigger[1024];
262*336c92b2SDaniel Bristot de Oliveira 	int retval;
263*336c92b2SDaniel Bristot de Oliveira 
264*336c92b2SDaniel Bristot de Oliveira 	if (!tevent->trigger)
265*336c92b2SDaniel Bristot de Oliveira 		return;
266*336c92b2SDaniel Bristot de Oliveira 
267*336c92b2SDaniel Bristot de Oliveira 	if (!tevent->trigger_enabled)
268*336c92b2SDaniel Bristot de Oliveira 		return;
269*336c92b2SDaniel Bristot de Oliveira 
270*336c92b2SDaniel Bristot de Oliveira 	debug_msg("Disabling %s:%s trigger %s\n", tevent->system,
271*336c92b2SDaniel Bristot de Oliveira 		  tevent->event ? : "*", tevent->trigger);
272*336c92b2SDaniel Bristot de Oliveira 
273*336c92b2SDaniel Bristot de Oliveira 	snprintf(trigger, 1024, "!%s\n", tevent->trigger);
274*336c92b2SDaniel Bristot de Oliveira 
275*336c92b2SDaniel Bristot de Oliveira 	retval = tracefs_event_file_write(instance->inst, tevent->system,
276*336c92b2SDaniel Bristot de Oliveira 					  tevent->event, "trigger", trigger);
277*336c92b2SDaniel Bristot de Oliveira 	if (retval < 0)
278*336c92b2SDaniel Bristot de Oliveira 		err_msg("Error disabling %s:%s trigger %s\n", tevent->system,
279*336c92b2SDaniel Bristot de Oliveira 			tevent->event ? : "*", tevent->trigger);
280*336c92b2SDaniel Bristot de Oliveira }
281*336c92b2SDaniel Bristot de Oliveira 
282*336c92b2SDaniel Bristot de Oliveira /*
283b5aa0be2SDaniel Bristot de Oliveira  * trace_events_disable - disable all trace events
284b5aa0be2SDaniel Bristot de Oliveira  */
285b5aa0be2SDaniel Bristot de Oliveira void trace_events_disable(struct trace_instance *instance,
286b5aa0be2SDaniel Bristot de Oliveira 			  struct trace_events *events)
287b5aa0be2SDaniel Bristot de Oliveira {
288b5aa0be2SDaniel Bristot de Oliveira 	struct trace_events *tevent = events;
289b5aa0be2SDaniel Bristot de Oliveira 
290b5aa0be2SDaniel Bristot de Oliveira 	if (!events)
291b5aa0be2SDaniel Bristot de Oliveira 		return;
292b5aa0be2SDaniel Bristot de Oliveira 
293b5aa0be2SDaniel Bristot de Oliveira 	while (tevent) {
294b5aa0be2SDaniel Bristot de Oliveira 		debug_msg("Disabling event %s:%s\n", tevent->system, tevent->event ? : "*");
295*336c92b2SDaniel Bristot de Oliveira 		if (tevent->enabled) {
296*336c92b2SDaniel Bristot de Oliveira 			trace_event_disable_trigger(instance, tevent);
297b5aa0be2SDaniel Bristot de Oliveira 			tracefs_event_disable(instance->inst, tevent->system, tevent->event);
298*336c92b2SDaniel Bristot de Oliveira 		}
299b5aa0be2SDaniel Bristot de Oliveira 
300b5aa0be2SDaniel Bristot de Oliveira 		tevent->enabled = 0;
301b5aa0be2SDaniel Bristot de Oliveira 		tevent = tevent->next;
302b5aa0be2SDaniel Bristot de Oliveira 	}
303b5aa0be2SDaniel Bristot de Oliveira }
304b5aa0be2SDaniel Bristot de Oliveira 
305b5aa0be2SDaniel Bristot de Oliveira /*
306*336c92b2SDaniel Bristot de Oliveira  * trace_event_enable_trigger - enable an event trigger associated with an event
307*336c92b2SDaniel Bristot de Oliveira  */
308*336c92b2SDaniel Bristot de Oliveira static int trace_event_enable_trigger(struct trace_instance *instance,
309*336c92b2SDaniel Bristot de Oliveira 				      struct trace_events *tevent)
310*336c92b2SDaniel Bristot de Oliveira {
311*336c92b2SDaniel Bristot de Oliveira 	char trigger[1024];
312*336c92b2SDaniel Bristot de Oliveira 	int retval;
313*336c92b2SDaniel Bristot de Oliveira 
314*336c92b2SDaniel Bristot de Oliveira 	if (!tevent->trigger)
315*336c92b2SDaniel Bristot de Oliveira 		return 0;
316*336c92b2SDaniel Bristot de Oliveira 
317*336c92b2SDaniel Bristot de Oliveira 	if (!tevent->event) {
318*336c92b2SDaniel Bristot de Oliveira 		err_msg("Trigger %s applies only for single events, not for all %s:* events\n",
319*336c92b2SDaniel Bristot de Oliveira 			tevent->trigger, tevent->system);
320*336c92b2SDaniel Bristot de Oliveira 		return 1;
321*336c92b2SDaniel Bristot de Oliveira 	}
322*336c92b2SDaniel Bristot de Oliveira 
323*336c92b2SDaniel Bristot de Oliveira 	snprintf(trigger, 1024, "%s\n", tevent->trigger);
324*336c92b2SDaniel Bristot de Oliveira 
325*336c92b2SDaniel Bristot de Oliveira 	debug_msg("Enabling %s:%s trigger %s\n", tevent->system,
326*336c92b2SDaniel Bristot de Oliveira 		  tevent->event ? : "*", tevent->trigger);
327*336c92b2SDaniel Bristot de Oliveira 
328*336c92b2SDaniel Bristot de Oliveira 	retval = tracefs_event_file_write(instance->inst, tevent->system,
329*336c92b2SDaniel Bristot de Oliveira 					  tevent->event, "trigger", trigger);
330*336c92b2SDaniel Bristot de Oliveira 	if (retval < 0) {
331*336c92b2SDaniel Bristot de Oliveira 		err_msg("Error enabling %s:%s trigger %s\n", tevent->system,
332*336c92b2SDaniel Bristot de Oliveira 			tevent->event ? : "*", tevent->trigger);
333*336c92b2SDaniel Bristot de Oliveira 		return 1;
334*336c92b2SDaniel Bristot de Oliveira 	}
335*336c92b2SDaniel Bristot de Oliveira 
336*336c92b2SDaniel Bristot de Oliveira 	tevent->trigger_enabled = 1;
337*336c92b2SDaniel Bristot de Oliveira 
338*336c92b2SDaniel Bristot de Oliveira 	return 0;
339*336c92b2SDaniel Bristot de Oliveira }
340*336c92b2SDaniel Bristot de Oliveira 
341*336c92b2SDaniel Bristot de Oliveira /*
342b5aa0be2SDaniel Bristot de Oliveira  * trace_events_enable - enable all events
343b5aa0be2SDaniel Bristot de Oliveira  */
344b5aa0be2SDaniel Bristot de Oliveira int trace_events_enable(struct trace_instance *instance,
345b5aa0be2SDaniel Bristot de Oliveira 			struct trace_events *events)
346b5aa0be2SDaniel Bristot de Oliveira {
347b5aa0be2SDaniel Bristot de Oliveira 	struct trace_events *tevent = events;
348b5aa0be2SDaniel Bristot de Oliveira 	int retval;
349b5aa0be2SDaniel Bristot de Oliveira 
350b5aa0be2SDaniel Bristot de Oliveira 	while (tevent) {
351b5aa0be2SDaniel Bristot de Oliveira 		debug_msg("Enabling event %s:%s\n", tevent->system, tevent->event ? : "*");
352b5aa0be2SDaniel Bristot de Oliveira 		retval = tracefs_event_enable(instance->inst, tevent->system, tevent->event);
353b5aa0be2SDaniel Bristot de Oliveira 		if (retval < 0) {
354b5aa0be2SDaniel Bristot de Oliveira 			err_msg("Error enabling event %s:%s\n", tevent->system,
355b5aa0be2SDaniel Bristot de Oliveira 				tevent->event ? : "*");
356b5aa0be2SDaniel Bristot de Oliveira 			return 1;
357b5aa0be2SDaniel Bristot de Oliveira 		}
358b5aa0be2SDaniel Bristot de Oliveira 
359b5aa0be2SDaniel Bristot de Oliveira 
360*336c92b2SDaniel Bristot de Oliveira 		retval = trace_event_enable_trigger(instance, tevent);
361*336c92b2SDaniel Bristot de Oliveira 		if (retval)
362*336c92b2SDaniel Bristot de Oliveira 			return 1;
363*336c92b2SDaniel Bristot de Oliveira 
364b5aa0be2SDaniel Bristot de Oliveira 		tevent->enabled = 1;
365b5aa0be2SDaniel Bristot de Oliveira 		tevent = tevent->next;
366b5aa0be2SDaniel Bristot de Oliveira 	}
367b5aa0be2SDaniel Bristot de Oliveira 
368b5aa0be2SDaniel Bristot de Oliveira 	return 0;
369b5aa0be2SDaniel Bristot de Oliveira }
370b5aa0be2SDaniel Bristot de Oliveira 
371b5aa0be2SDaniel Bristot de Oliveira /*
372b5aa0be2SDaniel Bristot de Oliveira  * trace_events_destroy - disable and free all trace events
373b5aa0be2SDaniel Bristot de Oliveira  */
374b5aa0be2SDaniel Bristot de Oliveira void trace_events_destroy(struct trace_instance *instance,
375b5aa0be2SDaniel Bristot de Oliveira 			  struct trace_events *events)
376b5aa0be2SDaniel Bristot de Oliveira {
377b5aa0be2SDaniel Bristot de Oliveira 	if (!events)
378b5aa0be2SDaniel Bristot de Oliveira 		return;
379b5aa0be2SDaniel Bristot de Oliveira 
380b5aa0be2SDaniel Bristot de Oliveira 	trace_events_disable(instance, events);
381b5aa0be2SDaniel Bristot de Oliveira 	trace_events_free(events);
382b5aa0be2SDaniel Bristot de Oliveira }
383