summaryrefslogtreecommitdiffstats
path: root/include/tracefs.h
blob: 3547b5a348aa3ff003044298ca263c957ff15c33 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
/* SPDX-License-Identifier: LGPL-2.1 */
/*
 * Copyright (C) 2019, VMware, Tzvetomir Stoyanov <tz.stoyanov@gmail.com>
 *
 */
#ifndef _TRACE_FS_H
#define _TRACE_FS_H

#include <fcntl.h>
#include <sched.h>
#include <event-parse.h>

char *tracefs_get_tracing_file(const char *name);
void tracefs_put_tracing_file(char *name);

/* the returned string must *not* be freed */
const char *tracefs_tracing_dir(void);
const char *tracefs_debug_dir(void);
int tracefs_set_tracing_dir(char *tracing_dir);
int tracefs_tracing_dir_is_mounted(bool mount, const char **path);

/* ftrace instances */
struct tracefs_instance;

void tracefs_instance_free(struct tracefs_instance *instance);
struct tracefs_instance *tracefs_instance_create(const char *name);
struct tracefs_instance *tracefs_instance_alloc(const char *tracing_dir,
						const char *name);
int tracefs_instance_destroy(struct tracefs_instance *instance);
bool tracefs_instance_is_new(struct tracefs_instance *instance);
const char *tracefs_instance_get_name(struct tracefs_instance *instance);
const char *tracefs_instance_get_trace_dir(struct tracefs_instance *instance);
char *
tracefs_instance_get_file(struct tracefs_instance *instance, const char *file);
char *tracefs_instance_get_dir(struct tracefs_instance *instance);
int tracefs_instance_file_write(struct tracefs_instance *instance,
				const char *file, const char *str);
int tracefs_instance_file_append(struct tracefs_instance *instance,
				 const char *file, const char *str);
int tracefs_instance_file_clear(struct tracefs_instance *instance,
				const char *file);
char *tracefs_instance_file_read(struct tracefs_instance *instance,
				 const char *file, int *psize);
int tracefs_instance_file_read_number(struct tracefs_instance *instance,
				      const char *file, long long *res);
int tracefs_instance_file_open(struct tracefs_instance *instance,
			       const char *file, int mode);
int tracefs_instances_walk(int (*callback)(const char *, void *), void *context);
int tracefs_instance_set_affinity_set(struct tracefs_instance *instance,
				  cpu_set_t *set, size_t set_size);
int tracefs_instance_set_affinity_raw(struct tracefs_instance *instance,
				      const char *mask);
int tracefs_instance_set_affinity(struct tracefs_instance *instance,
				  const char *cpu_str);
char *tracefs_instance_get_affinity(struct tracefs_instance *instance);
char *tracefs_instance_get_affinity_raw(struct tracefs_instance *instance);
int tracefs_instance_get_affinity_set(struct tracefs_instance *instance,
				      cpu_set_t *set, size_t set_size);
ssize_t tracefs_instance_get_buffer_size(struct tracefs_instance *instance, int cpu);
int tracefs_instance_set_buffer_size(struct tracefs_instance *instance, size_t size, int cpu);
char **tracefs_instances(const char *regex);

bool tracefs_instance_exists(const char *name);
bool tracefs_file_exists(struct tracefs_instance *instance, const char *name);
bool tracefs_dir_exists(struct tracefs_instance *instance, const char *name);

int tracefs_trace_is_on(struct tracefs_instance *instance);
int tracefs_trace_on(struct tracefs_instance *instance);
int tracefs_trace_off(struct tracefs_instance *instance);
int tracefs_trace_on_fd(int fd);
int tracefs_trace_off_fd(int fd);

enum tracefs_enable_state {
	TRACEFS_ERROR		= -1,
	TRACEFS_ALL_DISABLED	= 0,
	TRACEFS_ALL_ENABLED	= 1,
	TRACEFS_SOME_ENABLED	= 2,
};

int tracefs_event_enable(struct tracefs_instance *instance, const char *system, const char *event);
int tracefs_event_disable(struct tracefs_instance *instance, const char *system, const char *event);
enum tracefs_enable_state tracefs_event_is_enabled(struct tracefs_instance *instance,
			 const char *system, const char *event);

