Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Common header file for generic dynamic events.
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  * struct dyn_event_operations - Methods for each type of dynamic events
0020  *
0021  * These methods must be set for each type, since there is no default method.
0022  * Before using this for dyn_event_init(), it must be registered by
0023  * dyn_event_register().
0024  *
0025  * @create: Parse and create event method. This is invoked when user passes
0026  *  a event definition to dynamic_events interface. This must not destruct
0027  *  the arguments and return -ECANCELED if given arguments doesn't match its
0028  *  command prefix.
0029  * @show: Showing method. This is invoked when user reads the event definitions
0030  *  via dynamic_events interface.
0031  * @is_busy: Check whether given event is busy so that it can not be deleted.
0032  *  Return true if it is busy, otherwise false.
0033  * @free: Delete the given event. Return 0 if success, otherwise error.
0034  * @match: Check whether given event and system name match this event. The argc
0035  *  and argv is used for exact match. Return true if it matches, otherwise
0036  *  false.
0037  *
0038  * Except for @create, these methods are called under holding event_mutex.
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 /* Register new dyn_event type -- must be called at first */
0051 int dyn_event_register(struct dyn_event_operations *ops);
0052 
0053 /**
0054  * struct dyn_event - Dynamic event list header
0055  *
0056  * The dyn_event structure encapsulates a list and a pointer to the operators
0057  * for making a global list of dynamic events.
0058  * User must includes this in each event structure, so that those events can
0059  * be added/removed via dynamic_events interface.
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  * for_each_dyn_event   -   iterate over the dyn_event list
0106  * @pos:    the struct dyn_event * to use as a loop cursor
0107  *
0108  * This is just a basement of for_each macro. Wrap this for
0109  * each actual event structure with ops filtering.
0110  */
0111 #define for_each_dyn_event(pos) \
0112     list_for_each_entry(pos, &dyn_event_list, list)
0113 
0114 /*
0115  * for_each_dyn_event   -   iterate over the dyn_event list safely
0116  * @pos:    the struct dyn_event * to use as a loop cursor
0117  * @n:      the struct dyn_event * to use as temporary storage
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; /* e.g. ';', ',', or nothing */
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; /* e.g. '=' or nothing */
0143     char            separator; /* e.g. ';', ',', or nothing */
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