History

Merge branch 'tracing/ftrace' into tracing/core

Merge reason: this mini-topic had outstanding problems that delayed its merge, so it does not fast-forward.

Ingo Molnar committed 17 years ago

Commit 64edbc52 parents 43bd123 0f6ce3d9 files · +205 −86Browse files

Unified · Split

9 files
  1. Documentation/kernel-parameters.txt +15 −2
  2. include/linux/ftrace_event.h +1 −1
  3. include/trace/events/irq.h +12 −12
  4. include/trace/ftrace.h +90 −36
  5. kernel/trace/Kconfig +30 −30
  6. kernel/trace/ftrace.c +48 −2
  7. kernel/trace/trace.c +3 −0
  8. kernel/trace/trace_events_filter.c +3 −3
  9. kernel/trace/trace_output.c +3 −0
Documentation/kernel-parameters.txt+15−2
@@ -751,12 +751,25 @@ and is between 256 and 4096 characters. It is defined in the file · 750 unmodified lines
751751 ia64_pal_cache_flush instead of SAL_CACHE_FLUSH.
752752
753753 ftrace=[tracer]
754− [ftrace] will set and start the specified tracer
754+ [FTRACE] will set and start the specified tracer
755755 as early as possible in order to facilitate early
756756 boot debugging.
757757
758758 ftrace_dump_on_oops
759− [ftrace] will dump the trace buffers on oops.
759+ [FTRACE] will dump the trace buffers on oops.
760+
761+ ftrace_filter=[function-list]
762+ [FTRACE] Limit the functions traced by the function
763+ tracer at boot up. function-list is a comma separated
764+ list of functions. This list can be changed at run
765+ time by the set_ftrace_filter file in the debugfs
766+ tracing directory.
767+
768+ ftrace_notrace=[function-list]
769+ [FTRACE] Do not trace the functions specified in
770+ function-list. This list can be changed at run time
771+ by the set_ftrace_notrace file in the debugfs
772+ tracing directory.
760773
761774 gamecon.map[2|3]=
762775 [HW,JOY] Multisystem joystick and NES/SNES/PSX pad
include/linux/ftrace_event.h+1−1
@@ -51,6 +51,7 @@ struct trace_iterator { · 50 unmodified lines
5151 int cpu_file;
5252 struct mutex mutex;
5353 struct ring_buffer_iter *buffer_iter[NR_CPUS];
54+ unsigned long iter_flags;
5455
5556 /* The below is zeroed out in pipe_read */
5657 struct trace_seq seq;
@@ -58,7 +59,6 @@ struct trace_iterator { · 1 unmodified line
5859 int cpu;
5960 u64 ts;
6061
61− unsigned long iter_flags;
6262 loff_t pos;
6363 long idx;
6464
include/trace/events/irq.h+12−12
@@ -7,18 +7,18 @@ · 6 unmodified lines
77 #undef TRACE_SYSTEM
88 #define TRACE_SYSTEM irq
99
10−#define softirq_name(sirq) { sirq, #sirq }
11−#define show_softirq_name(val) \
12− __print_symbolic(val, \
13− softirq_name(HI_SOFTIRQ), \
14− softirq_name(TIMER_SOFTIRQ), \
15− softirq_name(NET_TX_SOFTIRQ), \
16− softirq_name(NET_RX_SOFTIRQ), \
17− softirq_name(BLOCK_SOFTIRQ), \
18− softirq_name(TASKLET_SOFTIRQ), \
19− softirq_name(SCHED_SOFTIRQ), \
20− softirq_name(HRTIMER_SOFTIRQ), \
21− softirq_name(RCU_SOFTIRQ))
10+#define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq }
11+#define show_softirq_name(val) \
12+ __print_symbolic(val, \
13+ softirq_name(HI), \
14+ softirq_name(TIMER), \
15+ softirq_name(NET_TX), \
16+ softirq_name(NET_RX), \
17+ softirq_name(BLOCK), \
18+ softirq_name(TASKLET), \
19+ softirq_name(SCHED), \
20+ softirq_name(HRTIMER), \
21+ softirq_name(RCU))
2222
2323 /**
2424 * irq_handler_entry - called immediately before the irq action handler
include/trace/ftrace.h+90−36
@@ -18,14 +18,17 @@ · 17 unmodified lines
1818
1919 #include <linux/ftrace_event.h>
2020
21+#undef __field
22+#define __field(type, item) type item;
23+
2124 #undef __array
2225 #define __array(type, item, len) type item[len];
2326
24−#undef __field
25−#define __field(type, item) type item;
27+#undef __dynamic_array
28+#define __dynamic_array(type, item, len) unsigned short __data_loc_##item;
2629
2730 #undef __string
28−#define __string(item, src) unsigned short __str_loc_##item;
31+#define __string(item, src) __dynamic_array(char, item, -1)
2932
3033 #undef TP_STRUCT__entry
3134 #define TP_STRUCT__entry(args...) args
@@ -35,7 +38,7 @@ · 3 unmodified lines
3538 struct ftrace_raw_##name { \
3639 struct trace_entry ent; \
3740 tstruct \
38− char __str_data[0]; \
41+ char __data[0]; \
3942 }; \
4043 static struct ftrace_event_call event_##name
4144
@@ -47,30 +50,31 @@ · 5 unmodified lines
4750 *
4851 * Include the following:
4952 *
50− * struct ftrace_str_offsets_<call> {
51− * int <str1>;
52− * int <str2>;
53+ * struct ftrace_data_offsets_<call> {
54+ * int <item1>;
55+ * int <item2>;
5356 * [...]
5457 * };
5558 *
56− * The __string() macro will create each int <str>, this is to
57− * keep the offset of each string from the beggining of the event
58− * once we perform the strlen() of the src strings.
59− *
59+ * The __dynamic_array() macro will create each int <item>, this is
60+ * to keep the offset of each array from the beginning of the event.
6061 */
6162
63+#undef __field
64+#define __field(type, item);
65+
6266 #undef __array
6367 #define __array(type, item, len)
6468
65−#undef __field
66−#define __field(type, item);
69+#undef __dynamic_array
70+#define __dynamic_array(type, item, len) int item;
6771
6872 #undef __string
69−#define __string(item, src) int item;
73+#define __string(item, src) __dynamic_array(char, item, -1)
7074
7175 #undef TRACE_EVENT
7276 #define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
73− struct ftrace_str_offsets_##call { \
77+ struct ftrace_data_offsets_##call { \
7478 tstruct; \
7579 };
7680
@@ -119,8 +123,12 @@ · 42 unmodified lines
119123 #undef TP_printk
120124 #define TP_printk(fmt, args...) fmt "\n", args
121125
126+#undef __get_dynamic_array
127+#define __get_dynamic_array(field) \
128+ ((void *)__entry + __entry->__data_loc_##field)
129+
122130 #undef __get_str
123−#define __get_str(field) ((char *)__entry + __entry->__str_loc_##field)
131+#define __get_str(field) (char *)__get_dynamic_array(field)
124132
125133 #undef __print_flags
126134 #define __print_flags(flag, delim, flag_array...) \
@@ -207,16 +215,19 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ · 80 unmodified lines
207215 if (!ret) \
208216 return 0;
209217
210−#undef __string
211−#define __string(item, src) \
212− ret = trace_seq_printf(s, "\tfield: __str_loc " #item ";\t" \
213− "offset:%u;tsize:%u;\n", \
218+#undef __dynamic_array
219+#define __dynamic_array(type, item, len) \
220+ ret = trace_seq_printf(s, "\tfield:__data_loc " #item ";\t" \
221+ "offset:%u;\tsize:%u;\n", \
214222 (unsigned int)offsetof(typeof(field), \
215− __str_loc_##item), \
216− (unsigned int)sizeof(field.__str_loc_##item)); \
223+ __data_loc_##item), \
224+ (unsigned int)sizeof(field.__data_loc_##item)); \
217225 if (!ret) \
218226 return 0;
219227
228+#undef __string
229+#define __string(item, src) __dynamic_array(char, item, -1)
230+
220231 #undef __entry
221232 #define __entry REC
222233
@@ -260,11 +271,14 @@ ftrace_format_##call(struct trace_seq *s) \ · 37 unmodified lines
260271 if (ret) \
261272 return ret;
262273
274+#undef __dynamic_array
275+#define __dynamic_array(type, item, len) \
276+ ret = trace_define_field(event_call, "__data_loc" "[" #type "]", #item,\
277+ offsetof(typeof(field), __data_loc_##item), \
278+ sizeof(field.__data_loc_##item), 0);
279+
263280 #undef __string
264−#define __string(item, src) \
265− ret = trace_define_field(event_call, "__str_loc", #item, \
266− offsetof(typeof(field), __str_loc_##item), \
267− sizeof(field.__str_loc_##item), 0);
281+#define __string(item, src) __dynamic_array(char, item, -1)
268282
269283 #undef TRACE_EVENT
270284 #define TRACE_EVENT(call, proto, args, tstruct, func, print) \
@@ -288,6 +302,43 @@ ftrace_define_fields_##call(void) \ · 17 unmodified lines
288302
289303 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
290304
305+/*
306+ * remember the offset of each array from the beginning of the event.
307+ */
308+
309+#undef __entry
310+#define __entry entry
311+
312+#undef __field
313+#define __field(type, item)
314+
315+#undef __array
316+#define __array(type, item, len)
317+
318+#undef __dynamic_array
319+#define __dynamic_array(type, item, len) \
320+ __data_offsets->item = __data_size + \
321+ offsetof(typeof(*entry), __data); \
322+ __data_size += (len) * sizeof(type);
323+
324+#undef __string
325+#define __string(item, src) __dynamic_array(char, item, strlen(src) + 1) \
326+
327+#undef TRACE_EVENT
328+#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
329+static inline int ftrace_get_offsets_##call( \
330+ struct ftrace_data_offsets_##call *__data_offsets, proto) \
331+{ \
332+ int __data_size = 0; \
333+ struct ftrace_raw_##call __maybe_unused *entry; \
334+ \
335+ tstruct; \
336+ \
337+ return __data_size; \
338+}
339+
340+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
341+
291342 /*
292343 * Stage 4 of the trace events.
293344 *
@@ -432,15 +483,15 @@ static void ftrace_profile_disable_##call(struct ftrace_event_call *event_call)\ · 138 unmodified lines
432483 #undef __array
433484 #define __array(type, item, len)
434485
486+#undef __dynamic_array
487+#define __dynamic_array(type, item, len) \
488+ __entry->__data_loc_##item = __data_offsets.item;
489+
435490 #undef __string
436−#define __string(item, src) \
437− __str_offsets.item = __str_size + \
438− offsetof(typeof(*entry), __str_data); \
439− __str_size += strlen(src) + 1;
491+#define __string(item, src) __dynamic_array(char, item, -1) \
440492
441493 #undef __assign_str
442494 #define __assign_str(dst, src) \
443− __entry->__str_loc_##dst = __str_offsets.dst; \
444495 strcpy(__get_str(dst), src);
445496
446497 #undef TRACE_EVENT
@@ -451,27 +502,30 @@ static struct ftrace_event_call event_##call; \ · 4 unmodified lines
451502 \
452503 static void ftrace_raw_event_##call(proto) \
453504 { \
454− struct ftrace_str_offsets_##call __maybe_unused __str_offsets; \
505+ struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\
455506 struct ftrace_event_call *event_call = &event_##call; \
456507 struct ring_buffer_event *event; \
457508 struct ftrace_raw_##call *entry; \
458509 unsigned long irq_flags; \
459− int __str_size = 0; \
510+ int __data_size; \
460511 int pc; \
461512 \
462513 local_save_flags(irq_flags); \
463514 pc = preempt_count(); \
464515 \
465− tstruct; \
516+ __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \
466517 \
467518 event = trace_current_buffer_lock_reserve(event_##call.id, \
468− sizeof(struct ftrace_raw_##call) + __str_size,\
519+ sizeof(*entry) + __data_size, \
469520 irq_flags, pc); \
470521 if (!event) \
471522 return; \
472523 entry = ring_buffer_event_data(event); \
473524 \
474− assign; \
525+ \
526+ tstruct \
527+ \
528+ { assign; } \
475529 \
476530 if (!filter_current_check_discard(event_call, entry, event)) \
477531 trace_nowake_buffer_unlock_commit(event, irq_flags, pc); \
kernel/trace/Kconfig+30−30
@@ -56,6 +56,13 @@ config CONTEXT_SWITCH_TRACER · 55 unmodified lines
5656 select MARKERS
5757 bool
5858
59+# All tracer options should select GENERIC_TRACER. For those options that are
60+# enabled by all tracers (context switch and event tracer) they select TRACING.
61+# This allows those options to appear when no other tracer is selected. But the
62+# options do not appear when something else selects it. We need the two options
63+# GENERIC_TRACER and TRACING to avoid circular dependencies to accomplish the
64+# hidding of the automatic options options.
65+
5966 config TRACING
6067 bool
6168 select DEBUG_FS
@@ -66,6 +73,10 @@ config TRACING · 4 unmodified lines
6673 select BINARY_PRINTF
6774 select EVENT_TRACING
6875
76+config GENERIC_TRACER
77+ bool
78+ select TRACING
79+
6980 #
7081 # Minimum requirements an architecture has to meet for us to
7182 # be able to offer generic tracing facilities:
@@ -95,7 +106,7 @@ config FUNCTION_TRACER · 23 unmodified lines
95106 depends on HAVE_FUNCTION_TRACER
96107 select FRAME_POINTER
97108 select KALLSYMS
98− select TRACING
109+ select GENERIC_TRACER
99110 select CONTEXT_SWITCH_TRACER
100111 help
101112 Enable the kernel to trace every kernel function. This is done
@@ -126,7 +137,7 @@ config IRQSOFF_TRACER · 24 unmodified lines
126137 depends on TRACE_IRQFLAGS_SUPPORT
127138 depends on GENERIC_TIME
128139 select TRACE_IRQFLAGS
129− select TRACING
140+ select GENERIC_TRACER
130141 select TRACER_MAX_TRACE
131142 help
132143 This option measures the time spent in irqs-off critical
@@ -147,7 +158,7 @@ config PREEMPT_TRACER · 14 unmodified lines
147158 default n
148159 depends on GENERIC_TIME
149160 depends on PREEMPT
150− select TRACING
161+ select GENERIC_TRACER
151162 select TRACER_MAX_TRACE
152163 help
153164 This option measures the time spent in preemption off critical
@@ -166,7 +177,7 @@ config PREEMPT_TRACER · 12 unmodified lines
166177 config SYSPROF_TRACER
167178 bool "Sysprof Tracer"
168179 depends on X86
169− select TRACING
180+ select GENERIC_TRACER
170181 select CONTEXT_SWITCH_TRACER
171182 help
172183 This tracer provides the trace needed by the 'Sysprof' userspace
@@ -174,44 +185,33 @@ config SYSPROF_TRACER · 1 unmodified line
174185
175186 config SCHED_TRACER
176187 bool "Scheduling Latency Tracer"
177− select TRACING
188+ select GENERIC_TRACER
178189 select CONTEXT_SWITCH_TRACER
179190 select TRACER_MAX_TRACE
180191 help
181192 This tracer tracks the latency of the highest priority task
182193 to be scheduled in, starting from the point it has woken up.
183194
184−config ENABLE_CONTEXT_SWITCH_TRACER
185− bool "Trace process context switches"
186− select TRACING
187− select CONTEXT_SWITCH_TRACER
188− help
189− This tracer gets called from the context switch and records
190− all switching of tasks.
191−
192−config ENABLE_EVENT_TRACING
193− bool "Trace various events in the kernel"
195+config ENABLE_DEFAULT_TRACERS
196+ bool "Trace process context switches and events"
197+ depends on !GENERIC_TRACER
194198 select TRACING
195199 help
196200 This tracer hooks to various trace points in the kernel
197201 allowing the user to pick and choose which trace point they
198− want to trace.
199−
200− Note, all tracers enable event tracing. This option is
201− only a convenience to enable event tracing when no other
202− tracers are selected.
202+ want to trace. It also includes the sched_switch tracer plugin.
203203
204204 config FTRACE_SYSCALLS
205205 bool "Trace syscalls"
206206 depends on HAVE_FTRACE_SYSCALLS
207− select TRACING
207+ select GENERIC_TRACER
208208 select KALLSYMS
209209 help
210210 Basic tracer to catch the syscall entry and exit events.
211211
212212 config BOOT_TRACER
213213 bool "Trace boot initcalls"
214− select TRACING
214+ select GENERIC_TRACER
215215 select CONTEXT_SWITCH_TRACER
216216 help
217217 This tracer helps developers to optimize boot times: it records
@@ -228,7 +228,7 @@ config BOOT_TRACER · 10 unmodified lines
228228
229229 config TRACE_BRANCH_PROFILING
230230 bool
231− select TRACING
231+ select GENERIC_TRACER
232232
233233 choice
234234 prompt "Branch Profiling"
@@ -308,7 +308,7 @@ config BRANCH_TRACER · 73 unmodified lines
308308 config POWER_TRACER
309309 bool "Trace power consumption behavior"
310310 depends on X86
311− select TRACING
311+ select GENERIC_TRACER
312312 help
313313 This tracer helps developers to analyze and optimize the kernels
314314 power management decisions, specifically the C-state and P-state
@@ -342,14 +342,14 @@ config STACK_TRACER · 27 unmodified lines
342342 config HW_BRANCH_TRACER
343343 depends on HAVE_HW_BRANCH_TRACER
344344 bool "Trace hw branches"
345− select TRACING
345+ select GENERIC_TRACER
346346 help
347347 This tracer records all branches on the system in a circular
348348 buffer giving access to the last N branches for each cpu.
349349
350350 config KMEMTRACE
351351 bool "Trace SLAB allocations"
352− select TRACING
352+ select GENERIC_TRACER
353353 help
354354 kmemtrace provides tracing for slab allocator functions, such as
355355 kmalloc, kfree, kmem_cache_alloc, kmem_cache_free etc.. Collected
@@ -369,7 +369,7 @@ config KMEMTRACE · 13 unmodified lines
369369
370370 config WORKQUEUE_TRACER
371371 bool "Trace workqueues"
372− select TRACING
372+ select GENERIC_TRACER
373373 help
374374 The workqueue tracer provides some statistical informations
375375 about each cpu workqueue thread such as the number of the
@@ -385,7 +385,7 @@ config BLK_DEV_IO_TRACE · 9 unmodified lines
385385 select RELAY
386386 select DEBUG_FS
387387 select TRACEPOINTS
388− select TRACING
388+ select GENERIC_TRACER
389389 select STACKTRACE
390390 help
391391 Say Y here if you want to be able to trace the block layer actions
@@ -446,7 +446,7 @@ config FTRACE_SELFTEST · 54 unmodified lines
446446
447447 config FTRACE_STARTUP_TEST
448448 bool "Perform a startup test on ftrace"
449− depends on TRACING
449+ depends on GENERIC_TRACER
450450 select FTRACE_SELFTEST
451451 help
452452 This option performs a series of startup tests on ftrace. On bootup
@@ -457,7 +457,7 @@ config FTRACE_STARTUP_TEST · 4 unmodified lines
457457 config MMIOTRACE
458458 bool "Memory mapped IO tracing"
459459 depends on HAVE_MMIOTRACE_SUPPORT && PCI
460− select TRACING
460+ select GENERIC_TRACER
461461 help
462462 Mmiotrace traces Memory Mapped I/O access and is meant for
463463 debugging and reverse engineering. It is called from the ioremap
kernel/trace/ftrace.c+48−2
@@ -32,6 +32,7 @@ · 31 unmodified lines
3232 #include <trace/events/sched.h>
3333
3434 #include <asm/ftrace.h>
35+#include <asm/setup.h>
3536
3637 #include "trace_output.h"
3738 #include "trace_stat.h"
@@ -598,7 +599,7 @@ function_profile_call(unsigned long ip, unsigned long parent_ip) · 560 unmodified lines
598599 local_irq_save(flags);
599600
600601 stat = &__get_cpu_var(ftrace_profile_stats);
601− if (!stat->hash)
602+ if (!stat->hash || !ftrace_profile_enabled)
602603 goto out;
603604
604605 rec = ftrace_find_profiled_func(stat, ip);
@@ -629,7 +630,7 @@ static void profile_graph_return(struct ftrace_graph_ret *trace) · 24 unmodified lines
629630
630631 local_irq_save(flags);
631632 stat = &__get_cpu_var(ftrace_profile_stats);
632− if (!stat->hash)
633+ if (!stat->hash || !ftrace_profile_enabled)
633634 goto out;
634635
635636 calltime = trace->rettime - trace->calltime;
@@ -723,6 +724,10 @@ ftrace_profile_write(struct file *filp, const char __user *ubuf, · 87 unmodified lines
723724 ftrace_profile_enabled = 1;
724725 } else {
725726 ftrace_profile_enabled = 0;
727+ /*
728+ * unregister_ftrace_profiler calls stop_machine
729+ * so this acts like an synchronize_sched.
730+ */
726731 unregister_ftrace_profiler();
727732 }
728733 }
@@ -2369,6 +2374,45 @@ void ftrace_set_notrace(unsigned char *buf, int len, int reset) · 1640 unmodified lines
23692374 ftrace_set_regex(buf, len, reset, 0);
23702375 }
23712376
2377+/*
2378+ * command line interface to allow users to set filters on boot up.
2379+ */
2380+#define FTRACE_FILTER_SIZE COMMAND_LINE_SIZE
2381+static char ftrace_notrace_buf[FTRACE_FILTER_SIZE] __initdata;
2382+static char ftrace_filter_buf[FTRACE_FILTER_SIZE] __initdata;
2383+
2384+static int __init set_ftrace_notrace(char *str)
2385+{
2386+ strncpy(ftrace_notrace_buf, str, FTRACE_FILTER_SIZE);
2387+ return 1;
2388+}
2389+__setup("ftrace_notrace=", set_ftrace_notrace);
2390+
2391+static int __init set_ftrace_filter(char *str)
2392+{
2393+ strncpy(ftrace_filter_buf, str, FTRACE_FILTER_SIZE);
2394+ return 1;
2395+}
2396+__setup("ftrace_filter=", set_ftrace_filter);
2397+
2398+static void __init set_ftrace_early_filter(char *buf, int enable)
2399+{
2400+ char *func;
2401+
2402+ while (buf) {
2403+ func = strsep(&buf, ",");
2404+ ftrace_set_regex(func, strlen(func), 0, enable);
2405+ }
2406+}
2407+
2408+static void __init set_ftrace_early_filters(void)
2409+{
2410+ if (ftrace_filter_buf[0])
2411+ set_ftrace_early_filter(ftrace_filter_buf, 1);
2412+ if (ftrace_notrace_buf[0])
2413+ set_ftrace_early_filter(ftrace_notrace_buf, 0);
2414+}
2415+
23722416 static int
23732417 ftrace_regex_release(struct inode *inode, struct file *file, int enable)
23742418 {
@@ -2829,6 +2873,8 @@ void __init ftrace_init(void) · 454 unmodified lines
28292873 if (ret)
28302874 pr_warning("Failed to register trace ftrace module notifier\n");
28312875
2876+ set_ftrace_early_filters();
2877+
28322878 return;
28332879 failed:
28342880 ftrace_disabled = 1;
kernel/trace/trace.c+3−0
@@ -2826,6 +2826,9 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) · 2825 unmodified lines
28262826 /* trace pipe does not show start of buffer */
28272827 cpumask_setall(iter->started);
28282828
2829+ if (trace_flags & TRACE_ITER_LATENCY_FMT)
2830+ iter->iter_flags |= TRACE_FILE_LAT_FMT;
2831+
28292832 iter->cpu_file = cpu_file;
28302833 iter->tr = &global_trace;
28312834 mutex_init(&iter->mutex);
kernel/trace/trace_events_filter.c+3−3
@@ -478,12 +478,12 @@ enum { · 477 unmodified lines
478478
479479 static int is_string_field(const char *type)
480480 {
481+ if (strstr(type, "__data_loc") && strstr(type, "char"))
482+ return FILTER_DYN_STRING;
483+
481484 if (strchr(type, '[') && strstr(type, "char"))
482485 return FILTER_STATIC_STRING;
483486
484− if (!strcmp(type, "__str_loc"))
485− return FILTER_DYN_STRING;
486−
487487 return 0;
488488 }
489489
kernel/trace/trace_output.c+3−0
@@ -17,6 +17,7 @@ · 16 unmodified lines
1717 static DECLARE_RWSEM(trace_event_mutex);
1818
1919 DEFINE_PER_CPU(struct trace_seq, ftrace_event_seq);
20+EXPORT_PER_CPU_SYMBOL(ftrace_event_seq);
2021
2122 static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly;
2223
@@ -250,6 +251,7 @@ ftrace_print_flags_seq(struct trace_seq *p, const char *delim, · 227 unmodified lines
250251
251252 return p->buffer;
252253 }
254+EXPORT_SYMBOL(ftrace_print_flags_seq);
253255
254256 const char *
255257 ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val,
@@ -275,6 +277,7 @@ ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val, · 19 unmodified lines
275277
276278 return p->buffer;
277279 }
280+EXPORT_SYMBOL(ftrace_print_symbols_seq);
278281
279282 #ifdef CONFIG_KRETPROBES
280283 static inline const char *kretprobed(const char *name)