Skip to content

Commit ae63b31

Browse files
Steven Rostedtrostedt
authored andcommitted
tracing: Separate out trace events from global variables
The trace events for ftrace are all defined via global variables. The arrays of events and event systems are linked to a global list. This prevents multiple users of the event system (what to enable and what not to). By adding descriptors to represent the event/file relation, as well as to which trace_array descriptor they are associated with, allows for more than one set of events to be defined. Once the trace events files have a link between the trace event and the trace_array they are associated with, we can create multiple trace_arrays that can record separate events in separate buffers. Signed-off-by: Steven Rostedt <[email protected]>
1 parent 613f04a commit ae63b31

File tree

6 files changed

+622
-260
lines changed

6 files changed

+622
-260
lines changed

include/linux/ftrace_event.h

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -182,18 +182,20 @@ extern int ftrace_event_reg(struct ftrace_event_call *event,
182182
enum trace_reg type, void *data);
183183

184184
enum {
185-
TRACE_EVENT_FL_ENABLED_BIT,
186185
TRACE_EVENT_FL_FILTERED_BIT,
187-
TRACE_EVENT_FL_RECORDED_CMD_BIT,
188186
TRACE_EVENT_FL_CAP_ANY_BIT,
189187
TRACE_EVENT_FL_NO_SET_FILTER_BIT,
190188
TRACE_EVENT_FL_IGNORE_ENABLE_BIT,
191189
};
192190

