0001
0002
0003
0004
0005
0006 #ifndef _TRACE_DYNEVENT_H
0007 #define _TRACE_DYNEVENT_H
0008
0009 #include <linux/kernel.h>
0010 #include <linux/list.h>
0011 #include <linux/mutex.h>
0012 #include <linux/seq_file.h>
0013
0014 #include "trace.h"
0015
0016 struct dyn_event;
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 struct dyn_event_operations {
0041 struct list_head list;
0042 int (*create)(const char *raw_command);
0043 int (*show)(struct seq_file *m, struct dyn_event *ev);
0044 bool (*is_busy)(struct dyn_event *ev);
0045 int (*free)(struct dyn_event *ev);
0046 bool (*match)(const char *system, const char *event,
0047 int argc, const char **argv, struct dyn_event *ev);
0048 };
0049
0050
0051 int dyn_event_register(struct dyn_event_operations *ops);
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061 struct dyn_event {
0062 struct list_head list;
0063 struct dyn_event_operations *ops;
0064 };
0065
0066 extern struct list_head dyn_event_list;
0067
0068 static inline
0069 int dyn_event_init(struct dyn_event *ev, struct dyn_event_operations *ops)
0070 {
0071 if (!ev || !ops)
0072 return -EINVAL;
0073
0074 INIT_LIST_HEAD(&ev->list);
0075 ev->ops = ops;
0076 return 0;
0077 }
0078
0079 static inline int dyn_event_add(struct dyn_event *ev,
0080 struct trace_event_call *call)
0081 {
0082 lockdep_assert_held(&event_mutex);
0083
0084 if (!ev || !ev->ops)
0085 return -EINVAL;
0086
0087 call->flags |= TRACE_EVENT_FL_DYNAMIC;
0088 list_add_tail(&ev->list, &dyn_event_list);
0089 return 0;
0090 }
0091
0092 static inline void dyn_event_remove(struct dyn_event *ev)
0093 {
0094 lockdep_assert_held(&event_mutex);
0095 list_del_init(&ev->list);
0096 }
0097
0098 void *dyn_event_seq_start(struct seq_file *m, loff_t *pos);
0099 void *dyn_event_seq_next(struct seq_file *m, void *v, loff_t *pos);
0100 void dyn_event_seq_stop(struct seq_file *m, void *v);
0101 int dyn_events_release_all(struct dyn_event_operations *type);
0102 int dyn_event_release(const char *raw_command, struct dyn_event_operations *type);
0103
0104
0105
0106
0107
0108
0109
0110
0111 #define for_each_dyn_event(pos) \
0112 list_for_each_entry(pos, &dyn_event_list, list)
0113
0114
0115
0116
0117
0118
0119 #define for_each_dyn_event_safe(pos, n) \
0120 list_for_each_entry_safe(pos, n, &dyn_event_list, list)
0121
0122 extern void dynevent_cmd_init(struct dynevent_cmd *cmd, char *buf, int maxlen,
0123 enum dynevent_type type,
0124 dynevent_create_fn_t run_command);
0125
0126 typedef int (*dynevent_check_arg_fn_t)(void *data);
0127
0128 struct dynevent_arg {
0129 const char *str;
0130 char separator;
0131 };
0132
0133 extern void dynevent_arg_init(struct dynevent_arg *arg,
0134 char separator);
0135 extern int dynevent_arg_add(struct dynevent_cmd *cmd,
0136 struct dynevent_arg *arg,
0137 dynevent_check_arg_fn_t check_arg);
0138
0139 struct dynevent_arg_pair {
0140 const char *lhs;
0141 const char *rhs;
0142 char operator;
0143 char separator;
0144 };
0145
0146 extern void dynevent_arg_pair_init(struct dynevent_arg_pair *arg_pair,
0147 char operator, char separator);
0148
0149 extern int dynevent_arg_pair_add(struct dynevent_cmd *cmd,
0150 struct dynevent_arg_pair *arg_pair,
0151 dynevent_check_arg_fn_t check_arg);
0152 extern int dynevent_str_add(struct dynevent_cmd *cmd, const char *str);
0153
0154 #endif