Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
event-parse.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <[email protected]>
3  *
4  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation;
8  * version 2.1 of the License (not later!)
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20  */
21 #ifndef _PARSE_EVENTS_H
22 #define _PARSE_EVENTS_H
23 
24 #include <stdarg.h>
25 #include <regex.h>
26 
27 #ifndef __maybe_unused
28 #define __maybe_unused __attribute__((unused))
29 #endif
30 
31 /* ----------------------- trace_seq ----------------------- */
32 
33 
34 #ifndef TRACE_SEQ_BUF_SIZE
35 #define TRACE_SEQ_BUF_SIZE 4096
36 #endif
37 
38 #ifndef DEBUG_RECORD
39 #define DEBUG_RECORD 0
40 #endif
41 
42 struct pevent_record {
43  unsigned long long ts;
44  unsigned long long offset;
45  long long missed_events; /* buffer dropped events before */
46  int record_size; /* size of binary record */
47  int size; /* size of data */
48  void *data;
49  int cpu;
50  int ref_count;
51  int locked; /* Do not free, even if ref_count is zero */
52  void *priv;
53 #if DEBUG_RECORD
54  struct pevent_record *prev;
55  struct pevent_record *next;
56  long alloc_addr;
57 #endif
58 };
59 
60 /*
61  * Trace sequences are used to allow a function to call several other functions
62  * to create a string of data to use (up to a max of PAGE_SIZE).
63  */
64 
65 struct trace_seq {
66  char *buffer;
67  unsigned int buffer_size;
68  unsigned int len;
69  unsigned int readpos;
70 };
71 
72 void trace_seq_init(struct trace_seq *s);
73 void trace_seq_destroy(struct trace_seq *s);
74 
75 extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
76  __attribute__ ((format (printf, 2, 3)));
77 extern int trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
78  __attribute__ ((format (printf, 2, 0)));
79 
80 extern int trace_seq_puts(struct trace_seq *s, const char *str);
81 extern int trace_seq_putc(struct trace_seq *s, unsigned char c);
82 
83 extern void trace_seq_terminate(struct trace_seq *s);
84 
85 extern int trace_seq_do_printf(struct trace_seq *s);
86 
87 
88 /* ----------------------- pevent ----------------------- */
89 
92 
95  struct event_format *event,
96  void *context);
97 
98 typedef int (*pevent_plugin_load_func)(struct pevent *pevent);
99 typedef int (*pevent_plugin_unload_func)(void);
100 
102  struct plugin_option *next;
103  void *handle;
104  char *file;
105  char *name;
107  char *description;
108  char *value;
109  void *priv;
110  int set;
111 };
112 
113 /*
114  * Plugin hooks that can be called:
115  *
116  * PEVENT_PLUGIN_LOADER: (required)
117  * The function name to initialized the plugin.
118  *
119  * int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
120  *
121  * PEVENT_PLUGIN_UNLOADER: (optional)
122  * The function called just before unloading
123  *
124  * int PEVENT_PLUGIN_UNLOADER(void)
125  *
126  * PEVENT_PLUGIN_OPTIONS: (optional)
127  * Plugin options that can be set before loading
128  *
129  * struct plugin_option PEVENT_PLUGIN_OPTIONS[] = {
130  * {
131  * .name = "option-name",
132  * .plugin_alias = "overide-file-name", (optional)
133  * .description = "description of option to show users",
134  * },
135  * {
136  * .name = NULL,
137  * },
138  * };
139  *
140  * Array must end with .name = NULL;
141  *
142  *
143  * .plugin_alias is used to give a shorter name to access
144  * the vairable. Useful if a plugin handles more than one event.
145  *
146  * PEVENT_PLUGIN_ALIAS: (optional)
147  * The name to use for finding options (uses filename if not defined)
148  */
149 #define PEVENT_PLUGIN_LOADER pevent_plugin_loader
150 #define PEVENT_PLUGIN_UNLOADER pevent_plugin_unloader
151 #define PEVENT_PLUGIN_OPTIONS pevent_plugin_options
152 #define PEVENT_PLUGIN_ALIAS pevent_plugin_alias
153 #define _MAKE_STR(x) #x
154 #define MAKE_STR(x) _MAKE_STR(x)
155 #define PEVENT_PLUGIN_LOADER_NAME MAKE_STR(PEVENT_PLUGIN_LOADER)
156 #define PEVENT_PLUGIN_UNLOADER_NAME MAKE_STR(PEVENT_PLUGIN_UNLOADER)
157 #define PEVENT_PLUGIN_OPTIONS_NAME MAKE_STR(PEVENT_PLUGIN_OPTIONS)
158 #define PEVENT_PLUGIN_ALIAS_NAME MAKE_STR(PEVENT_PLUGIN_ALIAS)
159 
160 #define NSECS_PER_SEC 1000000000ULL
161 #define NSECS_PER_USEC 1000ULL
162 
172 };
173 
174 struct format_field {
177  char *type;
178  char *name;
179  int offset;
180  int size;
181  unsigned int arraylen;
182  unsigned int elementsize;
183  unsigned long flags;
184 };
185 
186 struct format {
191 };
192 
194  char *atom;
195 };
196 
198  char *string;
199  int offset;
200 };
201 
203  char *name;
205 };
206 
209  char *value;
210  char *str;
211 };
212 
214  char *type;
215  struct print_arg *item;
216 };
217 
219  struct print_arg *field;
220  char *delim;
222 };
223 
225  struct print_arg *field;
227 };
228 
230  struct print_arg *field;
231  struct print_arg *size;
232 };
233 
236  struct print_arg *index;
237 };
238 
239 struct print_arg;
240 
241 struct print_arg_op {
242  char *op;
243  int prio;
244  struct print_arg *left;
245  struct print_arg *right;
246 };
247 
249 
252  struct print_arg *args;
253 };
254 
268 };
269 
270 struct print_arg {
271  struct print_arg *next;
273  union {
282  struct print_arg_op op;
284  };
285 };
286 
287 struct print_fmt {
288  char *format;
289  struct print_arg *args;
290 };
291 
292 struct event_format {
293  struct pevent *pevent;
294  char *name;
295  int id;
296  int flags;
297  struct format format;
299  char *system;
301  void *context;
302 };
303 
304 enum {
310 
311  EVENT_FL_FAILED = 0x80000000
312 };
313 
318 };
319 
330 };
331 
332 typedef unsigned long long (*pevent_func_handler)(struct trace_seq *s,
333  unsigned long long *args);
334 
342 };
343 
345  PEVENT_NSEC_OUTPUT = 1, /* output in NSECS */
346 };
347 
348 #define PEVENT_ERRORS \
349  _PE(MEM_ALLOC_FAILED, "failed to allocate memory"), \
350  _PE(PARSE_EVENT_FAILED, "failed to parse event"), \
351  _PE(READ_ID_FAILED, "failed to read event id"), \
352  _PE(READ_FORMAT_FAILED, "failed to read event format"), \
353  _PE(READ_PRINT_FAILED, "failed to read event print fmt"), \
354  _PE(OLD_FTRACE_ARG_FAILED,"failed to allocate field name for ftrace"),\
355  _PE(INVALID_ARG_TYPE, "invalid argument type")
356 
357 #undef _PE
358 #define _PE(__code, __str) PEVENT_ERRNO__ ## __code
361 
362  /*
363  * Choose an arbitrary negative big number not to clash with standard
364  * errno since SUS requires the errno has distinct positive values.
365  * See 'Issue 6' in the link below.
366  *
367  * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html
368  */
370 
372 
374 };
375 #undef _PE
376 
377 struct cmdline;
378 struct cmdline_list;
379 struct func_map;
380 struct func_list;
381 struct event_handler;
382 
383 struct pevent {
385 
393 
396 
398 
400 
401  int cpus;
403 
404  struct cmdline *cmdlines;
407 
410  unsigned int func_count;
411 
414  unsigned int printk_count;
415 
416 
421 
424 
426  int pid_size;
427 
429  int pc_size;
430 
433 
435  int ld_size;
436 
438 
440 
441  int flags;
442 
446 
449 
450  /* cache */
452 };
453 
454 static inline void pevent_set_flag(struct pevent *pevent, int flag)
455 {
456  pevent->flags |= flag;
457 }
458 
459 static inline unsigned short
460 __data2host2(struct pevent *pevent, unsigned short data)
461 {
462  unsigned short swap;
463 
464  if (pevent->host_bigendian == pevent->file_bigendian)
465  return data;
466 
467  swap = ((data & 0xffULL) << 8) |
468  ((data & (0xffULL << 8)) >> 8);
469 
470  return swap;
471 }
472 
473 static inline unsigned int
474 __data2host4(struct pevent *pevent, unsigned int data)
475 {
476  unsigned int swap;
477 
478  if (pevent->host_bigendian == pevent->file_bigendian)
479  return data;
480 
481  swap = ((data & 0xffULL) << 24) |
482  ((data & (0xffULL << 8)) << 8) |
483  ((data & (0xffULL << 16)) >> 8) |
484  ((data & (0xffULL << 24)) >> 24);
485 
486  return swap;
487 }
488 
489 static inline unsigned long long
490 __data2host8(struct pevent *pevent, unsigned long long data)
491 {
492  unsigned long long swap;
493 
494  if (pevent->host_bigendian == pevent->file_bigendian)
495  return data;
496 
497  swap = ((data & 0xffULL) << 56) |
498  ((data & (0xffULL << 8)) << 40) |
499  ((data & (0xffULL << 16)) << 24) |
500  ((data & (0xffULL << 24)) << 8) |
501  ((data & (0xffULL << 32)) >> 8) |
502  ((data & (0xffULL << 40)) >> 24) |
503  ((data & (0xffULL << 48)) >> 40) |
504  ((data & (0xffULL << 56)) >> 56);
505 
506  return swap;
507 }
508 
509 #define data2host2(pevent, ptr) __data2host2(pevent, *(unsigned short *)(ptr))
510 #define data2host4(pevent, ptr) __data2host4(pevent, *(unsigned int *)(ptr))
511 #define data2host8(pevent, ptr) \
512 ({ \
513  unsigned long long __val; \
514  \
515  memcpy(&__val, (ptr), sizeof(unsigned long long)); \
516  __data2host8(pevent, __val); \
517 })
518 
519 /* taken from kernel/trace/trace.h */
526 };
527 
528 int pevent_register_comm(struct pevent *pevent, const char *comm, int pid);
529 int pevent_register_function(struct pevent *pevent, char *name,
530  unsigned long long addr, char *mod);
531 int pevent_register_print_string(struct pevent *pevent, char *fmt,
532  unsigned long long addr);
533 int pevent_pid_is_registered(struct pevent *pevent, int pid);
534 
535 void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
536  struct pevent_record *record);
537 
538 int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size,
539  int long_size);
540 
541 enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
542  unsigned long size, const char *sys);
543 enum pevent_errno pevent_parse_format(struct event_format **eventp, const char *buf,
544  unsigned long size, const char *sys);
546 
547 void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
548  const char *name, struct pevent_record *record,
549  int *len, int err);
550 
551 int pevent_get_field_val(struct trace_seq *s, struct event_format *event,
552  const char *name, struct pevent_record *record,
553  unsigned long long *val, int err);
555  const char *name, struct pevent_record *record,
556  unsigned long long *val, int err);
558  const char *name, struct pevent_record *record,
559  unsigned long long *val, int err);
560 
561 int pevent_print_num_field(struct trace_seq *s, const char *fmt,
562  struct event_format *event, const char *name,
563  struct pevent_record *record, int err);
564 
565 int pevent_register_event_handler(struct pevent *pevent, int id, char *sys_name, char *event_name,
567 int pevent_register_print_function(struct pevent *pevent,
569  enum pevent_func_arg_type ret_type,
570  char *name, ...);
571 
572 struct format_field *pevent_find_common_field(struct event_format *event, const char *name);
573 struct format_field *pevent_find_field(struct event_format *event, const char *name);
574 struct format_field *pevent_find_any_field(struct event_format *event, const char *name);
575 
576 const char *pevent_find_function(struct pevent *pevent, unsigned long long addr);
577 unsigned long long
578 pevent_find_function_address(struct pevent *pevent, unsigned long long addr);
579 unsigned long long pevent_read_number(struct pevent *pevent, const void *ptr, int size);
580 int pevent_read_number_field(struct format_field *field, const void *data,
581  unsigned long long *value);
582 
583 struct event_format *pevent_find_event(struct pevent *pevent, int id);
584 
585 struct event_format *
586 pevent_find_event_by_name(struct pevent *pevent, const char *sys, const char *name);
587 
588 void pevent_data_lat_fmt(struct pevent *pevent,
589  struct trace_seq *s, struct pevent_record *record);
590 int pevent_data_type(struct pevent *pevent, struct pevent_record *rec);
591 struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type);
592 int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec);
593 const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid);
594 void pevent_event_info(struct trace_seq *s, struct event_format *event,
595  struct pevent_record *record);
596 int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum,
597  char *buf, size_t buflen);
598 
599 struct event_format **pevent_list_events(struct pevent *pevent, enum event_sort_type);
602 
603 static inline int pevent_get_cpus(struct pevent *pevent)
604 {
605  return pevent->cpus;
606 }
607 
608 static inline void pevent_set_cpus(struct pevent *pevent, int cpus)
609 {
610  pevent->cpus = cpus;
611 }
612 
613 static inline int pevent_get_long_size(struct pevent *pevent)
614 {
615  return pevent->long_size;
616 }
617 
618 static inline void pevent_set_long_size(struct pevent *pevent, int long_size)
619 {
620  pevent->long_size = long_size;
621 }
622 
623 static inline int pevent_is_file_bigendian(struct pevent *pevent)
624 {
625  return pevent->file_bigendian;
626 }
627 
628 static inline void pevent_set_file_bigendian(struct pevent *pevent, int endian)
629 {
630  pevent->file_bigendian = endian;
631 }
632 
633 static inline int pevent_is_host_bigendian(struct pevent *pevent)
634 {
635  return pevent->host_bigendian;
636 }
637 
638 static inline void pevent_set_host_bigendian(struct pevent *pevent, int endian)
639 {
640  pevent->host_bigendian = endian;
641 }
642 
643 static inline int pevent_is_latency_format(struct pevent *pevent)
644 {
645  return pevent->latency_format;
646 }
647 
648 static inline void pevent_set_latency_format(struct pevent *pevent, int lat)
649 {
650  pevent->latency_format = lat;
651 }
652 
653 struct pevent *pevent_alloc(void);
654 void pevent_free(struct pevent *pevent);
655 void pevent_ref(struct pevent *pevent);
656 void pevent_unref(struct pevent *pevent);
657 
658 /* access to the internal parser */
659 void pevent_buffer_init(const char *buf, unsigned long long size);
660 enum event_type pevent_read_token(char **tok);
661 void pevent_free_token(char *token);
662 int pevent_peek_char(void);
663 const char *pevent_get_input_buf(void);
664 unsigned long long pevent_get_input_buf_ptr(void);
665 
666 /* for debugging */
667 void pevent_print_funcs(struct pevent *pevent);
668 void pevent_print_printk(struct pevent *pevent);
669 
670 /* ----------------------- filtering ----------------------- */
671 
675 };
676 
681 };
682 
695 };
696 
710 };
711 
721 };
722 
727 };
728 
729 struct fliter_arg;
730 
733 };
734 
737 };
738 
741  union {
742  char *str;
743  unsigned long long val;
744  };
745 };
746 
749  struct filter_arg *left;
750  struct filter_arg *right;
751 };
752 
755  struct filter_arg *left;
756  struct filter_arg *right;
757 };
758 
761  struct filter_arg *left;
762  struct filter_arg *right;
763 };
764 
768  char *val;
769  char *buffer;
770  regex_t reg;
771 };
772 
773 struct filter_arg {
775  union {
783  };
784 };
785 
786 struct filter_type {
787  int event_id;
790 };
791 
792 struct event_filter {
793  struct pevent *pevent;
794  int filters;
796 };
797 
798 struct event_filter *pevent_filter_alloc(struct pevent *pevent);
799 
800 #define FILTER_NONE -2
801 #define FILTER_NOEXIST -1
802 #define FILTER_MISS 0
803 #define FILTER_MATCH 1
804 
809 };
810 
812  const char *filter_str,
813  char **error_str);
814 
815 
817  struct pevent_record *record);
818 
820  int event_id);
821 
823 
826 
828 
830 
832  int event_id);
833 
835  int event_id,
837 
839 
842 
843 int pevent_filter_compare(struct event_filter *filter1, struct event_filter *filter2);
844 
845 #endif /* _PARSE_EVENTS_H */