char *tracefs_error_last(struct tracefs_instance *instance);
char *tracefs_error_all(struct tracefs_instance *instance);
int tracefs_error_clear(struct tracefs_instance *instance);

void tracefs_list_free(char **list);
char **tracefs_list_add(char **list, const char *string);
int tracefs_list_size(char **list);

bool tracefs_tracer_available(const char *tracing_dir, const char *tracer);

/**
 * tracefs_trace_on_get_fd - Get a file descriptor of "tracing_on" in given instance
 * @instance: ftrace instance, can be NULL for the top instance
 *
 * Returns -1 in case of an error, or a valid file descriptor to "tracing_on"
 * file for reading and writing.The returned FD must be closed with close().
 */
static inline int tracefs_trace_on_get_fd(struct tracefs_instance *instance)
{
	return tracefs_instance_file_open(instance, "tracing_on", O_RDWR);
}

/* trace print string*/
int tracefs_print_init(struct tracefs_instance *instance);
int tracefs_printf(struct tracefs_instance *instance, const char *fmt, ...);
int tracefs_vprintf(struct tracefs_instance *instance, const char *fmt, va_list ap);
void tracefs_print_close(struct tracefs_instance *instance);

/* trace write binary data*/
int tracefs_binary_init(struct tracefs_instance *instance);
int tracefs_binary_write(struct tracefs_instance *instance, void *data, int len);
void tracefs_binary_close(struct tracefs_instance *instance);

/* events */
char **tracefs_event_systems(const char *tracing_dir);
char **tracefs_system_events(const char *tracing_dir, const char *system);
int tracefs_iterate_raw_events(struct tep_handle *tep,
				struct tracefs_instance *instance,
				cpu_set_t *cpus, int cpu_size,
				int (*callback)(struct tep_event *,
						struct tep_record *,
						int, void *),
				void *callback_context);
void tracefs_iterate_stop(struct tracefs_instance *instance);
int tracefs_follow_event(struct tep_handle *tep, struct tracefs_instance *instance,
			  const char *system, const char *event_name,
			  int (*callback)(struct tep_event *,
					  struct tep_record *,
					  int, void *),
			  void *callback_data);
int tracefs_follow_missed_events(struct tracefs_instance *instance,
				 int (*callback)(struct tep_event *,
						 struct tep_record *,
						 int, void *),
				 void *callback_data);

char *tracefs_event_get_file(struct tracefs_instance *instance,
			     const char *system, const char *event,
			     const char *file);
char *tracefs_event_file_read(struct tracefs_instance *instance,
			      const char *system, const char *event,
			      const char *file, int *psize);
int tracefs_event_file_write(struct tracefs_instance *instance,
			     const char *system, const char *event,
			     const char *file, const char *str);
int tracefs_event_file_append(struct tracefs_instance *instance,
			      const char *system, const char *event,
			      const char *file, const char *str);
int tracefs_event_file_clear(struct tracefs_instance *instance,
			     const char *system, const char *event,
			     const char *file);
bool tracefs_event_file_exists(struct tracefs_instance *instance,
			       const char *system, const char *event,
			       const char *file);

char **tracefs_tracers(const char *tracing_dir);

struct tep_handle *tracefs_local_events(const char *tracing_dir);
struct tep_handle *tracefs_local_events_system(const char *tracing_dir,
					       const char * const *sys_names);
int tracefs_fill_local_events(const char *tracing_dir,
			       struct tep_handle *tep, int *parsing_failures);

int tracefs_load_cmdlines(const char *tracing_dir, struct tep_handle *tep);

char *tracefs_get_clock(struct tracefs_instance *instance);

