Commit | Line | Data |
---|---|---|
5448d44c MH |
1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* | |
3 | * Common header file for generic dynamic events. | |
4 | */ | |
5 | ||
6 | #ifndef _TRACE_DYNEVENT_H | |
7 | #define _TRACE_DYNEVENT_H | |
8 | ||
9 | #include <linux/kernel.h> | |
10 | #include <linux/list.h> | |
11 | #include <linux/mutex.h> | |
12 | #include <linux/seq_file.h> | |
13 | ||
14 | #include "trace.h" | |
15 | ||
16 | struct dyn_event; | |
17 | ||
18 | /** | |
19 | * struct dyn_event_operations - Methods for each type of dynamic events | |
20 | * | |
21 | * These methods must be set for each type, since there is no default method. | |
22 | * Before using this for dyn_event_init(), it must be registered by | |
23 | * dyn_event_register(). | |
24 | * | |
25 | * @create: Parse and create event method. This is invoked when user passes | |
26 | * a event definition to dynamic_events interface. This must not destruct | |
27 | * the arguments and return -ECANCELED if given arguments doesn't match its | |
28 | * command prefix. | |
29 | * @show: Showing method. This is invoked when user reads the event definitions | |
30 | * via dynamic_events interface. | |
31 | * @is_busy: Check whether given event is busy so that it can not be deleted. | |
32 | * Return true if it is busy, otherwides false. | |
33 | * @free: Delete the given event. Return 0 if success, otherwides error. | |
34 | * @match: Check whether given event and system name match this event. | |
35 | * Return true if it matches, otherwides false. | |
36 | * | |
37 | * Except for @create, these methods are called under holding event_mutex. | |
38 | */ | |
39 | struct dyn_event_operations { | |
40 | struct list_head list; | |
41 | int (*create)(int argc, const char *argv[]); | |
42 | int (*show)(struct seq_file *m, struct dyn_event *ev); | |
43 | bool (*is_busy)(struct dyn_event *ev); | |
44 | int (*free)(struct dyn_event *ev); | |
45 | bool (*match)(const char *system, const char *event, | |
46 | struct dyn_event *ev); | |
47 | }; | |
48 | ||
49 | /* Register new dyn_event type -- must be called at first */ | |
50 | int dyn_event_register(struct dyn_event_operations *ops); | |
51 | ||
52 | /** | |
53 | * struct dyn_event - Dynamic event list header | |
54 | * | |
55 | * The dyn_event structure encapsulates a list and a pointer to the operators | |
56 | * for making a global list of dynamic events. | |
57 | * User must includes this in each event structure, so that those events can | |
58 | * be added/removed via dynamic_events interface. | |
59 | */ | |
60 | struct dyn_event { | |
61 | struct list_head list; | |
62 | struct dyn_event_operations *ops; | |
63 | }; | |
64 | ||
65 | extern struct list_head dyn_event_list; | |
66 | ||
67 | static inline | |
68 | int dyn_event_init(struct dyn_event *ev, struct dyn_event_operations *ops) | |
69 | { | |
70 | if (!ev || !ops) | |
71 | return -EINVAL; | |
72 | ||
73 | INIT_LIST_HEAD(&ev->list); | |
74 | ev->ops = ops; | |
75 | return 0; | |
76 | } | |
77 | ||
78 | static inline int dyn_event_add(struct dyn_event *ev) | |
79 | { | |
80 | lockdep_assert_held(&event_mutex); | |
81 | ||
82 | if (!ev || !ev->ops) | |
83 | return -EINVAL; | |
84 | ||
85 | list_add_tail(&ev->list, &dyn_event_list); | |
86 | return 0; | |
87 | } | |
88 | ||
89 | static inline void dyn_event_remove(struct dyn_event *ev) | |
90 | { | |
91 | lockdep_assert_held(&event_mutex); | |
92 | list_del_init(&ev->list); | |
93 | } | |
94 | ||
95 | void *dyn_event_seq_start(struct seq_file *m, loff_t *pos); | |
96 | void *dyn_event_seq_next(struct seq_file *m, void *v, loff_t *pos); | |
97 | void dyn_event_seq_stop(struct seq_file *m, void *v); | |
98 | int dyn_events_release_all(struct dyn_event_operations *type); | |
99 | int dyn_event_release(int argc, char **argv, struct dyn_event_operations *type); | |
100 | ||
101 | /* | |
102 | * for_each_dyn_event - iterate over the dyn_event list | |
103 | * @pos: the struct dyn_event * to use as a loop cursor | |
104 | * | |
105 | * This is just a basement of for_each macro. Wrap this for | |
106 | * each actual event structure with ops filtering. | |
107 | */ | |
108 | #define for_each_dyn_event(pos) \ | |
109 | list_for_each_entry(pos, &dyn_event_list, list) | |
110 | ||
111 | /* | |
112 | * for_each_dyn_event - iterate over the dyn_event list safely | |
113 | * @pos: the struct dyn_event * to use as a loop cursor | |
114 | * @n: the struct dyn_event * to use as temporary storage | |
115 | */ | |
116 | #define for_each_dyn_event_safe(pos, n) \ | |
117 | list_for_each_entry_safe(pos, n, &dyn_event_list, list) | |
118 | ||
119 | #endif |