191+
/*
192+
* Event flags:
193+
* FILTERED - The event has a filter attached
194+
* CAP_ANY - Any user can enable for perf
195+
* NO_SET_FILTER - Set when filter has error and is to be ignored
196+
*/
193197
enum {
194-
TRACE_EVENT_FL_ENABLED = (1 << TRACE_EVENT_FL_ENABLED_BIT),
195198
TRACE_EVENT_FL_FILTERED = (1 << TRACE_EVENT_FL_FILTERED_BIT),
196-
TRACE_EVENT_FL_RECORDED_CMD = (1 << TRACE_EVENT_FL_RECORDED_CMD_BIT),
197199
TRACE_EVENT_FL_CAP_ANY = (1 << TRACE_EVENT_FL_CAP_ANY_BIT),
198200
TRACE_EVENT_FL_NO_SET_FILTER = (1 << TRACE_EVENT_FL_NO_SET_FILTER_BIT),
199201
TRACE_EVENT_FL_IGNORE_ENABLE = (1 << TRACE_EVENT_FL_IGNORE_ENABLE_BIT),
@@ -203,12 +205,44 @@ struct ftrace_event_call {
203205
struct list_head list;
204206
struct ftrace_event_class *class;
205207
char *name;
206-
struct dentry *dir;
207208
struct trace_event event;
208209
const char *print_fmt;
209210
struct event_filter *filter;
211+
struct list_head *files;
210212
void *mod;
211213
void *data;
214+
int flags; /* static flags of different events */
215+
216+
#ifdef CONFIG_PERF_EVENTS
217+
int perf_refcount;
218+
struct hlist_head __percpu *perf_events;
219+
#endif
220+
};
221+
222+
struct trace_array;
223+
struct ftrace_subsystem_dir;
224+
225+
enum {
226+
FTRACE_EVENT_FL_ENABLED_BIT,
227+
FTRACE_EVENT_FL_RECORDED_CMD_BIT,
228+
};
229+
230+
/*
231+
* Ftrace event file flags:
232+
* ENABELD - The event is enabled
233+
* RECORDED_CMD - The comms should be recorded at sched_switch
234+
*/
235+
enum {
236+
FTRACE_EVENT_FL_ENABLED = (1 << FTRACE_EVENT_FL_ENABLED_BIT),
237+
FTRACE_EVENT_FL_RECORDED_CMD = (1 << FTRACE_EVENT_FL_RECORDED_CMD_BIT),
238+
};
239+
240+
struct ftrace_event_file {
241+
struct list_head list;
242+
struct ftrace_event_call *event_call;
243+
struct dentry *dir;
244+
struct trace_array *tr;
245+
struct ftrace_subsystem_dir *system;
212246

213247
/*
214248
* 32 bit flags:
@@ -223,17 +257,12 @@ struct ftrace_event_call {
223257
*
224258
* Note: Reads of flags do not hold the event_mutex since
225259
* they occur in critical sections. But the way flags
226-
* is currently used, these changes do no affect the code
260+
* is currently used, these changes do not affect the code
227261
* except that when a change is made, it may have a slight
228262
* delay in propagating the changes to other CPUs due to
229263
* caching and such.
230264
*/
231265
unsigned int flags;
232-
233-
#ifdef CONFIG_PERF_EVENTS
234-
int perf_refcount;
235-
struct hlist_head __percpu *perf_events;
236-
#endif
237266
};
238267

239268
#define __TRACE_EVENT_FLAGS(name, value) \

include/trace/ftrace.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,8 @@ static inline notrace int ftrace_get_offsets_##call( \
518518
static notrace void \
519519
ftrace_raw_event_##call(void *__data, proto) \
520520
{ \
521-
struct ftrace_event_call *event_call = __data; \
521+
struct ftrace_event_file *ftrace_file = __data; \
522+
struct ftrace_event_call *event_call = ftrace_file->event_call; \
522523
struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\
523524
struct ring_buffer_event *event; \
524525
struct ftrace_raw_##call *entry; \

kernel/trace/trace.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ unsigned long long ns2usecs(cycle_t nsec)
189189
*/
190190
static struct trace_array global_trace;
191191

192+
LIST_HEAD(ftrace_trace_arrays);
193+
192194
static DEFINE_PER_CPU(struct trace_array_cpu, global_trace_cpu);
193195

194196
int filter_current_check_discard(struct ring_buffer *buffer,
@@ -5359,6 +5361,12 @@ __init static int tracer_alloc_buffers(void)
53595361

53605362
register_die_notifier(&trace_die_notifier);
53615363

5364+
global_trace.flags = TRACE_ARRAY_FL_GLOBAL;
5365+
5366+
INIT_LIST_HEAD(&global_trace.systems);
5367+
INIT_LIST_HEAD(&global_trace.events);
5368+
list_add(&global_trace.list, &ftrace_trace_arrays);
5369+
53625370
while (trace_boot_options) {
53635371
char *option;
53645372

kernel/trace/trace.h

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,39 @@ struct trace_array_cpu {
158158
*/
159159
struct trace_array {
160160
struct ring_buffer *buffer;
161+
struct list_head list;
161162
int cpu;
162163
int buffer_disabled;
164+
unsigned int flags;
163165
cycle_t time_start;
166+
struct dentry *dir;
167+
struct dentry *event_dir;
168+
struct list_head systems;
169+
struct list_head events;
164170
struct task_struct *waiter;
165171
struct trace_array_cpu *data[NR_CPUS];
166172
};
167173

174+
enum {
175+
TRACE_ARRAY_FL_GLOBAL = (1 << 0)
176+
};
177+
178+
extern struct list_head ftrace_trace_arrays;
179+
180+
/*
181+
* The global tracer (top) should be the first trace array added,
182+
* but we check the flag anyway.
183+
*/
184+
static inline struct trace_array *top_trace_array(void)
185+
{
186+
struct trace_array *tr;
187+
188+
tr = list_entry(ftrace_trace_arrays.prev,
189+
typeof(*tr), list);
190+
WARN_ON(!(tr->flags & TRACE_ARRAY_FL_GLOBAL));
191+
return tr;
192+
}
193+
168194
#define FTRACE_CMP_TYPE(var, type) \
169195
__builtin_types_compatible_p(typeof(var), type *)
170196

@@ -851,12 +877,19 @@ struct event_filter {
851877
struct event_subsystem {
852878
struct list_head list;
853879
const char *name;
854-
struct dentry *entry;
855880
struct event_filter *filter;
856-
int nr_events;
857881
int ref_count;
858882
};
859883

884+
struct ftrace_subsystem_dir {
885+
struct list_head list;
886+
struct event_subsystem *subsystem;
887+
struct trace_array *tr;
888+
struct dentry *entry;
889+
int ref_count;
890+
int nr_events;
891+
};
892+
860893
#define FILTER_PRED_INVALID ((unsigned short)-1)
861894
#define FILTER_PRED_IS_RIGHT (1 << 15)
862895
#define FILTER_PRED_FOLD (1 << 15)
@@ -914,7 +947,7 @@ extern void print_event_filter(struct ftrace_event_call *call,
914947
struct trace_seq *s);
915948
extern int apply_event_filter(struct ftrace_event_call *call,
916949
char *filter_string);
917-
extern int apply_subsystem_event_filter(struct event_subsystem *system,
950+
extern int apply_subsystem_event_filter(struct ftrace_subsystem_dir *dir,
918951
char *filter_string);
919952
extern void print_subsystem_event_filter(struct event_subsystem *system,
920953
struct trace_seq *s);

0 commit comments

Comments
 (0)