enum tracefs_option_id {
	TRACEFS_OPTION_INVALID = 0,
	TRACEFS_OPTION_ANNOTATE,
	TRACEFS_OPTION_BIN,
	TRACEFS_OPTION_BLK_CGNAME,
	TRACEFS_OPTION_BLK_CGROUP,
	TRACEFS_OPTION_BLK_CLASSIC,
	TRACEFS_OPTION_BLOCK,
	TRACEFS_OPTION_CONTEXT_INFO,
	TRACEFS_OPTION_DISABLE_ON_FREE,
	TRACEFS_OPTION_DISPLAY_GRAPH,
	TRACEFS_OPTION_EVENT_FORK,
	TRACEFS_OPTION_FGRAPH_ABSTIME,
	TRACEFS_OPTION_FGRAPH_CPU,
	TRACEFS_OPTION_FGRAPH_DURATION,
	TRACEFS_OPTION_FGRAPH_IRQS,
	TRACEFS_OPTION_FGRAPH_OVERHEAD,
	TRACEFS_OPTION_FGRAPH_OVERRUN,
	TRACEFS_OPTION_FGRAPH_PROC,
	TRACEFS_OPTION_FGRAPH_TAIL,
	TRACEFS_OPTION_FUNC_STACKTRACE,
	TRACEFS_OPTION_FUNCTION_FORK,
	TRACEFS_OPTION_FUNCTION_TRACE,
	TRACEFS_OPTION_GRAPH_TIME,
	TRACEFS_OPTION_HEX,
	TRACEFS_OPTION_IRQ_INFO,
	TRACEFS_OPTION_LATENCY_FORMAT,
	TRACEFS_OPTION_MARKERS,
	TRACEFS_OPTION_OVERWRITE,
	TRACEFS_OPTION_PAUSE_ON_TRACE,
	TRACEFS_OPTION_PRINTK_MSG_ONLY,
	TRACEFS_OPTION_PRINT_PARENT,
	TRACEFS_OPTION_RAW,
	TRACEFS_OPTION_RECORD_CMD,
	TRACEFS_OPTION_RECORD_TGID,
	TRACEFS_OPTION_SLEEP_TIME,
	TRACEFS_OPTION_STACKTRACE,
	TRACEFS_OPTION_SYM_ADDR,
	TRACEFS_OPTION_SYM_OFFSET,
	TRACEFS_OPTION_SYM_USEROBJ,
	TRACEFS_OPTION_TRACE_PRINTK,
	TRACEFS_OPTION_USERSTACKTRACE,
	TRACEFS_OPTION_VERBOSE,
};
#define TRACEFS_OPTION_MAX (TRACEFS_OPTION_VERBOSE + 1)

struct tracefs_options_mask;
bool tracefs_option_mask_is_set(const struct tracefs_options_mask *options,
				enum tracefs_option_id id);
const struct tracefs_options_mask *tracefs_options_get_supported(struct tracefs_instance *instance);
bool tracefs_option_is_supported(struct tracefs_instance *instance, enum tracefs_option_id id);
const struct tracefs_options_mask *tracefs_options_get_enabled(struct tracefs_instance *instance);
bool tracefs_option_is_enabled(struct tracefs_instance *instance, enum tracefs_option_id id);
int tracefs_option_enable(struct tracefs_instance *instance, enum tracefs_option_id id);
int tracefs_option_disable(struct tracefs_instance *instance, enum tracefs_option_id id);
const char *tracefs_option_name(enum tracefs_option_id id);
enum tracefs_option_id tracefs_option_id(const char *name);

/*
 * RESET	- Reset on opening filter file (O_TRUNC)
 * CONTINUE	- Do not close filter file on return.
 * FUTURE	- For kernels that support this feature, enable filters for
 *		  a module that has yet to be loaded.
 */
enum {
	TRACEFS_FL_RESET	= (1 << 0),
	TRACEFS_FL_CONTINUE	= (1 << 1),
	TRACEFS_FL_FUTURE	= (1 << 2),
};

int tracefs_function_filter(struct tracefs_instance *instance, const char *filter,
			    const char *module, unsigned int flags);
int tracefs_function_notrace(struct tracefs_instance *instance, const char *filter,
			     const char *module, unsigned int flags);
int tracefs_filter_functions(const char *filter, const char *module, char ***list);


/* Control library logs */
void tracefs_set_loglevel(enum tep_loglevel level);

