Branch data Line data Source code
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. The argc 35 : : * and argv is used for exact match. Return true if it matches, otherwides 36 : : * false. 37 : : * 38 : : * Except for @create, these methods are called under holding event_mutex. 39 : : */ 40 : : struct dyn_event_operations { 41 : : struct list_head list; 42 : : int (*create)(int argc, const char *argv[]); 43 : : int (*show)(struct seq_file *m, struct dyn_event *ev); 44 : : bool (*is_busy)(struct dyn_event *ev); 45 : : int (*free)(struct dyn_event *ev); 46 : : bool (*match)(const char *system, const char *event, 47 : : int argc, const char **argv, struct dyn_event *ev); 48 : : }; 49 : : 50 : : /* Register new dyn_event type -- must be called at first */ 51 : : int dyn_event_register(struct dyn_event_operations *ops); 52 : : 53 : : /** 54 : : * struct dyn_event - Dynamic event list header 55 : : * 56 : : * The dyn_event structure encapsulates a list and a pointer to the operators 57 : : * for making a global list of dynamic events. 58 : : * User must includes this in each event structure, so that those events can 59 : : * be added/removed via dynamic_events interface. 60 : : */ 61 : : struct dyn_event { 62 : : struct list_head list; 63 : : struct dyn_event_operations *ops; 64 : : }; 65 : : 66 : : extern struct list_head dyn_event_list; 67 : : 68 : : static inline 69 : : int dyn_event_init(struct dyn_event *ev, struct dyn_event_operations *ops) 70 : : { 71 [ # # ]: 0 : if (!ev || !ops) 72 : : return -EINVAL; 73 : : 74 : 0 : INIT_LIST_HEAD(&ev->list); 75 : 0 : ev->ops = ops; 76 : : return 0; 77 : : } 78 : : 79 : : static inline int dyn_event_add(struct dyn_event *ev) 80 : : { 81 : : lockdep_assert_held(&event_mutex); 82 : : 83 [ # # # # : 0 : if (!ev || !ev->ops) # # # # ] 84 : : return -EINVAL; 85 : : 86 : 0 : list_add_tail(&ev->list, &dyn_event_list); 87 : : return 0; 88 : : } 89 : : 90 : : static inline void dyn_event_remove(struct dyn_event *ev) 91 : : { 92 : : lockdep_assert_held(&event_mutex); 93 : 0 : list_del_init(&ev->list); 94 : : } 95 : : 96 : : void *dyn_event_seq_start(struct seq_file *m, loff_t *pos); 97 : : void *dyn_event_seq_next(struct seq_file *m, void *v, loff_t *pos); 98 : : void dyn_event_seq_stop(struct seq_file *m, void *v); 99 : : int dyn_events_release_all(struct dyn_event_operations *type); 100 : : int dyn_event_release(int argc, char **argv, struct dyn_event_operations *type); 101 : : 102 : : /* 103 : : * for_each_dyn_event - iterate over the dyn_event list 104 : : * @pos: the struct dyn_event * to use as a loop cursor 105 : : * 106 : : * This is just a basement of for_each macro. Wrap this for 107 : : * each actual event structure with ops filtering. 108 : : */ 109 : : #define for_each_dyn_event(pos) \ 110 : : list_for_each_entry(pos, &dyn_event_list, list) 111 : : 112 : : /* 113 : : * for_each_dyn_event - iterate over the dyn_event list safely 114 : : * @pos: the struct dyn_event * to use as a loop cursor 115 : : * @n: the struct dyn_event * to use as temporary storage 116 : : */ 117 : : #define for_each_dyn_event_safe(pos, n) \ 118 : : list_for_each_entry_safe(pos, n, &dyn_event_list, list) 119 : : 120 : : #endif