enum tracefs_tracers {
	TRACEFS_TRACER_NOP = 0,
	TRACEFS_TRACER_CUSTOM,
	TRACEFS_TRACER_FUNCTION,
	TRACEFS_TRACER_FUNCTION_GRAPH,
	TRACEFS_TRACER_IRQSOFF,
	TRACEFS_TRACER_PREEMPTOFF,
	TRACEFS_TRACER_PREEMPTIRQSOFF,
	TRACEFS_TRACER_WAKEUP,
	TRACEFS_TRACER_WAKEUP_RT,
	TRACEFS_TRACER_WAKEUP_DL,
	TRACEFS_TRACER_MMIOTRACE,
	TRACEFS_TRACER_HWLAT,
	TRACEFS_TRACER_BRANCH,
	TRACEFS_TRACER_BLOCK,
};

int tracefs_tracer_set(struct tracefs_instance *instance, enum tracefs_tracers tracer, ...);

int tracefs_tracer_clear(struct tracefs_instance *instance);

ssize_t tracefs_trace_pipe_stream(int fd, struct tracefs_instance *instance, int flags);
ssize_t tracefs_trace_pipe_print(struct tracefs_instance *instance, int flags);
void tracefs_trace_pipe_stop(struct tracefs_instance *instance);

/* Dynamic events */
struct tracefs_dynevent;
enum tracefs_dynevent_type {
	TRACEFS_DYNEVENT_UNKNOWN	= 0,
	TRACEFS_DYNEVENT_KPROBE		= 1 << 0,
	TRACEFS_DYNEVENT_KRETPROBE	= 1 << 1,
	TRACEFS_DYNEVENT_UPROBE		= 1 << 2,
	TRACEFS_DYNEVENT_URETPROBE	= 1 << 3,
	TRACEFS_DYNEVENT_EPROBE		= 1 << 4,
	TRACEFS_DYNEVENT_SYNTH		= 1 << 5,
	TRACEFS_DYNEVENT_MAX		= 1 << 6,
};

#define TRACEFS_DYNEVENT_ALL		0xFFFFFFFF

int tracefs_dynevent_create(struct tracefs_dynevent *devent);
int tracefs_dynevent_destroy(struct tracefs_dynevent *devent, bool force);
int tracefs_dynevent_destroy_all(unsigned int types, bool force);
void tracefs_dynevent_free(struct tracefs_dynevent *devent);
void tracefs_dynevent_list_free(struct tracefs_dynevent **events);
struct tracefs_dynevent **
tracefs_dynevent_get_all(unsigned int types, const char *system);
struct tracefs_dynevent *
tracefs_dynevent_get(enum tracefs_dynevent_type type, const char *system, const char *event);
enum tracefs_dynevent_type
tracefs_dynevent_info(struct tracefs_dynevent *dynevent, char **system,
		      char **event, char **prefix, char **addr, char **format);
struct tep_event *
tracefs_dynevent_get_event(struct tep_handle *tep, struct tracefs_dynevent *dynevent);

struct tracefs_dynevent *
tracefs_eprobe_alloc(const char *system, const char *event,
		     const char *target_system, const char *target_event, const char *fetchargs);
struct tracefs_dynevent *
tracefs_uprobe_alloc(const char *system, const char *event,
		     const char *file, unsigned long long offset, const char *fetchargs);
struct tracefs_dynevent *
tracefs_uretprobe_alloc(const char *system, const char *event,
			const char *file, unsigned long long offset, const char *fetchargs);

struct tracefs_dynevent *
tracefs_kprobe_alloc(const char *system, const char *event, const char *addr, const char *format);
struct tracefs_dynevent *
tracefs_kretprobe_alloc(const char *system, const char *event,
			const char *addr, const char *format, unsigned int max);
int tracefs_kprobe_raw(const char *system, const char *event,
		       const char *addr, const char *format);
int tracefs_kretprobe_raw(const char *system, const char *event,
			  const char *addr, const char *format);

enum tracefs_hist_key_type {
	TRACEFS_HIST_KEY_NORMAL = 0,
	TRACEFS_HIST_KEY_HEX,
	TRACEFS_HIST_KEY_SYM,
	TRACEFS_HIST_KEY_SYM_OFFSET,
	TRACEFS_HIST_KEY_SYSCALL,
	TRACEFS_HIST_KEY_EXECNAME,
	TRACEFS_HIST_KEY_LOG,
	TRACEFS_HIST_KEY_USECS,
	TRACEFS_HIST_KEY_BUCKETS,
	TRACEFS_HIST_KEY_MAX
};

enum tracefs_hist_sort_direction {
	TRACEFS_HIST_SORT_ASCENDING,
	TRACEFS_HIST_SORT_DESCENDING,
};

#define TRACEFS_HIST_TIMESTAMP		"common_timestamp"
#define TRACEFS_HIST_TIMESTAMP_USECS	"common_timestamp.usecs"
#define TRACEFS_HIST_CPU		"cpu"

#define TRACEFS_HIST_COUNTER		"__COUNTER__"

#define TRACEFS_HIST_HITCOUNT		"hitcount"

struct tracefs_hist;

enum tracefs_hist_command {
	TRACEFS_HIST_CMD_START = 0,
	TRACEFS_HIST_CMD_PAUSE,
	TRACEFS_HIST_CMD_CONT,
	TRACEFS_HIST_CMD_CLEAR,
	TRACEFS_HIST_CMD_DESTROY,
};

enum tracefs_filter {
	TRACEFS_FILTER_COMPARE,
	TRACEFS_FILTER_AND,
	TRACEFS_FILTER_OR,
	TRACEFS_FILTER_NOT,
	TRACEFS_FILTER_OPEN_PAREN,
	TRACEFS_FILTER_CLOSE_PAREN,
};

enum tracefs_compare {
	TRACEFS_COMPARE_EQ,
	TRACEFS_COMPARE_NE,
	TRACEFS_COMPARE_GT,
	TRACEFS_COMPARE_GE,
	TRACEFS_COMPARE_LT,
	TRACEFS_COMPARE_LE,
	TRACEFS_COMPARE_RE,
	TRACEFS_COMPARE_AND,
};

void tracefs_hist_free(struct tracefs_hist *hist);
struct tracefs_hist *
tracefs_hist_alloc(struct tep_handle *tep,
		   const char *system, const char *event_name,
		   const char *key, enum tracefs_hist_key_type type);
struct tracefs_hist *
tracefs_hist_alloc_2d(struct tep_handle *tep,
		      const char *system, const char *event_name,
		      const char *key1, enum tracefs_hist_key_type type1,
		      const char *key2, enum tracefs_hist_key_type type2);

struct tracefs_hist_axis {
	const char *key;
	enum tracefs_hist_key_type type;
};

struct tracefs_hist_axis_cnt {
	const char *key;
	enum tracefs_hist_key_type type;
	int cnt;
};

struct tracefs_hist *
tracefs_hist_alloc_nd(struct tep_handle *tep,
		      const char *system, const char *event_name,
		      struct tracefs_hist_axis *axes);
struct tracefs_hist *
tracefs_hist_alloc_nd_cnt(struct tep_handle *tep,
			  const char *system, const char *event_name,
			  struct tracefs_hist_axis_cnt *axes);
const char *tracefs_hist_get_name(struct tracefs_hist *hist);
const char *tracefs_hist_get_event(struct tracefs_hist *hist);
const char *tracefs_hist_get_system(struct tracefs_hist *hist);
int tracefs_hist_add_key(struct tracefs_hist *hist, const char *key,
			 enum tracefs_hist_key_type type);
int tracefs_hist_add_key_cnt(struct tracefs_hist *hist, const char *key,
			 enum tracefs_hist_key_type type, int cnt);
int tracefs_hist_add_value(struct tracefs_hist *hist, const char *value);
int tracefs_hist_add_sort_key(struct tracefs_hist *hist,
			      const char *sort_key);
int tracefs_hist_set_sort_key(struct tracefs_hist *hist,
			      const char *sort_key, ...);
int tracefs_hist_sort_key_direction(struct tracefs_hist *hist,
				    const char *sort_key,
				    enum tracefs_hist_sort_direction dir);
int tracefs_hist_add_name(struct tracefs_hist *hist, const char *name);
int tracefs_hist_append_filter(struct tracefs_hist *hist,
			       enum tracefs_filter type,
			       const char *field,
			       enum tracefs_compare compare,
			       const char *val);
int tracefs_hist_echo_cmd(struct trace_seq *seq,  struct tracefs_instance *instance,
			  struct tracefs_hist *hist, enum tracefs_hist_command command);
int tracefs_hist_command(struct tracefs_instance *instance,
			 struct tracefs_hist *hist, enum tracefs_hist_command cmd);

/**
 * tracefs_hist_start - enable a histogram
 * @instance: The instance the histogram will be in (NULL for toplevel)
 * @hist: The histogram to start
 *
 * Starts executing a histogram.
 *
 * Returns 0 on success, -1 on error.
 */
static inline int tracefs_hist_start(struct tracefs_instance *instance,
				     struct tracefs_hist *hist)
{
	return tracefs_hist_command(instance, hist, 0);
}

/**
 * tracefs_hist_pause - pause a histogram
 * @instance: The instance the histogram is in (NULL for toplevel)
 * @hist: The histogram to pause
 *
 * Pause a histogram.
 *
 * Returns 0 on success, -1 on error.
 */
static inline int tracefs_hist_pause(struct tracefs_instance *instance,
				     struct tracefs_hist *hist)
{
	return tracefs_hist_command(instance, hist, TRACEFS_HIST_CMD_PAUSE);
}

/**
 * tracefs_hist_continue - continue a paused histogram
 * @instance: The instance the histogram is in (NULL for toplevel)
 * @hist: The histogram to continue
 *
 * Continue a histogram.
 *
 * Returns 0 on success, -1 on error.
 */
static inline int tracefs_hist_continue(struct tracefs_instance *instance,
					struct tracefs_hist *hist)
{
	return tracefs_hist_command(instance, hist, TRACEFS_HIST_CMD_CONT);
}

/**
 * tracefs_hist_reset - clear a histogram
 * @instance: The instance the histogram is in (NULL for toplevel)
 * @hist: The histogram to reset
 *
 * Resets a histogram.
 *
 * Returns 0 on success, -1 on error.
 */
static inline int tracefs_hist_reset(struct tracefs_instance *instance,
				     struct tracefs_hist *hist)
{
	return tracefs_hist_command(instance, hist, TRACEFS_HIST_CMD_CLEAR);
}

/**
 * tracefs_hist_destroy - deletes a histogram (needs to be enabled again)
 * @instance: The instance the histogram is in (NULL for toplevel)
 * @hist: The histogram to delete
 *
 * Deletes (removes) a running histogram. This is different than
 * clear, as clear only clears the data but the histogram still exists.
 * This deletes the histogram and should be called before
 * tracefs_hist_free() to clean up properly.
 *
 * Returns 0 on success, -1 on error.
 */
static inline int tracefs_hist_destroy(struct tracefs_instance *instance,
				       struct tracefs_hist *hist)
{
	return tracefs_hist_command(instance, hist, TRACEFS_HIST_CMD_DESTROY);
}

struct tracefs_synth;

/*
 * DELTA_END	- end_field - start_field
 * DELTA_START	- start_field - end_field
 * ADD		- start_field + end_field
 */
enum tracefs_synth_calc {
	TRACEFS_SYNTH_DELTA_END,
	TRACEFS_SYNTH_DELTA_START,
	TRACEFS_SYNTH_ADD,
};

int tracefs_filter_string_append(struct tep_event *event, char **filter,
				 enum tracefs_filter type,
				 const char *field, enum tracefs_compare compare,
				 const char *val);
int tracefs_filter_string_verify(struct tep_event *event, const char *filter,
				 char **err);

int tracefs_event_filter_apply(struct tracefs_instance *instance,
			       struct tep_event *event, const char *filter);

int tracefs_event_filter_clear(struct tracefs_instance *instance,
			       struct tep_event *event);

/** Deprecated do not use: Instead use tracefs_filter_string_append() **/
int tracefs_event_append_filter(struct tep_event *event, char **filter,
				enum tracefs_filter type,
				const char *field, enum tracefs_compare compare,
				const char *val);

/** Deprecated do not use: Instead use tracefs_filter_string_verify()  **/
int tracefs_event_verify_filter(struct tep_event *event, const char *filter,
				char **err);

#define TRACEFS_TIMESTAMP "common_timestamp"
#define TRACEFS_TIMESTAMP_USECS "common_timestamp.usecs"

enum tracefs_synth_handler {
	TRACEFS_SYNTH_HANDLE_NONE	= 0,
	TRACEFS_SYNTH_HANDLE_MATCH,
	TRACEFS_SYNTH_HANDLE_MAX,
	TRACEFS_SYNTH_HANDLE_CHANGE,
};

const char *tracefs_synth_get_name(struct tracefs_synth *synth);
struct tracefs_synth *tracefs_synth_alloc(struct tep_handle *tep,
					  const char *name,
					  const char *start_system,
					  const char *start_event,
					  const char *end_system,
					  const char *end_event,
					  const char *start_match_field,
					  const char *end_match_field,
					  const char *match_name);
int tracefs_synth_add_match_field(struct tracefs_synth *synth,
				  const char *start_match_field,
				  const char *end_match_field,
				  const char *name);
int tracefs_synth_add_compare_field(struct tracefs_synth *synth,
				    const char *start_compare_field,
				    const char *end_compare_field,
				    enum tracefs_synth_calc calc,
				    const char *name);
int tracefs_synth_add_start_field(struct tracefs_synth *synth,
				  const char *start_field,
				  const char *name);
int tracefs_synth_add_end_field(struct tracefs_synth *synth,
				const char *end_field,
				const char *name);
int tracefs_synth_append_start_filter(struct tracefs_synth *synth,
				      enum tracefs_filter type,
				      const char *field,
				      enum tracefs_compare compare,
				      const char *val);
int tracefs_synth_append_end_filter(struct tracefs_synth *synth,
				    enum tracefs_filter type,
				    const char *field,
				    enum tracefs_compare compare,
				    const char *val);
int tracefs_synth_trace(struct tracefs_synth *synth,
			enum tracefs_synth_handler type, const char *field);
int tracefs_synth_snapshot(struct tracefs_synth *synth,
			   enum tracefs_synth_handler type, const char *field);
int tracefs_synth_save(struct tracefs_synth *synth,
		       enum tracefs_synth_handler type, const char *field,
		       char **save_fields);
bool tracefs_synth_complete(struct tracefs_synth *synth);
struct tracefs_hist *tracefs_synth_get_start_hist(struct tracefs_synth *synth);
int tracefs_synth_create(struct tracefs_synth *synth);
int tracefs_synth_destroy(struct tracefs_synth *synth);
void tracefs_synth_free(struct tracefs_synth *synth);
int tracefs_synth_echo_cmd(struct trace_seq *seq, struct tracefs_synth *synth);
int tracefs_synth_raw_fmt(struct trace_seq *seq, struct tracefs_synth *synth);
const char *tracefs_synth_show_event(struct tracefs_synth *synth);
const char *tracefs_synth_show_start_hist(struct tracefs_synth *synth);
const char *tracefs_synth_show_end_hist(struct tracefs_synth *synth);

struct tracefs_synth *tracefs_sql(struct tep_handle *tep, const char *name,
				  const char *sql_buffer, char **err);
struct tep_event *
tracefs_synth_get_event(struct tep_handle *tep, struct tracefs_synth *synth);

struct tracefs_cpu;

struct tracefs_cpu *tracefs_cpu_alloc_fd(int fd, int subbuf_size, bool nonblock);
struct tracefs_cpu *tracefs_cpu_open(struct tracefs_instance *instance,
				     int cpu, bool nonblock);
void tracefs_cpu_close(struct tracefs_cpu *tcpu);
void tracefs_cpu_free_fd(struct tracefs_cpu *tcpu);
int tracefs_cpu_read_size(struct tracefs_cpu *tcpu);
int tracefs_cpu_read(struct tracefs_cpu *tcpu, void *buffer, bool nonblock);
int tracefs_cpu_buffered_read(struct tracefs_cpu *tcpu, void *buffer, bool nonblock);
int tracefs_cpu_write(struct tracefs_cpu *tcpu, int wfd, bool nonblock);
int tracefs_cpu_stop(struct tracefs_cpu *tcpu);
int tracefs_cpu_flush(struct tracefs_cpu *tcpu, void *buffer);
int tracefs_cpu_flush_write(struct tracefs_cpu *tcpu, int wfd);
int tracefs_cpu_pipe(struct tracefs_cpu *tcpu, int wfd, bool nonblock);

#endif /* _TRACE_FS_H */