History

Merge tag 'trace-v6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull tracing updates from Steven Rostedt: - Add function names as a way to filter function addresses - Add sample module to test ftrace ops and dynamic trampolines - Allow stack traces to be passed from beginning event to end event for synthetic events. This will allow seeing the stack trace of when a task is scheduled out and recorded when it gets scheduled back in. - Add trace event helper __get_buf() to use as a temporary buffer when printing out trace event output. - Add kernel command line to create trace instances on boot up. - Add enabling of events to instances created at boot up. - Add trace_array_puts() to write into instances. - Allow boot instances to take a snapshot at the end of boot up. - Allow live patch modules to include trace events - Minor fixes and clean ups * tag 'trace-v6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: (31 commits) tracing: Remove unnecessary NULL assignment tracepoint: Allow livepatch module add trace event tracing: Always use canonical ftrace path tracing/histogram: Fix stacktrace histogram Documententation tracing/histogram: Fix stacktrace key tracing/histogram: Fix a few problems with stacktrace variable printing tracing: Add BUILD_BUG() to make sure stacktrace fits in strings tracing/histogram: Don't use strlen to find length of stacktrace variables tracing: Allow boot instances to have snapshot buffers tracing: Add trace_array_puts() to write into instance tracing: Add enabling of events to boot instances tracing: Add creation of instances at boot command line tracing: Fix trace_event_raw_event_synth() if else statement samples: ftrace: Make some global variables static ftrace: sample: avoid open-coded 64-bit division samples: ftrace: Include the nospec-branch.h only for x86 tracing: Acquire buffer from temparary trace sequence tracing/histogram: Wrap remaining shell snippets in code blocks tracing/osnoise: No need for schedule_hrtimeout range bpf/tracing: Use stage6 of tracing to not duplicate macros ...

Linus Torvalds committed 3 years ago

Commit b72b5fe2 parents 9191423 7568a2142 files · +1113 −221Browse files

Unified · Split

42 files
  1. Documentation/admin-guide/kernel-parameters.txt +29 −0
  2. Documentation/trace/events.rst +12 −0
  3. Documentation/trace/histogram.rst +198 −44
  4. include/linux/kernel.h +1 −1
  5. include/linux/trace.h +12 −0
  6. include/linux/trace_seq.h +5 −0
  7. include/linux/tracepoint.h +2 −2
  8. include/trace/bpf_probe.h +1 −44
  9. include/trace/perf.h +1 −45
  10. include/trace/stages/stage3_trace_output.h +3 −0
  11. include/trace/stages/stage6_event_callback.h +3 −0
  12. include/trace/stages/stage7_class_define.h +1 −0
  13. kernel/trace/Kconfig +10 −10
  14. kernel/trace/kprobe_event_gen_test.c +1 −1
  15. kernel/trace/ring_buffer.c +7 −2
  16. kernel/trace/synth_event_gen_test.c +1 −1
  17. kernel/trace/trace.c +145 −19
  18. kernel/trace/trace.h +6 −0
  19. kernel/trace/trace_events.c +5 −8
  20. kernel/trace/trace_events_filter.c +92 −1
  21. kernel/trace/trace_events_hist.c +103 −23
  22. kernel/trace/trace_events_synth.c +86 −4
  23. kernel/trace/trace_osnoise.c +1 −1
  24. kernel/trace/trace_seq.c +23 −0
  25. kernel/trace/trace_synth.h +1 −0
  26. kernel/tracepoint.c +2 −2
  27. samples/Kconfig +7 −0
  28. samples/Makefile +1 −0
  29. samples/ftrace/Makefile +1 −0
  30. samples/ftrace/ftrace-direct-modify.c +1 −1
  31. samples/ftrace/ftrace-direct-multi-modify.c +1 −1
  32. samples/ftrace/ftrace-direct-multi.c +1 −1
  33. samples/ftrace/ftrace-direct-too.c +1 −1
  34. samples/ftrace/ftrace-direct.c +1 −1
  35. samples/ftrace/ftrace-ops.c +252 −0
  36. samples/user_events/example.c +2 −2
  37. scripts/tracing/draw_functrace.py +3 −3
  38. tools/lib/api/fs/tracing_path.c +2 −2
  39. tools/testing/selftests/ftrace/test.d/filter/event-filter-function.tc +58 −0
  40. tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-stack.tc +24 −0
  41. tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-syntax.tc +6 −0
  42. tools/tracing/latency/latency-collector.c +1 −1
Documentation/admin-guide/kernel-parameters.txt+29−0
@@ -1509,6 +1509,15 @@ · 1508 unmodified lines
15091509 boot up that is likely to be overridden by user space
15101510 start up functionality.
15111511
1512+ Optionally, the snapshot can also be defined for a tracing
1513+ instance that was created by the trace_instance= command
1514+ line parameter.
1515+
1516+ trace_instance=foo,sched_switch ftrace_boot_snapshot=foo
1517+
1518+ The above will cause the "foo" tracing instance to trigger
1519+ a snapshot at the end of boot up.
1520+
15121521 ftrace_dump_on_oops[=orig_cpu]
15131522 [FTRACE] will dump the trace buffers on oops.
15141523 If no parameter is passed, ftrace will dump
@@ -6283,6 +6292,26 @@ · 4768 unmodified lines
62836292 comma-separated list of trace events to enable. See
62846293 also Documentation/trace/events.rst
62856294
6295+ trace_instance=[instance-info]
6296+ [FTRACE] Create a ring buffer instance early in boot up.
6297+ This will be listed in:
6298+
6299+ /sys/kernel/tracing/instances
6300+
6301+ Events can be enabled at the time the instance is created
6302+ via:
6303+
6304+ trace_instance=<name>,<system1>:<event1>,<system2>:<event2>
6305+
6306+ Note, the "<system*>:" portion is optional if the event is
6307+ unique.
6308+
6309+ trace_instance=foo,sched:sched_switch,irq_handler_entry,initcall
6310+
6311+ will enable the "sched_switch" event (note, the "sched:" is optional, and
6312+ the same thing would happen if it was left off). The irq_handler_entry
6313+ event, and all events under the "initcall" system.
6314+
62866315 trace_options=[option-list]
62876316 [FTRACE] Enable or disable tracer options at boot.
62886317 The option-list is a comma delimited list of options
Documentation/trace/events.rst+12−0
@@ -207,6 +207,18 @@ field name:: · 206 unmodified lines
207207 As the kernel will have to know how to retrieve the memory that the pointer
208208 is at from user space.
209209
210+You can convert any long type to a function address and search by function name::
211+
212+ call_site.function == security_prepare_creds
213+
214+The above will filter when the field "call_site" falls on the address within
215+"security_prepare_creds". That is, it will compare the value of "call_site" and
216+the filter will return true if it is greater than or equal to the start of
217+the function "security_prepare_creds" and less than the end of that function.
218+
219+The ".function" postfix can only be attached to values of size long, and can only
220+be compared with "==" or "!=".
221+
210222 5.2 Setting filters
211223 -------------------
212224
Documentation/trace/histogram.rst+198−44
@@ -81,6 +81,7 @@ Documentation written by Tom Zanussi · 80 unmodified lines
8181 .usecs display a common_timestamp in microseconds
8282 .percent display a number of percentage value
8383 .graph display a bar-graph of a value
84+ .stacktrace display as a stacktrace (must by a long[] type)
8485 ============= =================================================
8586
8687 Note that in general the semantics of a given field aren't
@@ -1786,6 +1787,8 @@ or assigned to a variable and referenced in a subsequent expression:: · 1699 unmodified lines
17861787 # echo 'hist:keys=next_pid:us_per_sec=1000000 ...' >> event/trigger
17871788 # echo 'hist:keys=next_pid:timestamp_secs=common_timestamp/$us_per_sec ...' >> event/trigger
17881789
1790+Variables can even hold stacktraces, which are useful with synthetic events.
1791+
17891792 2.2.2 Synthetic Events
17901793 ----------------------
17911794
@@ -1861,7 +1864,7 @@ A histogram can now be defined for the new synthetic event:: · 69 unmodified lines
18611864 The above shows the latency "lat" in a power of 2 grouping.
18621865
18631866 Like any other event, once a histogram is enabled for the event, the
1864−output can be displayed by reading the event's 'hist' file.
1867+output can be displayed by reading the event's 'hist' file::
18651868
18661869 # cat /sys/kernel/tracing/events/synthetic/wakeup_latency/hist
18671870
@@ -1908,7 +1911,7 @@ output can be displayed by reading the event's 'hist' file. · 40 unmodified lines
19081911
19091912
19101913 The latency values can also be grouped linearly by a given size with
1911−the ".buckets" modifier and specify a size (in this case groups of 10).
1914+the ".buckets" modifier and specify a size (in this case groups of 10)::
19121915
19131916 # echo 'hist:keys=pid,prio,lat.buckets=10:sort=lat' >> \
19141917 /sys/kernel/tracing/events/synthetic/wakeup_latency/trigger
@@ -1940,6 +1943,157 @@ the ".buckets" modifier and specify a size (in this case groups of 10). · 25 unmodified lines
19401943 Entries: 16
19411944 Dropped: 0
19421945
1946+To save stacktraces, create a synthetic event with a field of type "unsigned long[]"
1947+or even just "long[]". For example, to see how long a task is blocked in an
1948+uninterruptible state::
1949+
1950+ # cd /sys/kernel/tracing
1951+ # echo 's:block_lat pid_t pid; u64 delta; unsigned long[] stack;' > dynamic_events
1952+ # echo 'hist:keys=next_pid:ts=common_timestamp.usecs,st=stacktrace if prev_state == 2' >> events/sched/sched_switch/trigger
1953+ # echo 'hist:keys=prev_pid:delta=common_timestamp.usecs-$ts,s=$st:onmax($delta).trace(block_lat,prev_pid,$delta,$s)' >> events/sched/sched_switch/trigger
1954+ # echo 1 > events/synthetic/block_lat/enable
1955+ # cat trace
1956+
1957+ # tracer: nop
1958+ #
1959+ # entries-in-buffer/entries-written: 2/2 #P:8
1960+ #
1961+ # _-----=> irqs-off/BH-disabled
1962+ # / _----=> need-resched
1963+ # | / _---=> hardirq/softirq
1964+ # || / _--=> preempt-depth
1965+ # ||| / _-=> migrate-disable
1966+ # |||| / delay
1967+ # TASK-PID CPU# ||||| TIMESTAMP FUNCTION
1968+ # | | | ||||| | |
1969+ <idle>-0 [005] d..4. 521.164922: block_lat: pid=0 delta=8322 stack=STACK:
1970+ => __schedule+0x448/0x7b0
1971+ => schedule+0x5a/0xb0
1972+ => io_schedule+0x42/0x70
1973+ => bit_wait_io+0xd/0x60
1974+ => __wait_on_bit+0x4b/0x140
1975+ => out_of_line_wait_on_bit+0x91/0xb0
1976+ => jbd2_journal_commit_transaction+0x1679/0x1a70
1977+ => kjournald2+0xa9/0x280
1978+ => kthread+0xe9/0x110
1979+ => ret_from_fork+0x2c/0x50
1980+
1981+ <...>-2 [004] d..4. 525.184257: block_lat: pid=2 delta=76 stack=STACK:
1982+ => __schedule+0x448/0x7b0
1983+ => schedule+0x5a/0xb0
1984+ => schedule_timeout+0x11a/0x150
1985+ => wait_for_completion_killable+0x144/0x1f0
1986+ => __kthread_create_on_node+0xe7/0x1e0
1987+ => kthread_create_on_node+0x51/0x70
1988+ => create_worker+0xcc/0x1a0
1989+ => worker_thread+0x2ad/0x380
1990+ => kthread+0xe9/0x110
1991+ => ret_from_fork+0x2c/0x50
1992+
1993+A synthetic event that has a stacktrace field may use it as a key in
1994+histogram::
1995+
1996+ # echo 'hist:keys=delta.buckets=100,stack.stacktrace:sort=delta' > events/synthetic/block_lat/trigger
1997+ # cat events/synthetic/block_lat/hist
1998+
1999+ # event histogram
2000+ #
2001+ # trigger info: hist:keys=delta.buckets=100,stack.stacktrace:vals=hitcount:sort=delta.buckets=100:size=2048 [active]
2002+ #
2003+ { delta: ~ 0-99, stack.stacktrace __schedule+0xa19/0x1520
2004+ schedule+0x6b/0x110
2005+ io_schedule+0x46/0x80
2006+ bit_wait_io+0x11/0x80
2007+ __wait_on_bit+0x4e/0x120
2008+ out_of_line_wait_on_bit+0x8d/0xb0
2009+ __wait_on_buffer+0x33/0x40
2010+ jbd2_journal_commit_transaction+0x155a/0x19b0
2011+ kjournald2+0xab/0x270
2012+ kthread+0xfa/0x130
2013+ ret_from_fork+0x29/0x50
2014+ } hitcount: 1
2015+ { delta: ~ 0-99, stack.stacktrace __schedule+0xa19/0x1520
2016+ schedule+0x6b/0x110
2017+ io_schedule+0x46/0x80
2018+ rq_qos_wait+0xd0/0x170
2019+ wbt_wait+0x9e/0xf0
2020+ __rq_qos_throttle+0x25/0x40
2021+ blk_mq_submit_bio+0x2c3/0x5b0
2022+ __submit_bio+0xff/0x190
2023+ submit_bio_noacct_nocheck+0x25b/0x2b0
2024+ submit_bio_noacct+0x20b/0x600
2025+ submit_bio+0x28/0x90
2026+ ext4_bio_write_page+0x1e0/0x8c0
2027+ mpage_submit_page+0x60/0x80
2028+ mpage_process_page_bufs+0x16c/0x180
2029+ mpage_prepare_extent_to_map+0x23f/0x530
2030+ } hitcount: 1
2031+ { delta: ~ 0-99, stack.stacktrace __schedule+0xa19/0x1520
2032+ schedule+0x6b/0x110
2033+ schedule_hrtimeout_range_clock+0x97/0x110
2034+ schedule_hrtimeout_range+0x13/0x20
2035+ usleep_range_state+0x65/0x90
2036+ __intel_wait_for_register+0x1c1/0x230 [i915]
2037+ intel_psr_wait_for_idle_locked+0x171/0x2a0 [i915]
2038+ intel_pipe_update_start+0x169/0x360 [i915]
2039+ intel_update_crtc+0x112/0x490 [i915]
2040+ skl_commit_modeset_enables+0x199/0x600 [i915]
2041+ intel_atomic_commit_tail+0x7c4/0x1080 [i915]
2042+ intel_atomic_commit_work+0x12/0x20 [i915]
2043+ process_one_work+0x21c/0x3f0
2044+ worker_thread+0x50/0x3e0
2045+ kthread+0xfa/0x130
2046+ } hitcount: 3
2047+ { delta: ~ 0-99, stack.stacktrace __schedule+0xa19/0x1520
2048+ schedule+0x6b/0x110
2049+ schedule_timeout+0x11e/0x160
2050+ __wait_for_common+0x8f/0x190
2051+ wait_for_completion+0x24/0x30
2052+ __flush_work.isra.0+0x1cc/0x360
2053+ flush_work+0xe/0x20
2054+ drm_mode_rmfb+0x18b/0x1d0 [drm]
2055+ drm_mode_rmfb_ioctl+0x10/0x20 [drm]
2056+ drm_ioctl_kernel+0xb8/0x150 [drm]
2057+ drm_ioctl+0x243/0x560 [drm]
2058+ __x64_sys_ioctl+0x92/0xd0
2059+ do_syscall_64+0x59/0x90
2060+ entry_SYSCALL_64_after_hwframe+0x72/0xdc
2061+ } hitcount: 1
2062+ { delta: ~ 0-99, stack.stacktrace __schedule+0xa19/0x1520
2063+ schedule+0x6b/0x110
2064+ schedule_timeout+0x87/0x160
2065+ __wait_for_common+0x8f/0x190
2066+ wait_for_completion_timeout+0x1d/0x30
2067+ drm_atomic_helper_wait_for_flip_done+0x57/0x90 [drm_kms_helper]
2068+ intel_atomic_commit_tail+0x8ce/0x1080 [i915]
2069+ intel_atomic_commit_work+0x12/0x20 [i915]
2070+ process_one_work+0x21c/0x3f0
2071+ worker_thread+0x50/0x3e0
2072+ kthread+0xfa/0x130
2073+ ret_from_fork+0x29/0x50
2074+ } hitcount: 1
2075+ { delta: ~ 100-199, stack.stacktrace __schedule+0xa19/0x1520
2076+ schedule+0x6b/0x110
2077+ schedule_hrtimeout_range_clock+0x97/0x110
2078+ schedule_hrtimeout_range+0x13/0x20
2079+ usleep_range_state+0x65/0x90
2080+ pci_set_low_power_state+0x17f/0x1f0
2081+ pci_set_power_state+0x49/0x250
2082+ pci_finish_runtime_suspend+0x4a/0x90
2083+ pci_pm_runtime_suspend+0xcb/0x1b0
2084+ __rpm_callback+0x48/0x120
2085+ rpm_callback+0x67/0x70
2086+ rpm_suspend+0x167/0x780
2087+ rpm_idle+0x25a/0x380
2088+ pm_runtime_work+0x93/0xc0
2089+ process_one_work+0x21c/0x3f0
2090+ } hitcount: 1
2091+
2092+ Totals:
2093+ Hits: 10
2094+ Entries: 7
2095+ Dropped: 0
2096+
19432097 2.2.3 Hist trigger 'handlers' and 'actions'
19442098 -------------------------------------------
19452099
@@ -2054,11 +2208,11 @@ The following commonly-used handler.action pairs are available: · 108 unmodified lines
20542208 wakeup_new_test($testpid) if comm=="cyclictest"' >> \
20552209 /sys/kernel/tracing/events/sched/sched_wakeup_new/trigger
20562210
2057− Or, equivalently, using the 'trace' keyword syntax:
2211+ Or, equivalently, using the 'trace' keyword syntax::
20582212
2059− # echo 'hist:keys=$testpid:testpid=pid:onmatch(sched.sched_wakeup_new).\
2060− trace(wakeup_new_test,$testpid) if comm=="cyclictest"' >> \
2061− /sys/kernel/tracing/events/sched/sched_wakeup_new/trigger
2213+ # echo 'hist:keys=$testpid:testpid=pid:onmatch(sched.sched_wakeup_new).\
2214+ trace(wakeup_new_test,$testpid) if comm=="cyclictest"' >> \
2215+ /sys/kernel/tracing/events/sched/sched_wakeup_new/trigger
20622216
20632217 Creating and displaying a histogram based on those events is now
20642218 just a matter of using the fields and new synthetic event in the
@@ -2191,48 +2345,48 @@ The following commonly-used handler.action pairs are available: · 126 unmodified lines
21912345 resulting latency, stored in wakeup_lat, exceeds the current
21922346 maximum latency, a snapshot is taken. As part of the setup, all
21932347 the scheduler events are also enabled, which are the events that
2194− will show up in the snapshot when it is taken at some point:
2348+ will show up in the snapshot when it is taken at some point::
21952349
2196− # echo 1 > /sys/kernel/tracing/events/sched/enable
2350+ # echo 1 > /sys/kernel/tracing/events/sched/enable
21972351
2198− # echo 'hist:keys=pid:ts0=common_timestamp.usecs \
2199− if comm=="cyclictest"' >> \
2200− /sys/kernel/tracing/events/sched/sched_waking/trigger
2352+ # echo 'hist:keys=pid:ts0=common_timestamp.usecs \
2353+ if comm=="cyclictest"' >> \
2354+ /sys/kernel/tracing/events/sched/sched_waking/trigger
22012355
2202− # echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0: \
2203− onmax($wakeup_lat).save(next_prio,next_comm,prev_pid,prev_prio, \
2204− prev_comm):onmax($wakeup_lat).snapshot() \
2205− if next_comm=="cyclictest"' >> \
2206− /sys/kernel/tracing/events/sched/sched_switch/trigger
2356+ # echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0: \
2357+ onmax($wakeup_lat).save(next_prio,next_comm,prev_pid,prev_prio, \
2358+ prev_comm):onmax($wakeup_lat).snapshot() \
2359+ if next_comm=="cyclictest"' >> \
2360+ /sys/kernel/tracing/events/sched/sched_switch/trigger
22072361
22082362 When the histogram is displayed, for each bucket the max value
22092363 and the saved values corresponding to the max are displayed
22102364 following the rest of the fields.
22112365
22122366 If a snapshot was taken, there is also a message indicating that,
2213− along with the value and event that triggered the global maximum:
2367+ along with the value and event that triggered the global maximum::
22142368
2215− # cat /sys/kernel/tracing/events/sched/sched_switch/hist
2216− { next_pid: 2101 } hitcount: 200
2217− max: 52 next_prio: 120 next_comm: cyclictest \
2218− prev_pid: 0 prev_prio: 120 prev_comm: swapper/6
2369+ # cat /sys/kernel/tracing/events/sched/sched_switch/hist
2370+ { next_pid: 2101 } hitcount: 200
2371+ max: 52 next_prio: 120 next_comm: cyclictest \
2372+ prev_pid: 0 prev_prio: 120 prev_comm: swapper/6
22192373
2220− { next_pid: 2103 } hitcount: 1326
2221− max: 572 next_prio: 19 next_comm: cyclictest \
2222− prev_pid: 0 prev_prio: 120 prev_comm: swapper/1
2374+ { next_pid: 2103 } hitcount: 1326
2375+ max: 572 next_prio: 19 next_comm: cyclictest \
2376+ prev_pid: 0 prev_prio: 120 prev_comm: swapper/1
22232377
2224− { next_pid: 2102 } hitcount: 1982 \
2225− max: 74 next_prio: 19 next_comm: cyclictest \
2226− prev_pid: 0 prev_prio: 120 prev_comm: swapper/5
2378+ { next_pid: 2102 } hitcount: 1982 \
2379+ max: 74 next_prio: 19 next_comm: cyclictest \
2380+ prev_pid: 0 prev_prio: 120 prev_comm: swapper/5
22272381
2228− Snapshot taken (see tracing/snapshot). Details:
2229− triggering value { onmax($wakeup_lat) }: 572 \
2230− triggered by event with key: { next_pid: 2103 }
2382+ Snapshot taken (see tracing/snapshot). Details:
2383+ triggering value { onmax($wakeup_lat) }: 572 \
2384+ triggered by event with key: { next_pid: 2103 }
22312385
2232− Totals:
2233− Hits: 3508
2234− Entries: 3
2235− Dropped: 0
2386+ Totals:
2387+ Hits: 3508
2388+ Entries: 3
2389+ Dropped: 0
22362390
22372391 In the above case, the event that triggered the global maximum has
22382392 the key with next_pid == 2103. If you look at the bucket that has
@@ -2310,15 +2464,15 @@ The following commonly-used handler.action pairs are available: · 71 unmodified lines
23102464 $cwnd variable. If the value has changed, a snapshot is taken.
23112465 As part of the setup, all the scheduler and tcp events are also
23122466 enabled, which are the events that will show up in the snapshot
2313− when it is taken at some point:
2467+ when it is taken at some point::
23142468
2315− # echo 1 > /sys/kernel/tracing/events/sched/enable
2316− # echo 1 > /sys/kernel/tracing/events/tcp/enable
2469+ # echo 1 > /sys/kernel/tracing/events/sched/enable
2470+ # echo 1 > /sys/kernel/tracing/events/tcp/enable
23172471
2318− # echo 'hist:keys=dport:cwnd=snd_cwnd: \
2319− onchange($cwnd).save(snd_wnd,srtt,rcv_wnd): \
2320− onchange($cwnd).snapshot()' >> \
2321− /sys/kernel/tracing/events/tcp/tcp_probe/trigger
2472+ # echo 'hist:keys=dport:cwnd=snd_cwnd: \
2473+ onchange($cwnd).save(snd_wnd,srtt,rcv_wnd): \
2474+ onchange($cwnd).snapshot()' >> \
2475+ /sys/kernel/tracing/events/tcp/tcp_probe/trigger
23222476
23232477 When the histogram is displayed, for each bucket the tracked value
23242478 and the saved values corresponding to that value are displayed
@@ -2341,10 +2495,10 @@ The following commonly-used handler.action pairs are available: · 16 unmodified lines
23412495 { dport: 443 } hitcount: 211
23422496 changed: 10 snd_wnd: 26960 srtt: 17379 rcv_wnd: 28800
23432497
2344− Snapshot taken (see tracing/snapshot). Details::
2498+ Snapshot taken (see tracing/snapshot). Details:
23452499
2346− triggering value { onchange($cwnd) }: 10
2347− triggered by event with key: { dport: 80 }
2500+ triggering value { onchange($cwnd) }: 10
2501+ triggered by event with key: { dport: 80 }
23482502
23492503 Totals:
23502504 Hits: 414
include/linux/kernel.h+1−1
@@ -297,7 +297,7 @@ bool mac_pton(const char *s, u8 *mac); · 296 unmodified lines
297297 *
298298 * Use tracing_on/tracing_off when you want to quickly turn on or off
299299 * tracing. It simply enables or disables the recording of the trace events.
300− * This also corresponds to the user space /sys/kernel/debug/tracing/tracing_on
300+ * This also corresponds to the user space /sys/kernel/tracing/tracing_on
301301 * file, which gives a means for the kernel and userspace to interact.
302302 * Place a tracing_off() in the kernel where you want tracing to end.
303303 * From user space, examine the trace, and then echo 1 > tracing_on
include/linux/trace.h+12−0
@@ -33,6 +33,18 @@ struct trace_array; · 32 unmodified lines
3333 int register_ftrace_export(struct trace_export *export);
3434 int unregister_ftrace_export(struct trace_export *export);
3535
36+/**
37+ * trace_array_puts - write a constant string into the trace buffer.
38+ * @tr: The trace array to write to
39+ * @str: The constant string to write
40+ */
41+#define trace_array_puts(tr, str) \
42+ ({ \
43+ str ? __trace_array_puts(tr, _THIS_IP_, str, strlen(str)) : -1; \
44+ })
45+int __trace_array_puts(struct trace_array *tr, unsigned long ip,
46+ const char *str, int size);
47+
3648 void trace_printk_init_buffers(void);
3749 __printf(3, 4)
3850 int trace_array_printk(struct trace_array *tr, unsigned long ip,
include/linux/trace_seq.h+5−0
@@ -95,6 +95,7 @@ extern void trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, · 94 unmodified lines
9595 extern int trace_seq_hex_dump(struct trace_seq *s, const char *prefix_str,
9696 int prefix_type, int rowsize, int groupsize,
9797 const void *buf, size_t len, bool ascii);
98+char *trace_seq_acquire(struct trace_seq *s, unsigned int len);
9899
99100 #else /* CONFIG_TRACING */
100101 static inline __printf(2, 3)
@@ -139,6 +140,10 @@ static inline int trace_seq_path(struct trace_seq *s, const struct path *path) · 38 unmodified lines
139140 {
140141 return 0;
141142 }
143+static inline char *trace_seq_acquire(struct trace_seq *s, unsigned int len)
144+{
145+ return NULL;
146+}
142147 #endif /* CONFIG_TRACING */
143148
144149 #endif /* _LINUX_TRACE_SEQ_H */
include/linux/tracepoint.h+2−2
@@ -482,7 +482,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) · 481 unmodified lines
482482 * * This is how the trace record is structured and will
483483 * * be saved into the ring buffer. These are the fields
484484 * * that will be exposed to user-space in
485− * * /sys/kernel/debug/tracing/events/<*>/format.
485+ * * /sys/kernel/tracing/events/<*>/format.
486486 * *
487487 * * The declared 'local variable' is called '__entry'
488488 * *
@@ -542,7 +542,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) · 53 unmodified lines
542542 * tracepoint callback (this is used by programmatic plugins and
543543 * can also by used by generic instrumentation like SystemTap), and
544544 * it is also used to expose a structured trace record in
545− * /sys/kernel/debug/tracing/events/.
545+ * /sys/kernel/tracing/events/.
546546 *
547547 * A set of (un)registration functions can be passed to the variant
548548 * TRACE_EVENT_FN to perform any (un)registration work.
include/trace/bpf_probe.h+1−44
@@ -4,50 +4,7 @@ · 3 unmodified lines
44
55 #ifdef CONFIG_BPF_EVENTS
66
7−#undef __entry
8−#define __entry entry
9−
10−#undef __get_dynamic_array
11−#define __get_dynamic_array(field) \
12− ((void *)__entry + (__entry->__data_loc_##field & 0xffff))
13−
14−#undef __get_dynamic_array_len
15−#define __get_dynamic_array_len(field) \
16− ((__entry->__data_loc_##field >> 16) & 0xffff)
17−
18−#undef __get_str
19−#define __get_str(field) ((char *)__get_dynamic_array(field))
20−
21−#undef __get_bitmask
22−#define __get_bitmask(field) (char *)__get_dynamic_array(field)
23−
24−#undef __get_cpumask
25−#define __get_cpumask(field) (char *)__get_dynamic_array(field)
26−
27−#undef __get_sockaddr
28−#define __get_sockaddr(field) ((struct sockaddr *)__get_dynamic_array(field))
29−
30−#undef __get_rel_dynamic_array
31−#define __get_rel_dynamic_array(field) \
32− ((void *)(&__entry->__rel_loc_##field) + \
33− sizeof(__entry->__rel_loc_##field) + \
34− (__entry->__rel_loc_##field & 0xffff))
35−
36−#undef __get_rel_dynamic_array_len
37−#define __get_rel_dynamic_array_len(field) \
38− ((__entry->__rel_loc_##field >> 16) & 0xffff)
39−
40−#undef __get_rel_str
41−#define __get_rel_str(field) ((char *)__get_rel_dynamic_array(field))
42−
43−#undef __get_rel_bitmask
44−#define __get_rel_bitmask(field) (char *)__get_rel_dynamic_array(field)
45−
46−#undef __get_rel_cpumask
47−#define __get_rel_cpumask(field) (char *)__get_rel_dynamic_array(field)
48−
49−#undef __get_rel_sockaddr
50−#define __get_rel_sockaddr(field) ((struct sockaddr *)__get_rel_dynamic_array(field))
7+#include "stages/stage6_event_callback.h"
518
529 #undef __perf_count
5310 #define __perf_count(c) (c)
include/trace/perf.h+1−45
@@ -4,51 +4,7 @@ · 3 unmodified lines
44
55 #ifdef CONFIG_PERF_EVENTS
66
7−#undef __entry
8−#define __entry entry
9−
10−#undef __get_dynamic_array
11−#define __get_dynamic_array(field) \
12− ((void *)__entry + (__entry->__data_loc_##field & 0xffff))
13−
14−#undef __get_dynamic_array_len
15−#define __get_dynamic_array_len(field) \
16− ((__entry->__data_loc_##field >> 16) & 0xffff)
17−
18−#undef __get_str
19−#define __get_str(field) ((char *)__get_dynamic_array(field))
20−
21−#undef __get_bitmask
22−#define __get_bitmask(field) (char *)__get_dynamic_array(field)
23−
24−#undef __get_cpumask
25−#define __get_cpumask(field) (char *)__get_dynamic_array(field)
26−
27−#undef __get_sockaddr
28−#define __get_sockaddr(field) ((struct sockaddr *)__get_dynamic_array(field))
29−
30−#undef __get_rel_dynamic_array
31−#define __get_rel_dynamic_array(field) \
32− ((void *)__entry + \
33− offsetof(typeof(*__entry), __rel_loc_##field) + \
34− sizeof(__entry->__rel_loc_##field) + \
35− (__entry->__rel_loc_##field & 0xffff))
36−
37−#undef __get_rel_dynamic_array_len
38−#define __get_rel_dynamic_array_len(field) \
39− ((__entry->__rel_loc_##field >> 16) & 0xffff)
40−
41−#undef __get_rel_str
42−#define __get_rel_str(field) ((char *)__get_rel_dynamic_array(field))
43−
44−#undef __get_rel_bitmask
45−#define __get_rel_bitmask(field) (char *)__get_rel_dynamic_array(field)
46−
47−#undef __get_rel_cpumask
48−#define __get_rel_cpumask(field) (char *)__get_rel_dynamic_array(field)
49−
50−#undef __get_rel_sockaddr
51−#define __get_rel_sockaddr(field) ((struct sockaddr *)__get_rel_dynamic_array(field))
7+#include "stages/stage6_event_callback.h"
528
539 #undef __perf_count
5410 #define __perf_count(c) (__count = (c))
include/trace/stages/stage3_trace_output.h+3−0
@@ -139,3 +139,6 @@ · 138 unmodified lines
139139 u64 ____val = (u64)(value); \
140140 (u32) do_div(____val, NSEC_PER_SEC); \
141141 })
142+
143+#undef __get_buf
144+#define __get_buf(len) trace_seq_acquire(p, (len))
include/trace/stages/stage6_event_callback.h+3−0
@@ -2,6 +2,9 @@ · 1 unmodified line
22
33 /* Stage 6 definitions for creating trace events */
44
5+/* Reuse some of the stage 3 macros */
6+#include "stage3_trace_output.h"
7+
58 #undef __entry
69 #define __entry entry
710
include/trace/stages/stage7_class_define.h+1−0
@@ -23,6 +23,7 @@ · 22 unmodified lines
2323 #undef __get_rel_sockaddr
2424 #undef __print_array
2525 #undef __print_hex_dump
26+#undef __get_buf
2627
2728 /*
2829 * The below is not executed in the kernel. It is only what is
kernel/trace/Kconfig+10−10
@@ -242,7 +242,7 @@ config DYNAMIC_FTRACE · 241 unmodified lines
242242 enabled, and the functions not enabled will not affect
243243 performance of the system.
244244
245− See the files in /sys/kernel/debug/tracing:
245+ See the files in /sys/kernel/tracing:
246246 available_filter_functions
247247 set_ftrace_filter
248248 set_ftrace_notrace
@@ -306,7 +306,7 @@ config STACK_TRACER · 57 unmodified lines
306306 select KALLSYMS
307307 help
308308 This special tracer records the maximum stack footprint of the
309− kernel and displays it in /sys/kernel/debug/tracing/stack_trace.
309+ kernel and displays it in /sys/kernel/tracing/stack_trace.
310310
311311 This tracer works by hooking into every function call that the
312312 kernel executes, and keeping a maximum stack depth value and
@@ -346,7 +346,7 @@ config IRQSOFF_TRACER · 33 unmodified lines
346346 disabled by default and can be runtime (re-)started
347347 via:
348348
349− echo 0 > /sys/kernel/debug/tracing/tracing_max_latency
349+ echo 0 > /sys/kernel/tracing/tracing_max_latency
350350
351351 (Note that kernel size and overhead increase with this option
352352 enabled. This option and the preempt-off timing option can be
@@ -370,7 +370,7 @@ config PREEMPT_TRACER · 17 unmodified lines
370370 disabled by default and can be runtime (re-)started
371371 via:
372372
373− echo 0 > /sys/kernel/debug/tracing/tracing_max_latency
373+ echo 0 > /sys/kernel/tracing/tracing_max_latency
374374
375375 (Note that kernel size and overhead increase with this option
376376 enabled. This option and the irqs-off timing option can be
@@ -522,7 +522,7 @@ config TRACER_SNAPSHOT · 145 unmodified lines
522522 Allow tracing users to take snapshot of the current buffer using the
523523 ftrace interface, e.g.:
524524
525− echo 1 > /sys/kernel/debug/tracing/snapshot
525+ echo 1 > /sys/kernel/tracing/snapshot
526526 cat snapshot
527527
528528 config TRACER_SNAPSHOT_PER_CPU_SWAP
@@ -534,7 +534,7 @@ config TRACER_SNAPSHOT_PER_CPU_SWAP · 5 unmodified lines
534534 full swap (all buffers). If this is set, then the following is
535535 allowed:
536536
537− echo 1 > /sys/kernel/debug/tracing/per_cpu/cpu2/snapshot
537+ echo 1 > /sys/kernel/tracing/per_cpu/cpu2/snapshot
538538
539539 After which, only the tracing buffer for CPU 2 was swapped with
540540 the main tracing buffer, and the other CPU buffers remain the same.
@@ -581,7 +581,7 @@ config PROFILE_ANNOTATED_BRANCHES · 40 unmodified lines
581581 This tracer profiles all likely and unlikely macros
582582 in the kernel. It will display the results in:
583583
584− /sys/kernel/debug/tracing/trace_stat/branch_annotated
584+ /sys/kernel/tracing/trace_stat/branch_annotated
585585
586586 Note: this will add a significant overhead; only turn this
587587 on if you need to profile the system's use of these macros.
@@ -594,7 +594,7 @@ config PROFILE_ALL_BRANCHES · 6 unmodified lines
594594 taken in the kernel is recorded whether it hit or miss.
595595 The results will be displayed in:
596596
597− /sys/kernel/debug/tracing/trace_stat/branch_all
597+ /sys/kernel/tracing/trace_stat/branch_all
598598
599599 This option also enables the likely/unlikely profiler.
600600
@@ -645,8 +645,8 @@ config BLK_DEV_IO_TRACE · 44 unmodified lines
645645 Tracing also is possible using the ftrace interface, e.g.:
646646
647647 echo 1 > /sys/block/sda/sda1/trace/enable
648− echo blk > /sys/kernel/debug/tracing/current_tracer
649− cat /sys/kernel/debug/tracing/trace_pipe
648+ echo blk > /sys/kernel/tracing/current_tracer
649+ cat /sys/kernel/tracing/trace_pipe
650650
651651 If unsure, say N.
652652
kernel/trace/kprobe_event_gen_test.c+1−1
@@ -21,7 +21,7 @@ · 20 unmodified lines
2121 * Then:
2222 *
2323 * # insmod kernel/trace/kprobe_event_gen_test.ko
24− * # cat /sys/kernel/debug/tracing/trace
24+ * # cat /sys/kernel/tracing/trace
2525 *
2626 * You should see many instances of the "gen_kprobe_test" and
2727 * "gen_kretprobe_test" events in the trace buffer.
kernel/trace/ring_buffer.c+7−2
@@ -2864,7 +2864,7 @@ rb_check_timestamp(struct ring_buffer_per_cpu *cpu_buffer, · 2863 unmodified lines
28642864 sched_clock_stable() ? "" :
28652865 "If you just came from a suspend/resume,\n"
28662866 "please switch to the trace global clock:\n"
2867− " echo global > /sys/kernel/debug/tracing/trace_clock\n"
2867+ " echo global > /sys/kernel/tracing/trace_clock\n"
28682868 "or add trace_clock=global to the kernel command line\n");
28692869 }
28702870
@@ -5604,11 +5604,16 @@ EXPORT_SYMBOL_GPL(ring_buffer_alloc_read_page); · 2733 unmodified lines
56045604 */
56055605 void ring_buffer_free_read_page(struct trace_buffer *buffer, int cpu, void *data)
56065606 {
5607− struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
5607+ struct ring_buffer_per_cpu *cpu_buffer;
56085608 struct buffer_data_page *bpage = data;
56095609 struct page *page = virt_to_page(bpage);
56105610 unsigned long flags;
56115611
5612+ if (!buffer || !buffer->buffers || !buffer->buffers[cpu])
5613+ return;
5614+
5615+ cpu_buffer = buffer->buffers[cpu];
5616+
56125617 /* If the page is still in use someplace else, we can't reuse it */
56135618 if (page_ref_count(page) > 1)
56145619 goto out;
kernel/trace/synth_event_gen_test.c+1−1
@@ -22,7 +22,7 @@ · 21 unmodified lines
2222 * Then:
2323 *
2424 * # insmod kernel/trace/synth_event_gen_test.ko
25− * # cat /sys/kernel/debug/tracing/trace
25+ * # cat /sys/kernel/tracing/trace
2626 *
2727 * You should see several events in the trace buffer -
2828 * "create_synth_test", "empty_synth_test", and several instances of
kernel/trace/trace.c+145−19
@@ -49,6 +49,8 @@ · 48 unmodified lines
4949 #include <linux/irq_work.h>
5050 #include <linux/workqueue.h>
5151
52+#include <asm/setup.h> /* COMMAND_LINE_SIZE */
53+
5254 #include "trace.h"
5355 #include "trace_output.h"
5456
@@ -186,6 +188,12 @@ static char *default_bootup_tracer; · 131 unmodified lines
186188 static bool allocate_snapshot;
187189 static bool snapshot_at_boot;
188190
191+static char boot_instance_info[COMMAND_LINE_SIZE] __initdata;
192+static int boot_instance_index;
193+
194+static char boot_snapshot_info[COMMAND_LINE_SIZE] __initdata;
195+static int boot_snapshot_index;
196+
189197 static int __init set_cmdline_ftrace(char *str)
190198 {
191199 strlcpy(bootup_tracer_buf, str, MAX_TRACER_SIZE);
@@ -222,9 +230,22 @@ __setup("traceoff_on_warning", stop_trace_on_warning); · 30 unmodified lines
222230
223231 static int __init boot_alloc_snapshot(char *str)
224232 {
225− allocate_snapshot = true;
226− /* We also need the main ring buffer expanded */
227− ring_buffer_expanded = true;
233+ char *slot = boot_snapshot_info + boot_snapshot_index;
234+ int left = sizeof(boot_snapshot_info) - boot_snapshot_index;
235+ int ret;
236+
237+ if (str[0] == '=') {
238+ str++;
239+ if (strlen(str) >= left)
240+ return -1;
241+
242+ ret = snprintf(slot, left, "%s\t", str);
243+ boot_snapshot_index += ret;
244+ } else {
245+ allocate_snapshot = true;
246+ /* We also need the main ring buffer expanded */
247+ ring_buffer_expanded = true;
248+ }
228249 return 1;
229250 }
230251 __setup("alloc_snapshot", boot_alloc_snapshot);
@@ -239,6 +260,23 @@ static int __init boot_snapshot(char *str) · 8 unmodified lines
239260 __setup("ftrace_boot_snapshot", boot_snapshot);
240261
241262
263+static int __init boot_instance(char *str)
264+{
265+ char *slot = boot_instance_info + boot_instance_index;
266+ int left = sizeof(boot_instance_info) - boot_instance_index;
267+ int ret;
268+
269+ if (strlen(str) >= left)
270+ return -1;
271+
272+ ret = snprintf(slot, left, "%s\t", str);
273+ boot_instance_index += ret;
274+
275+ return 1;
276+}
277+__setup("trace_instance=", boot_instance);
278+
279+
242280 static char trace_boot_options_buf[MAX_TRACER_SIZE] __initdata;
243281
244282 static int __init set_trace_boot_options(char *str)
@@ -1001,13 +1039,8 @@ __buffer_unlock_commit(struct trace_buffer *buffer, struct ring_buffer_event *ev · 756 unmodified lines
10011039 ring_buffer_unlock_commit(buffer);
10021040 }
10031041
1004−/**
1005− * __trace_puts - write a constant string into the trace buffer.
1006− * @ip: The address of the caller
1007− * @str: The constant string to write
1008− * @size: The size of the string.
1009− */
1010−int __trace_puts(unsigned long ip, const char *str, int size)
1042+int __trace_array_puts(struct trace_array *tr, unsigned long ip,
1043+ const char *str, int size)
10111044 {
10121045 struct ring_buffer_event *event;
10131046 struct trace_buffer *buffer;
@@ -1015,7 +1048,7 @@ int __trace_puts(unsigned long ip, const char *str, int size) · 1 unmodified line
10151048 unsigned int trace_ctx;
10161049 int alloc;
10171050
1018− if (!(global_trace.trace_flags & TRACE_ITER_PRINTK))
1051+ if (!(tr->trace_flags & TRACE_ITER_PRINTK))
10191052 return 0;
10201053
10211054 if (unlikely(tracing_selftest_running || tracing_disabled))
@@ -1024,7 +1057,7 @@ int __trace_puts(unsigned long ip, const char *str, int size) · 2 unmodified lines
10241057 alloc = sizeof(*entry) + size + 2; /* possible \n added */
10251058
10261059 trace_ctx = tracing_gen_ctx();
1027− buffer = global_trace.array_buffer.buffer;
1060+ buffer = tr->array_buffer.buffer;
10281061 ring_buffer_nest_start(buffer);
10291062 event = __trace_buffer_lock_reserve(buffer, TRACE_PRINT, alloc,
10301063 trace_ctx);
@@ -1046,11 +1079,23 @@ int __trace_puts(unsigned long ip, const char *str, int size) · 15 unmodified lines
10461079 entry->buf[size] = '\0';
10471080
10481081 __buffer_unlock_commit(buffer, event);
1049− ftrace_trace_stack(&global_trace, buffer, trace_ctx, 4, NULL);
1082+ ftrace_trace_stack(tr, buffer, trace_ctx, 4, NULL);
10501083 out:
10511084 ring_buffer_nest_end(buffer);
10521085 return size;
10531086 }
1087+EXPORT_SYMBOL_GPL(__trace_array_puts);
1088+
1089+/**
1090+ * __trace_puts - write a constant string into the trace buffer.
1091+ * @ip: The address of the caller
1092+ * @str: The constant string to write
1093+ * @size: The size of the string.
1094+ */
1095+int __trace_puts(unsigned long ip, const char *str, int size)
1096+{
1097+ return __trace_array_puts(&global_trace, ip, str, size);
1098+}
10541099 EXPORT_SYMBOL_GPL(__trace_puts);
10551100
10561101 /**
@@ -1142,7 +1187,7 @@ void tracing_snapshot_instance(struct trace_array *tr) · 85 unmodified lines
11421187 *
11431188 * Note, make sure to allocate the snapshot with either
11441189 * a tracing_snapshot_alloc(), or by doing it manually
1145− * with: echo 1 > /sys/kernel/debug/tracing/snapshot
1190+ * with: echo 1 > /sys/kernel/tracing/snapshot
11461191 *
11471192 * If the snapshot buffer is not allocated, it will stop tracing.
11481193 * Basically making a permanent snapshot.
@@ -5760,7 +5805,7 @@ static const char readme_msg[] = · 4611 unmodified lines
57605805 #ifdef CONFIG_SYNTH_EVENTS
57615806 " events/synthetic_events\t- Create/append/remove/show synthetic events\n"
57625807 "\t Write into this file to define/undefine new synthetic events.\n"
5763− "\t example: echo 'myevent u64 lat; char name[]' >> synthetic_events\n"
5808+ "\t example: echo 'myevent u64 lat; char name[]; long[] stack' >> synthetic_events\n"
57645809 #endif
57655810 #endif
57665811 ;
@@ -9225,10 +9270,6 @@ static int allocate_trace_buffers(struct trace_array *tr, int size) · 3458 unmodified lines
92259270 }
92269271 tr->allocated_snapshot = allocate_snapshot;
92279272
9228− /*
9229− * Only the top level trace array gets its snapshot allocated
9230− * from the kernel command line.
9231− */
92329273 allocate_snapshot = false;
92339274 #endif
92349275
@@ -10144,6 +10185,79 @@ out: · 909 unmodified lines
1014410185 return ret;
1014510186 }
1014610187
10188+#ifdef CONFIG_TRACER_MAX_TRACE
10189+__init static bool tr_needs_alloc_snapshot(const char *name)
10190+{
10191+ char *test;
10192+ int len = strlen(name);
10193+ bool ret;
10194+
10195+ if (!boot_snapshot_index)
10196+ return false;
10197+
10198+ if (strncmp(name, boot_snapshot_info, len) == 0 &&
10199+ boot_snapshot_info[len] == '\t')
10200+ return true;
10201+
10202+ test = kmalloc(strlen(name) + 3, GFP_KERNEL);
10203+ if (!test)
10204+ return false;
10205+
10206+ sprintf(test, "\t%s\t", name);
10207+ ret = strstr(boot_snapshot_info, test) == NULL;
10208+ kfree(test);
10209+ return ret;
10210+}
10211+
10212+__init static void do_allocate_snapshot(const char *name)
10213+{
10214+ if (!tr_needs_alloc_snapshot(name))
10215+ return;
10216+
10217+ /*
10218+ * When allocate_snapshot is set, the next call to
10219+ * allocate_trace_buffers() (called by trace_array_get_by_name())
10220+ * will allocate the snapshot buffer. That will alse clear
10221+ * this flag.
10222+ */
10223+ allocate_snapshot = true;
10224+}
10225+#else
10226+static inline void do_allocate_snapshot(const char *name) { }
10227+#endif
10228+
10229+__init static void enable_instances(void)
10230+{
10231+ struct trace_array *tr;
10232+ char *curr_str;
10233+ char *str;
10234+ char *tok;
10235+
10236+ /* A tab is always appended */
10237+ boot_instance_info[boot_instance_index - 1] = '\0';
10238+ str = boot_instance_info;
10239+
10240+ while ((curr_str = strsep(&str, "\t"))) {
10241+
10242+ tok = strsep(&curr_str, ",");
10243+
10244+ if (IS_ENABLED(CONFIG_TRACER_MAX_TRACE))
10245+ do_allocate_snapshot(tok);
10246+
10247+ tr = trace_array_get_by_name(tok);
10248+ if (!tr) {
10249+ pr_warn("Failed to create instance buffer %s\n", curr_str);
10250+ continue;
10251+ }
10252+ /* Allow user space to delete it */
10253+ trace_array_put(tr);
10254+
10255+ while ((tok = strsep(&curr_str, ","))) {
10256+ early_enable_events(tr, tok, true);
10257+ }
10258+ }
10259+}
10260+
1014710261 __init static int tracer_alloc_buffers(void)
1014810262 {
1014910263 int ring_buf_size;
@@ -10277,10 +10391,19 @@ out: · 127 unmodified lines
1027710391
1027810392 void __init ftrace_boot_snapshot(void)
1027910393 {
10394+ struct trace_array *tr;
10395+
1028010396 if (snapshot_at_boot) {
1028110397 tracing_snapshot();
1028210398 internal_trace_puts("** Boot snapshot taken **\n");
1028310399 }
10400+
10401+ list_for_each_entry(tr, &ftrace_trace_arrays, list) {
10402+ if (tr == &global_trace)
10403+ continue;
10404+ trace_array_puts(tr, "** Boot snapshot taken **\n");
10405+ tracing_snapshot_instance(tr);
10406+ }
1028410407 }
1028510408
1028610409 void __init early_trace_init(void)
@@ -10302,6 +10425,9 @@ void __init early_trace_init(void) · 15 unmodified lines
1030210425 void __init trace_init(void)
1030310426 {
1030410427 trace_event_init();
10428+
10429+ if (boot_instance_index)
10430+ enable_instances();
1030510431 }
1030610432
1030710433 __init static void clear_boot_tracer(void)
kernel/trace/trace.h+6−0
@@ -113,6 +113,10 @@ enum trace_type { · 112 unmodified lines
113113 #define MEM_FAIL(condition, fmt, ...) \
114114 DO_ONCE_LITE_IF(condition, pr_err, "ERROR: " fmt, ##__VA_ARGS__)
115115
116+#define HIST_STACKTRACE_DEPTH 16
117+#define HIST_STACKTRACE_SIZE (HIST_STACKTRACE_DEPTH * sizeof(unsigned long))
118+#define HIST_STACKTRACE_SKIP 5
119+
116120 /*
117121 * syscalls are special, and need special handling, this is why
118122 * they are not included in trace_entries.h
@@ -1331,6 +1335,8 @@ DECLARE_PER_CPU(int, trace_buffered_event_cnt); · 1212 unmodified lines
13311335 void trace_buffered_event_disable(void);
13321336 void trace_buffered_event_enable(void);
13331337
1338+void early_enable_events(struct trace_array *tr, char *buf, bool disable_first);
1339+
13341340 static inline void
13351341 __trace_event_discard_commit(struct trace_buffer *buffer,
13361342 struct ring_buffer_event *event)
kernel/trace/trace_events.c+5−8
@@ -2281,8 +2281,6 @@ create_new_subsystem(const char *name) · 2280 unmodified lines
22812281 if (!system->name)
22822282 goto out_free;
22832283
2284− system->filter = NULL;
2285−
22862284 system->filter = kzalloc(sizeof(struct event_filter), GFP_KERNEL);
22872285 if (!system->filter)
22882286 goto out_free;
@@ -2843,7 +2841,7 @@ static __init int setup_trace_triggers(char *str) · 554 unmodified lines
28432841 if (!trigger)
28442842 break;
28452843 bootup_triggers[i].event = strsep(&trigger, ".");
2846− bootup_triggers[i].trigger = strsep(&trigger, ".");
2844+ bootup_triggers[i].trigger = trigger;
28472845 if (!bootup_triggers[i].trigger)
28482846 break;
28492847 }
@@ -3771,10 +3769,9 @@ static __init int event_trace_memsetup(void) · 921 unmodified lines
37713769 return 0;
37723770 }
37733771
3774−static __init void
3775−early_enable_events(struct trace_array *tr, bool disable_first)
3772+__init void
3773+early_enable_events(struct trace_array *tr, char *buf, bool disable_first)
37763774 {
3777− char *buf = bootup_event_buf;
37783775 char *token;
37793776 int ret;
37803777
@@ -3827,7 +3824,7 @@ static __init int event_trace_enable(void) · 46 unmodified lines
38273824 */
38283825 __trace_early_add_events(tr);
38293826
3830− early_enable_events(tr, false);
3827+ early_enable_events(tr, bootup_event_buf, false);
38313828
38323829 trace_printk_start_comm();
38333830
@@ -3855,7 +3852,7 @@ static __init int event_trace_enable_again(void) · 21 unmodified lines
38553852 if (!tr)
38563853 return -ENODEV;
38573854
3858− early_enable_events(tr, true);
3855+ early_enable_events(tr, bootup_event_buf, true);
38593856
38603857 return 0;
38613858 }
kernel/trace/trace_events_filter.c+92−1
@@ -64,6 +64,7 @@ enum filter_pred_fn { · 63 unmodified lines
6464 FILTER_PRED_FN_PCHAR_USER,
6565 FILTER_PRED_FN_PCHAR,
6666 FILTER_PRED_FN_CPU,
67+ FILTER_PRED_FN_FUNCTION,
6768 FILTER_PRED_FN_,
6869 FILTER_PRED_TEST_VISITED,
6970 };
@@ -71,6 +72,7 @@ enum filter_pred_fn { · 1 unmodified line
7172 struct filter_pred {
7273 enum filter_pred_fn fn_num;
7374 u64 val;
75+ u64 val2;
7476 struct regex regex;
7577 unsigned short *ops;
7678 struct ftrace_event_field *field;
@@ -103,6 +105,7 @@ struct filter_pred { · 26 unmodified lines
103105 C(INVALID_FILTER, "Meaningless filter expression"), \
104106 C(IP_FIELD_ONLY, "Only 'ip' field is supported for function trace"), \
105107 C(INVALID_VALUE, "Invalid value (did you forget quotes)?"), \
108+ C(NO_FUNCTION, "Function not found"), \
106109 C(ERRNO, "Error"), \
107110 C(NO_FILTER, "No filter found")
108111
@@ -876,6 +879,17 @@ static int filter_pred_comm(struct filter_pred *pred, void *event) · 767 unmodified lines
876879 return cmp ^ pred->not;
877880 }
878881
882+/* Filter predicate for functions. */
883+static int filter_pred_function(struct filter_pred *pred, void *event)
884+{
885+ unsigned long *addr = (unsigned long *)(event + pred->offset);
886+ unsigned long start = (unsigned long)pred->val;
887+ unsigned long end = (unsigned long)pred->val2;
888+ int ret = *addr >= start && *addr < end;
889+
890+ return pred->op == OP_EQ ? ret : !ret;
891+}
892+
879893 /*
880894 * regex_match_foo - Basic regex callbacks
881895 *
@@ -1335,6 +1349,8 @@ static int filter_pred_fn_call(struct filter_pred *pred, void *event) · 453 unmodified lines
13351349 return filter_pred_pchar(pred, event);
13361350 case FILTER_PRED_FN_CPU:
13371351 return filter_pred_cpu(pred, event);
1352+ case FILTER_PRED_FN_FUNCTION:
1353+ return filter_pred_function(pred, event);
13381354 case FILTER_PRED_TEST_VISITED:
13391355 return test_pred_visited_fn(pred, event);
13401356 default:
@@ -1350,8 +1366,13 @@ static int parse_pred(const char *str, void *data, · 9 unmodified lines
13501366 struct trace_event_call *call = data;
13511367 struct ftrace_event_field *field;
13521368 struct filter_pred *pred = NULL;
1369+ unsigned long offset;
1370+ unsigned long size;
1371+ unsigned long ip;
13531372 char num_buf[24]; /* Big enough to hold an address */
13541373 char *field_name;
1374+ char *name;
1375+ bool function = false;
13551376 bool ustring = false;
13561377 char q;
13571378 u64 val;
@@ -1393,6 +1414,12 @@ static int parse_pred(const char *str, void *data, · 35 unmodified lines
13931414 i += len;
13941415 }
13951416
1417+ /* See if the field is a kernel function name */
1418+ if ((len = str_has_prefix(str + i, ".function"))) {
1419+ function = true;
1420+ i += len;
1421+ }
1422+
13961423 while (isspace(str[i]))
13971424 i++;
13981425
@@ -1423,7 +1450,71 @@ static int parse_pred(const char *str, void *data, · 24 unmodified lines
14231450 pred->offset = field->offset;
14241451 pred->op = op;
14251452
1426− if (ftrace_event_is_function(call)) {
1453+ if (function) {
1454+ /* The field must be the same size as long */
1455+ if (field->size != sizeof(long)) {
1456+ parse_error(pe, FILT_ERR_ILLEGAL_FIELD_OP, pos + i);
1457+ goto err_free;
1458+ }
1459+
1460+ /* Function only works with '==' or '!=' and an unquoted string */
1461+ switch (op) {
1462+ case OP_NE:
1463+ case OP_EQ:
1464+ break;
1465+ default:
1466+ parse_error(pe, FILT_ERR_INVALID_OP, pos + i);
1467+ goto err_free;
1468+ }
1469+
1470+ if (isdigit(str[i])) {
1471+ /* We allow 0xDEADBEEF */
1472+ while (isalnum(str[i]))
1473+ i++;
1474+
1475+ len = i - s;
1476+ /* 0xfeedfacedeadbeef is 18 chars max */
1477+ if (len >= sizeof(num_buf)) {
1478+ parse_error(pe, FILT_ERR_OPERAND_TOO_LONG, pos + i);
1479+ goto err_free;
1480+ }
1481+
1482+ strncpy(num_buf, str + s, len);
1483+ num_buf[len] = 0;
1484+
1485+ ret = kstrtoul(num_buf, 0, &ip);
1486+ if (ret) {
1487+ parse_error(pe, FILT_ERR_INVALID_VALUE, pos + i);
1488+ goto err_free;
1489+ }
1490+ } else {
1491+ s = i;
1492+ for (; str[i] && !isspace(str[i]); i++)
1493+ ;
1494+
1495+ len = i - s;
1496+ name = kmemdup_nul(str + s, len, GFP_KERNEL);
1497+ if (!name)
1498+ goto err_mem;
1499+ ip = kallsyms_lookup_name(name);
1500+ kfree(name);
1501+ if (!ip) {
1502+ parse_error(pe, FILT_ERR_NO_FUNCTION, pos + i);
1503+ goto err_free;
1504+ }
1505+ }
1506+
1507+ /* Now find the function start and end address */
1508+ if (!kallsyms_lookup_size_offset(ip, &size, &offset)) {
1509+ parse_error(pe, FILT_ERR_NO_FUNCTION, pos + i);
1510+ goto err_free;
1511+ }
1512+
1513+ pred->fn_num = FILTER_PRED_FN_FUNCTION;
1514+ pred->val = ip - offset;
1515+ pred->val2 = pred->val + size;
1516+
1517+ } else if (ftrace_event_is_function(call)) {
14271518 /*
14281519 * Perf does things different with function events.
14291520 * It only allows an "ip" field, and expects a string.
kernel/trace/trace_events_hist.c+103−23
@@ -135,6 +135,7 @@ enum hist_field_fn { · 134 unmodified lines
135135 HIST_FIELD_FN_DIV_NOT_POWER2,
136136 HIST_FIELD_FN_DIV_MULT_SHIFT,
137137 HIST_FIELD_FN_EXECNAME,
138+ HIST_FIELD_FN_STACK,
138139 };
139140
140141 /*
@@ -480,10 +481,6 @@ DEFINE_HIST_FIELD_FN(u8); · 339 unmodified lines
480481 #define for_each_hist_key_field(i, hist_data) \
481482 for ((i) = (hist_data)->n_vals; (i) < (hist_data)->n_fields; (i)++)
482483
483−#define HIST_STACKTRACE_DEPTH 16
484−#define HIST_STACKTRACE_SIZE (HIST_STACKTRACE_DEPTH * sizeof(unsigned long))
485−#define HIST_STACKTRACE_SKIP 5
486−
487484 #define HITCOUNT_IDX 0
488485 #define HIST_KEY_SIZE_MAX (MAX_FILTER_STR_VAL + HIST_STACKTRACE_SIZE)
489486
@@ -1360,7 +1357,12 @@ static const char *hist_field_name(struct hist_field *field, · 870 unmodified lines
13601357 field_name = field->name;
13611358 } else if (field->flags & HIST_FIELD_FL_TIMESTAMP)
13621359 field_name = "common_timestamp";
1363− else if (field->flags & HIST_FIELD_FL_HITCOUNT)
1360+ else if (field->flags & HIST_FIELD_FL_STACKTRACE) {
1361+ if (field->field)
1362+ field_name = field->field->name;
1363+ else
1364+ field_name = "stacktrace";
1365+ } else if (field->flags & HIST_FIELD_FL_HITCOUNT)
13641366 field_name = "hitcount";
13651367
13661368 if (field_name == NULL)
@@ -1718,6 +1720,8 @@ static const char *get_hist_field_flags(struct hist_field *hist_field) · 351 unmodified lines
17181720 flags_str = "percent";
17191721 else if (hist_field->flags & HIST_FIELD_FL_GRAPH)
17201722 flags_str = "graph";
1723+ else if (hist_field->flags & HIST_FIELD_FL_STACKTRACE)
1724+ flags_str = "stacktrace";
17211725
17221726 return flags_str;
17231727 }
@@ -1979,7 +1983,14 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, · 255 unmodified lines
19791983 }
19801984
19811985 if (flags & HIST_FIELD_FL_STACKTRACE) {
1982− hist_field->fn_num = HIST_FIELD_FN_NOP;
1986+ if (field)
1987+ hist_field->fn_num = HIST_FIELD_FN_STACK;
1988+ else
1989+ hist_field->fn_num = HIST_FIELD_FN_NOP;
1990+ hist_field->size = HIST_STACKTRACE_SIZE;
1991+ hist_field->type = kstrdup_const("unsigned long[]", GFP_KERNEL);
1992+ if (!hist_field->type)
1993+ goto free;
19831994 goto out;
19841995 }
19851996
@@ -2312,6 +2323,8 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, · 326 unmodified lines
23122323 *flags |= HIST_FIELD_FL_EXECNAME;
23132324 else if (strcmp(modifier, "syscall") == 0)
23142325 *flags |= HIST_FIELD_FL_SYSCALL;
2326+ else if (strcmp(modifier, "stacktrace") == 0)
2327+ *flags |= HIST_FIELD_FL_STACKTRACE;
23152328 else if (strcmp(modifier, "log2") == 0)
23162329 *flags |= HIST_FIELD_FL_LOG2;
23172330 else if (strcmp(modifier, "usecs") == 0)
@@ -2351,6 +2364,8 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, · 33 unmodified lines
23512364 hist_data->enable_timestamps = true;
23522365 if (*flags & HIST_FIELD_FL_TIMESTAMP_USECS)
23532366 hist_data->attrs->ts_in_usecs = true;
2367+ } else if (strcmp(field_name, "stacktrace") == 0) {
2368+ *flags |= HIST_FIELD_FL_STACKTRACE;
23542369 } else if (strcmp(field_name, "common_cpu") == 0)
23552370 *flags |= HIST_FIELD_FL_CPU;
23562371 else if (strcmp(field_name, "hitcount") == 0)
@@ -3111,6 +3126,9 @@ static inline void __update_field_vars(struct tracing_map_elt *elt, · 754 unmodified lines
31113126 unsigned int i, j, var_idx;
31123127 u64 var_val;
31133128
3129+ /* Make sure stacktrace can fit in the string variable length */
3130+ BUILD_BUG_ON((HIST_STACKTRACE_DEPTH + 1) * sizeof(long) >= STR_VAR_LEN_MAX);
3131+
31143132 for (i = 0, j = field_var_str_start; i < n_field_vars; i++) {
31153133 struct field_var *field_var = field_vars[i];
31163134 struct hist_field *var = field_var->var;
@@ -3119,13 +3137,26 @@ static inline void __update_field_vars(struct tracing_map_elt *elt, · 2 unmodified lines
31193137 var_val = hist_fn_call(val, elt, buffer, rbe, rec);
31203138 var_idx = var->var.idx;
31213139
3122− if (val->flags & HIST_FIELD_FL_STRING) {
3140+ if (val->flags & (HIST_FIELD_FL_STRING |
3141+ HIST_FIELD_FL_STACKTRACE)) {
31233142 char *str = elt_data->field_var_str[j++];
31243143 char *val_str = (char *)(uintptr_t)var_val;
31253144 unsigned int size;
31263145
3127− size = min(val->size, STR_VAR_LEN_MAX);
3128− strscpy(str, val_str, size);
3146+ if (val->flags & HIST_FIELD_FL_STRING) {
3147+ size = min(val->size, STR_VAR_LEN_MAX);
3148+ strscpy(str, val_str, size);
3149+ } else {
3150+ char *stack_start = str + sizeof(unsigned long);
3151+ int e;
3152+
3153+ e = stack_trace_save((void *)stack_start,
3154+ HIST_STACKTRACE_DEPTH,
3155+ HIST_STACKTRACE_SKIP);
3156+ if (e < HIST_STACKTRACE_DEPTH - 1)
3157+ ((unsigned long *)stack_start)[e] = 0;
3158+ *((unsigned long *)str) = e;
3159+ }
31293160 var_val = (u64)(uintptr_t)str;
31303161 }
31313162 tracing_map_set_var(elt, var_idx, var_val);
@@ -3824,7 +3855,8 @@ static void save_field_var(struct hist_trigger_data *hist_data, · 692 unmodified lines
38243855 {
38253856 hist_data->field_vars[hist_data->n_field_vars++] = field_var;
38263857
3827− if (field_var->val->flags & HIST_FIELD_FL_STRING)
3858+ /* Stack traces are saved in the string storage too */
3859+ if (field_var->val->flags & (HIST_FIELD_FL_STRING | HIST_FIELD_FL_STACKTRACE))
38283860 hist_data->n_field_var_str++;
38293861 }
38303862
@@ -3849,6 +3881,9 @@ static int check_synth_field(struct synth_event *event, · 18 unmodified lines
38493881 && field->is_dynamic)
38503882 return 0;
38513883
3884+ if (strstr(hist_field->type, "long[") && field->is_stack)
3885+ return 0;
3886+
38523887 if (strcmp(field->type, hist_field->type) != 0) {
38533888 if (field->size != hist_field->size ||
38543889 (!field->is_string && field->is_signed != hist_field->is_signed))
@@ -4103,7 +4138,8 @@ static int action_create(struct hist_trigger_data *hist_data, · 248 unmodified lines
41034138 }
41044139
41054140 hist_data->save_vars[hist_data->n_save_vars++] = field_var;
4106− if (field_var->val->flags & HIST_FIELD_FL_STRING)
4141+ if (field_var->val->flags &
4142+ (HIST_FIELD_FL_STRING | HIST_FIELD_FL_STACKTRACE))
41074143 hist_data->n_save_var_str++;
41084144 kfree(param);
41094145 }
@@ -4242,6 +4278,19 @@ static u64 hist_field_execname(struct hist_field *hist_field, · 132 unmodified lines
42424278 return (u64)(unsigned long)(elt_data->comm);
42434279 }
42444280
4281+static u64 hist_field_stack(struct hist_field *hist_field,
4282+ struct tracing_map_elt *elt,
4283+ struct trace_buffer *buffer,
4284+ struct ring_buffer_event *rbe,
4285+ void *event)
4286+{
4287+ u32 str_item = *(u32 *)(event + hist_field->field->offset);
4288+ int str_loc = str_item & 0xffff;
4289+ char *addr = (char *)(event + str_loc);
4290+
4291+ return (u64)(unsigned long)addr;
4292+}
4293+
42454294 static u64 hist_fn_call(struct hist_field *hist_field,
42464295 struct tracing_map_elt *elt,
42474296 struct trace_buffer *buffer,
@@ -4305,6 +4354,8 @@ static u64 hist_fn_call(struct hist_field *hist_field, · 57 unmodified lines
43054354 return div_by_mult_and_shift(hist_field, elt, buffer, rbe, event);
43064355 case HIST_FIELD_FN_EXECNAME:
43074356 return hist_field_execname(hist_field, elt, buffer, rbe, event);
4357+ case HIST_FIELD_FN_STACK:
4358+ return hist_field_stack(hist_field, elt, buffer, rbe, event);
43084359 default:
43094360 return 0;
43104361 }
@@ -4351,7 +4402,8 @@ static int create_var_field(struct hist_trigger_data *hist_data, · 40 unmodified lines
43514402 if (!ret && hist_data->fields[val_idx]->flags & HIST_FIELD_FL_EXECNAME)
43524403 update_var_execname(hist_data->fields[val_idx]);
43534404
4354− if (!ret && hist_data->fields[val_idx]->flags & HIST_FIELD_FL_STRING)
4405+ if (!ret && hist_data->fields[val_idx]->flags &
4406+ (HIST_FIELD_FL_STRING | HIST_FIELD_FL_STACKTRACE))
43554407 hist_data->fields[val_idx]->var_str_idx = hist_data->n_var_str++;
43564408
43574409 return ret;
@@ -5092,7 +5144,8 @@ static void hist_trigger_elt_update(struct hist_trigger_data *hist_data, · 734 unmodified lines
50925144 if (hist_field->flags & HIST_FIELD_FL_VAR) {
50935145 var_idx = hist_field->var.idx;
50945146
5095− if (hist_field->flags & HIST_FIELD_FL_STRING) {
5147+ if (hist_field->flags &
5148+ (HIST_FIELD_FL_STRING | HIST_FIELD_FL_STACKTRACE)) {
50965149 unsigned int str_start, var_str_idx, idx;
50975150 char *str, *val_str;
50985151 unsigned int size;
@@ -5105,9 +5158,20 @@ static void hist_trigger_elt_update(struct hist_trigger_data *hist_data, · 6 unmodified lines
51055158 str = elt_data->field_var_str[idx];
51065159 val_str = (char *)(uintptr_t)hist_val;
51075160
5108− size = min(hist_field->size, STR_VAR_LEN_MAX);
5109− strscpy(str, val_str, size);
5110−
5161+ if (hist_field->flags & HIST_FIELD_FL_STRING) {
5162+ size = min(hist_field->size, STR_VAR_LEN_MAX);
5163+ strscpy(str, val_str, size);
5164+ } else {
5165+ char *stack_start = str + sizeof(unsigned long);
5166+ int e;
5167+
5168+ e = stack_trace_save((void *)stack_start,
5169+ HIST_STACKTRACE_DEPTH,
5170+ HIST_STACKTRACE_SKIP);
5171+ if (e < HIST_STACKTRACE_DEPTH - 1)
5172+ ((unsigned long *)stack_start)[e] = 0;
5173+ *((unsigned long *)str) = e;
5174+ }
51115175 hist_val = (u64)(uintptr_t)str;
51125176 }
51135177 tracing_map_set_var(elt, var_idx, hist_val);
@@ -5193,8 +5257,17 @@ static void event_hist_trigger(struct event_trigger_data *data, · 79 unmodified lines
51935257
51945258 if (key_field->flags & HIST_FIELD_FL_STACKTRACE) {
51955259 memset(entries, 0, HIST_STACKTRACE_SIZE);
5196− stack_trace_save(entries, HIST_STACKTRACE_DEPTH,
5197− HIST_STACKTRACE_SKIP);
5260+ if (key_field->field) {
5261+ unsigned long *stack, n_entries;
5262+
5263+ field_contents = hist_fn_call(key_field, elt, buffer, rbe, rec);
5264+ stack = (unsigned long *)(long)field_contents;
5265+ n_entries = *stack;
5266+ memcpy(entries, ++stack, n_entries * sizeof(unsigned long));
5267+ } else {
5268+ stack_trace_save(entries, HIST_STACKTRACE_DEPTH,
5269+ HIST_STACKTRACE_SKIP);
5270+ }
51985271 key = entries;
51995272 } else {
52005273 field_contents = hist_fn_call(key_field, elt, buffer, rbe, rec);
@@ -5297,7 +5370,10 @@ static void hist_trigger_print_key(struct seq_file *m, · 96 unmodified lines
52975370 seq_printf(m, "%s: %-30s[%3llu]", field_name,
52985371 syscall_name, uval);
52995372 } else if (key_field->flags & HIST_FIELD_FL_STACKTRACE) {
5300− seq_puts(m, "stacktrace:\n");
5373+ if (key_field->field)
5374+ seq_printf(m, "%s.stacktrace", key_field->field->name);
5375+ else
5376+ seq_puts(m, "stacktrace:\n");
53015377 hist_trigger_stacktrace_print(m,
53025378 key + key_field->offset,
53035379 HIST_STACKTRACE_DEPTH);
@@ -5842,7 +5918,8 @@ static void hist_field_print(struct seq_file *m, struct hist_field *hist_field) · 538 unmodified lines
58425918
58435919 if (hist_field->flags) {
58445920 if (!(hist_field->flags & HIST_FIELD_FL_VAR_REF) &&
5845− !(hist_field->flags & HIST_FIELD_FL_EXPR)) {
5921+ !(hist_field->flags & HIST_FIELD_FL_EXPR) &&
5922+ !(hist_field->flags & HIST_FIELD_FL_STACKTRACE)) {
58465923 const char *flags = get_hist_field_flags(hist_field);
58475924
58485925 if (flags)
@@ -5875,9 +5952,12 @@ static int event_hist_trigger_print(struct seq_file *m, · 26 unmodified lines
58755952 if (i > hist_data->n_vals)
58765953 seq_puts(m, ",");
58775954
5878− if (field->flags & HIST_FIELD_FL_STACKTRACE)
5879− seq_puts(m, "stacktrace");
5880− else
5955+ if (field->flags & HIST_FIELD_FL_STACKTRACE) {
5956+ if (field->field)
5957+ seq_printf(m, "%s.stacktrace", field->field->name);
5958+ else
5959+ seq_puts(m, "stacktrace");
5960+ } else
58815961 hist_field_print(m, field);
58825962 }
58835963
kernel/trace/trace_events_synth.c+86−4
@@ -173,6 +173,14 @@ static int synth_field_is_string(char *type) · 172 unmodified lines
173173 return false;
174174 }
175175
176+static int synth_field_is_stack(char *type)
177+{
178+ if (strstr(type, "long[") != NULL)
179+ return true;
180+
181+ return false;
182+}
183+
176184 static int synth_field_string_size(char *type)
177185 {
178186 char buf[4], *end, *start;
@@ -248,6 +256,8 @@ static int synth_field_size(char *type) · 69 unmodified lines
248256 size = sizeof(gfp_t);
249257 else if (synth_field_is_string(type))
250258 size = synth_field_string_size(type);
259+ else if (synth_field_is_stack(type))
260+ size = 0;
251261
252262 return size;
253263 }
@@ -292,6 +302,8 @@ static const char *synth_field_fmt(char *type) · 38 unmodified lines
292302 fmt = "%x";
293303 else if (synth_field_is_string(type))
294304 fmt = "%.*s";
305+ else if (synth_field_is_stack(type))
306+ fmt = "%s";
295307
296308 return fmt;
297309 }
@@ -371,6 +383,23 @@ static enum print_line_t print_synth_event(struct trace_iterator *iter, · 73 unmodified lines
371383 i == se->n_fields - 1 ? "" : " ");
372384 n_u64 += STR_VAR_LEN_MAX / sizeof(u64);
373385 }
386+ } else if (se->fields[i]->is_stack) {
387+ u32 offset, data_offset, len;
388+ unsigned long *p, *end;
389+
390+ offset = (u32)entry->fields[n_u64];
391+ data_offset = offset & 0xffff;
392+ len = offset >> 16;
393+
394+ p = (void *)entry + data_offset;
395+ end = (void *)p + len - (sizeof(long) - 1);
396+
397+ trace_seq_printf(s, "%s=STACK:\n", se->fields[i]->name);
398+
399+ for (; *p && p < end; p++)
400+ trace_seq_printf(s, "=> %pS\n", (void *)*p);
401+ n_u64++;
402+
374403 } else {
375404 struct trace_print_flags __flags[] = {
376405 __def_gfpflag_names, {-1, NULL} };
@@ -416,8 +445,7 @@ static unsigned int trace_string(struct synth_trace_event *entry, · 39 unmodified lines
416445 if (is_dynamic) {
417446 u32 data_offset;
418447
419− data_offset = offsetof(typeof(*entry), fields);
420− data_offset += event->n_u64 * sizeof(u64);
448+ data_offset = struct_size(entry, fields, event->n_u64);
421449 data_offset += data_size;
422450
423451 len = kern_fetch_store_strlen((unsigned long)str_val);
@@ -447,6 +475,43 @@ static unsigned int trace_string(struct synth_trace_event *entry, · 23 unmodified lines
447475 return len;
448476 }
449477
478+static unsigned int trace_stack(struct synth_trace_event *entry,
479+ struct synth_event *event,
480+ long *stack,
481+ unsigned int data_size,
482+ unsigned int *n_u64)
483+{
484+ unsigned int len;
485+ u32 data_offset;
486+ void *data_loc;
487+
488+ data_offset = struct_size(entry, fields, event->n_u64);
489+ data_offset += data_size;
490+
491+ for (len = 0; len < HIST_STACKTRACE_DEPTH; len++) {
492+ if (!stack[len])
493+ break;
494+ }
495+
496+ /* Include the zero'd element if it fits */
497+ if (len < HIST_STACKTRACE_DEPTH)
498+ len++;
499+
500+ len *= sizeof(long);
501+
502+ /* Find the dynamic section to copy the stack into. */
503+ data_loc = (void *)entry + data_offset;
504+ memcpy(data_loc, stack, len);
505+
506+ /* Fill in the field that holds the offset/len combo */
507+ data_offset |= len << 16;
508+ *(u32 *)&entry->fields[*n_u64] = data_offset;
509+
510+ (*n_u64)++;
511+
512+ return len;
513+}
514+
450515 static notrace void trace_event_raw_event_synth(void *__data,
451516 u64 *var_ref_vals,
452517 unsigned int *var_ref_idx)
@@ -473,7 +538,12 @@ static notrace void trace_event_raw_event_synth(void *__data, · 20 unmodified lines
473538 val_idx = var_ref_idx[field_pos];
474539 str_val = (char *)(long)var_ref_vals[val_idx];
475540
476− len = kern_fetch_store_strlen((unsigned long)str_val);
541+ if (event->dynamic_fields[i]->is_stack) {
542+ len = *((unsigned long *)str_val);
543+ len *= sizeof(unsigned long);
544+ } else {
545+ len = kern_fetch_store_strlen((unsigned long)str_val);
546+ }
477547
478548 fields_size += len;
479549 }
@@ -499,6 +569,12 @@ static notrace void trace_event_raw_event_synth(void *__data, · 19 unmodified lines
499569 event->fields[i]->is_dynamic,
500570 data_size, &n_u64);
501571 data_size += len; /* only dynamic string increments */
572+ } else if (event->fields[i]->is_stack) {
573+ long *stack = (long *)(long)var_ref_vals[val_idx];
574+
575+ len = trace_stack(entry, event, stack,
576+ data_size, &n_u64);
577+ data_size += len;
502578 } else {
503579 struct synth_field *field = event->fields[i];
504580 u64 val = var_ref_vals[val_idx];
@@ -561,6 +637,9 @@ static int __set_synth_event_print_fmt(struct synth_event *event, · 56 unmodified lines
561637 event->fields[i]->is_dynamic)
562638 pos += snprintf(buf + pos, LEN_OR_ZERO,
563639 ", __get_str(%s)", event->fields[i]->name);
640+ else if (event->fields[i]->is_stack)
641+ pos += snprintf(buf + pos, LEN_OR_ZERO,
642+ ", __get_stacktrace(%s)", event->fields[i]->name);
564643 else
565644 pos += snprintf(buf + pos, LEN_OR_ZERO,
566645 ", REC->%s", event->fields[i]->name);
@@ -697,7 +776,8 @@ static struct synth_field *parse_synth_field(int argc, char **argv, · 130 unmodified lines
697776 ret = -EINVAL;
698777 goto free;
699778 } else if (size == 0) {
700− if (synth_field_is_string(field->type)) {
779+ if (synth_field_is_string(field->type) ||
780+ synth_field_is_stack(field->type)) {
701781 char *type;
702782
703783 len = sizeof("__data_loc ") + strlen(field->type) + 1;
@@ -728,6 +808,8 @@ static struct synth_field *parse_synth_field(int argc, char **argv, · 24 unmodified lines
728808
729809 if (synth_field_is_string(field->type))
730810 field->is_string = true;
811+ else if (synth_field_is_stack(field->type))
812+ field->is_stack = true;
731813
732814 field->is_signed = synth_field_signed(field->type);
733815 out:
kernel/trace/trace_osnoise.c+1−1
@@ -1539,7 +1539,7 @@ static void osnoise_sleep(void) · 1538 unmodified lines
15391539 wake_time = ktime_add_us(ktime_get(), interval);
15401540 __set_current_state(TASK_INTERRUPTIBLE);
15411541
1542− while (schedule_hrtimeout_range(&wake_time, 0, HRTIMER_MODE_ABS)) {
1542+ while (schedule_hrtimeout(&wake_time, HRTIMER_MODE_ABS)) {
15431543 if (kthread_should_stop())
15441544 break;
15451545 }
kernel/trace/trace_seq.c+23−0
@@ -403,3 +403,26 @@ int trace_seq_hex_dump(struct trace_seq *s, const char *prefix_str, · 402 unmodified lines
403403 return 1;
404404 }
405405 EXPORT_SYMBOL(trace_seq_hex_dump);
406+
407+/*
408+ * trace_seq_acquire - acquire seq buffer with size len
409+ * @s: trace sequence descriptor
410+ * @len: size of buffer to be acquired
411+ *
412+ * acquire buffer with size of @len from trace_seq for output usage,
413+ * user can fill string into that buffer.
414+ *
415+ * Returns start address of acquired buffer.
416+ *
417+ * it allow multiple usage in one trace output function call.
418+ */
419+char *trace_seq_acquire(struct trace_seq *s, unsigned int len)
420+{
421+ char *ret = trace_seq_buffer_ptr(s);
422+
423+ if (!WARN_ON_ONCE(seq_buf_buffer_left(&s->seq) < len))
424+ seq_buf_commit(&s->seq, len);
425+
426+ return ret;
427+}
428+EXPORT_SYMBOL(trace_seq_acquire);
kernel/trace/trace_synth.h+1−0
@@ -18,6 +18,7 @@ struct synth_field { · 17 unmodified lines
1818 bool is_signed;
1919 bool is_string;
2020 bool is_dynamic;
21+ bool is_stack;
2122 };
2223
2324 struct synth_event {
kernel/tracepoint.c+2−2
@@ -571,8 +571,8 @@ static void for_each_tracepoint_range( · 570 unmodified lines
571571 bool trace_module_has_bad_taint(struct module *mod)
572572 {
573573 return mod->taints & ~((1 << TAINT_OOT_MODULE) | (1 << TAINT_CRAP) |
574− (1 << TAINT_UNSIGNED_MODULE) |
575− (1 << TAINT_TEST));
574+ (1 << TAINT_UNSIGNED_MODULE) | (1 << TAINT_TEST) |
575+ (1 << TAINT_LIVEPATCH));
576576 }
577577
578578 static BLOCKING_NOTIFIER_HEAD(tracepoint_notify_list);
samples/Kconfig+7−0
@@ -46,6 +46,13 @@ config SAMPLE_FTRACE_DIRECT_MULTI · 45 unmodified lines
4646 that hooks to wake_up_process and schedule, and prints
4747 the function addresses.
4848
49+config SAMPLE_FTRACE_OPS
50+ tristate "Build custom ftrace ops example"
51+ depends on FUNCTION_TRACER
52+ help
53+ This builds an ftrace ops example that hooks two functions and
54+ measures the time taken to invoke one function a number of times.
55+
4956 config SAMPLE_TRACE_ARRAY
5057 tristate "Build sample module for kernel access to Ftrace instancess"
5158 depends on EVENT_TRACING && m
samples/Makefile+1−0
@@ -24,6 +24,7 @@ obj-$(CONFIG_SAMPLE_TRACE_CUSTOM_EVENTS) += trace_events/ · 23 unmodified lines
2424 obj-$(CONFIG_SAMPLE_TRACE_PRINTK) += trace_printk/
2525 obj-$(CONFIG_SAMPLE_FTRACE_DIRECT) += ftrace/
2626 obj-$(CONFIG_SAMPLE_FTRACE_DIRECT_MULTI) += ftrace/
27+obj-$(CONFIG_SAMPLE_FTRACE_OPS) += ftrace/
2728 obj-$(CONFIG_SAMPLE_TRACE_ARRAY) += ftrace/
2829 subdir-$(CONFIG_SAMPLE_UHID) += uhid
2930 obj-$(CONFIG_VIDEO_PCI_SKELETON) += v4l/
samples/ftrace/Makefile+1−0
@@ -5,6 +5,7 @@ obj-$(CONFIG_SAMPLE_FTRACE_DIRECT) += ftrace-direct-too.o · 4 unmodified lines
55 obj-$(CONFIG_SAMPLE_FTRACE_DIRECT) += ftrace-direct-modify.o
66 obj-$(CONFIG_SAMPLE_FTRACE_DIRECT_MULTI) += ftrace-direct-multi.o
77 obj-$(CONFIG_SAMPLE_FTRACE_DIRECT_MULTI) += ftrace-direct-multi-modify.o
8+obj-$(CONFIG_SAMPLE_FTRACE_OPS) += ftrace-ops.o
89
910 CFLAGS_sample-trace-array.o := -I$(src)
1011 obj-$(CONFIG_SAMPLE_TRACE_ARRAY) += sample-trace-array.o
samples/ftrace/ftrace-direct-modify.c+1−1
@@ -3,7 +3,6 @@ · 2 unmodified lines
33 #include <linux/kthread.h>
44 #include <linux/ftrace.h>
55 #include <asm/asm-offsets.h>
6−#include <asm/nospec-branch.h>
76
87 extern void my_direct_func1(void);
98 extern void my_direct_func2(void);
@@ -26,6 +25,7 @@ static unsigned long my_ip = (unsigned long)schedule; · 16 unmodified lines
2625 #ifdef CONFIG_X86_64
2726
2827 #include <asm/ibt.h>
28+#include <asm/nospec-branch.h>
2929
3030 asm (
3131 " .pushsection .text, \"ax\", @progbits\n"
samples/ftrace/ftrace-direct-multi-modify.c+1−1
@@ -3,7 +3,6 @@ · 2 unmodified lines
33 #include <linux/kthread.h>
44 #include <linux/ftrace.h>
55 #include <asm/asm-offsets.h>
6−#include <asm/nospec-branch.h>
76
87 extern void my_direct_func1(unsigned long ip);
98 extern void my_direct_func2(unsigned long ip);
@@ -24,6 +23,7 @@ extern void my_tramp2(void *); · 14 unmodified lines
2423 #ifdef CONFIG_X86_64
2524
2625 #include <asm/ibt.h>
26+#include <asm/nospec-branch.h>
2727
2828 asm (
2929 " .pushsection .text, \"ax\", @progbits\n"
samples/ftrace/ftrace-direct-multi.c+1−1
@@ -5,7 +5,6 @@ · 4 unmodified lines
55 #include <linux/ftrace.h>
66 #include <linux/sched/stat.h>
77 #include <asm/asm-offsets.h>
8−#include <asm/nospec-branch.h>
98
109 extern void my_direct_func(unsigned long ip);
1110
@@ -19,6 +18,7 @@ extern void my_tramp(void *); · 7 unmodified lines
1918 #ifdef CONFIG_X86_64
2019
2120 #include <asm/ibt.h>
21+#include <asm/nospec-branch.h>
2222
2323 asm (
2424 " .pushsection .text, \"ax\", @progbits\n"
samples/ftrace/ftrace-direct-too.c+1−1
@@ -4,7 +4,6 @@ · 3 unmodified lines
44 #include <linux/mm.h> /* for handle_mm_fault() */
55 #include <linux/ftrace.h>
66 #include <asm/asm-offsets.h>
7−#include <asm/nospec-branch.h>
87
98 extern void my_direct_func(struct vm_area_struct *vma,
109 unsigned long address, unsigned int flags);
@@ -21,6 +20,7 @@ extern void my_tramp(void *); · 10 unmodified lines
2120 #ifdef CONFIG_X86_64
2221
2322 #include <asm/ibt.h>
23+#include <asm/nospec-branch.h>
2424
2525 asm (
2626 " .pushsection .text, \"ax\", @progbits\n"
samples/ftrace/ftrace-direct.c+1−1
@@ -4,7 +4,6 @@ · 3 unmodified lines
44 #include <linux/sched.h> /* for wake_up_process() */
55 #include <linux/ftrace.h>
66 #include <asm/asm-offsets.h>
7−#include <asm/nospec-branch.h>
87
98 extern void my_direct_func(struct task_struct *p);
109
@@ -18,6 +17,7 @@ extern void my_tramp(void *); · 7 unmodified lines
1817 #ifdef CONFIG_X86_64
1918
2019 #include <asm/ibt.h>
20+#include <asm/nospec-branch.h>
2121
2222 asm (
2323 " .pushsection .text, \"ax\", @progbits\n"
samples/ftrace/ftrace-ops.c+252−0
@@ -0,0 +1,252 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+
3+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
4+
5+#include <linux/ftrace.h>
6+#include <linux/ktime.h>
7+#include <linux/module.h>
8+
9+#include <asm/barrier.h>
10+
11+/*
12+ * Arbitrary large value chosen to be sufficiently large to minimize noise but
13+ * sufficiently small to complete quickly.
14+ */
15+static unsigned int nr_function_calls = 100000;
16+module_param(nr_function_calls, uint, 0);
17+MODULE_PARM_DESC(nr_function_calls, "How many times to call the relevant tracee");
18+
19+/*
20+ * The number of ops associated with a call site affects whether a tracer can
21+ * be called directly or whether it's necessary to go via the list func, which
22+ * can be significantly more expensive.
23+ */
24+static unsigned int nr_ops_relevant = 1;
25+module_param(nr_ops_relevant, uint, 0);
26+MODULE_PARM_DESC(nr_ops_relevant, "How many ftrace_ops to associate with the relevant tracee");
27+
28+/*
29+ * On architectures where all call sites share the same trampoline, having
30+ * tracers enabled for distinct functions can force the use of the list func
31+ * and incur overhead for all call sites.
32+ */
33+static unsigned int nr_ops_irrelevant;
34+module_param(nr_ops_irrelevant, uint, 0);
35+MODULE_PARM_DESC(nr_ops_irrelevant, "How many ftrace_ops to associate with the irrelevant tracee");
36+
37+/*
38+ * On architectures with DYNAMIC_FTRACE_WITH_REGS, saving the full pt_regs can
39+ * be more expensive than only saving the minimal necessary regs.
40+ */
41+static bool save_regs;
42+module_param(save_regs, bool, 0);
43+MODULE_PARM_DESC(save_regs, "Register ops with FTRACE_OPS_FL_SAVE_REGS (save all registers in the trampoline)");
44+
45+static bool assist_recursion;
46+module_param(assist_recursion, bool, 0);
47+MODULE_PARM_DESC(assist_reursion, "Register ops with FTRACE_OPS_FL_RECURSION");
48+
49+static bool assist_rcu;
50+module_param(assist_rcu, bool, 0);
51+MODULE_PARM_DESC(assist_reursion, "Register ops with FTRACE_OPS_FL_RCU");
52+
53+/*
54+ * By default, a trivial tracer is used which immediately returns to mimimize
55+ * overhead. Sometimes a consistency check using a more expensive tracer is
56+ * desireable.
57+ */
58+static bool check_count;
59+module_param(check_count, bool, 0);
60+MODULE_PARM_DESC(check_count, "Check that tracers are called the expected number of times\n");
61+
62+/*
63+ * Usually it's not interesting to leave the ops registered after the test
64+ * runs, but sometimes it can be useful to leave them registered so that they
65+ * can be inspected through the tracefs 'enabled_functions' file.
66+ */
67+static bool persist;
68+module_param(persist, bool, 0);
69+MODULE_PARM_DESC(persist, "Successfully load module and leave ftrace ops registered after test completes\n");
70+
71+/*
72+ * Marked as noinline to ensure that an out-of-line traceable copy is
73+ * generated by the compiler.
74+ *
75+ * The barrier() ensures the compiler won't elide calls by determining there
76+ * are no side-effects.
77+ */
78+static noinline void tracee_relevant(void)
79+{
80+ barrier();
81+}
82+
83+/*
84+ * Marked as noinline to ensure that an out-of-line traceable copy is
85+ * generated by the compiler.
86+ *
87+ * The barrier() ensures the compiler won't elide calls by determining there
88+ * are no side-effects.
89+ */
90+static noinline void tracee_irrelevant(void)
91+{
92+ barrier();
93+}
94+
95+struct sample_ops {
96+ struct ftrace_ops ops;
97+ unsigned int count;
98+};
99+
100+static void ops_func_nop(unsigned long ip, unsigned long parent_ip,
101+ struct ftrace_ops *op,
102+ struct ftrace_regs *fregs)
103+{
104+ /* do nothing */
105+}
106+
107+static void ops_func_count(unsigned long ip, unsigned long parent_ip,
108+ struct ftrace_ops *op,
109+ struct ftrace_regs *fregs)
110+{
111+ struct sample_ops *self;
112+
113+ self = container_of(op, struct sample_ops, ops);
114+ self->count++;
115+}
116+
117+static struct sample_ops *ops_relevant;
118+static struct sample_ops *ops_irrelevant;
119+
120+static struct sample_ops *ops_alloc_init(void *tracee, ftrace_func_t func,
121+ unsigned long flags, int nr)
122+{
123+ struct sample_ops *ops;
124+
125+ ops = kcalloc(nr, sizeof(*ops), GFP_KERNEL);
126+ if (WARN_ON_ONCE(!ops))
127+ return NULL;
128+
129+ for (unsigned int i = 0; i < nr; i++) {
130+ ops[i].ops.func = func;
131+ ops[i].ops.flags = flags;
132+ WARN_ON_ONCE(ftrace_set_filter_ip(&ops[i].ops, (unsigned long)tracee, 0, 0));
133+ WARN_ON_ONCE(register_ftrace_function(&ops[i].ops));
134+ }
135+
136+ return ops;
137+}
138+
139+static void ops_destroy(struct sample_ops *ops, int nr)
140+{
141+ if (!ops)
142+ return;
143+
144+ for (unsigned int i = 0; i < nr; i++) {
145+ WARN_ON_ONCE(unregister_ftrace_function(&ops[i].ops));
146+ ftrace_free_filter(&ops[i].ops);
147+ }
148+
149+ kfree(ops);
150+}
151+
152+static void ops_check(struct sample_ops *ops, int nr,
153+ unsigned int expected_count)
154+{
155+ if (!ops || !check_count)
156+ return;
157+
158+ for (unsigned int i = 0; i < nr; i++) {
159+ if (ops->count == expected_count)
160+ continue;
161+ pr_warn("Counter called %u times (expected %u)\n",
162+ ops->count, expected_count);
163+ }
164+}
165+
166+static ftrace_func_t tracer_relevant = ops_func_nop;
167+static ftrace_func_t tracer_irrelevant = ops_func_nop;
168+
169+static int __init ftrace_ops_sample_init(void)
170+{
171+ unsigned long flags = 0;
172+ ktime_t start, end;
173+ u64 period;
174+
175+ if (!IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS) && save_regs) {
176+ pr_info("this kernel does not support saving registers\n");
177+ save_regs = false;
178+ } else if (save_regs) {
179+ flags |= FTRACE_OPS_FL_SAVE_REGS;
180+ }
181+
182+ if (assist_recursion)
183+ flags |= FTRACE_OPS_FL_RECURSION;
184+
185+ if (assist_rcu)
186+ flags |= FTRACE_OPS_FL_RCU;
187+
188+ if (check_count) {
189+ tracer_relevant = ops_func_count;
190+ tracer_irrelevant = ops_func_count;
191+ }
192+
193+ pr_info("registering:\n"
194+ " relevant ops: %u\n"
195+ " tracee: %ps\n"
196+ " tracer: %ps\n"
197+ " irrelevant ops: %u\n"
198+ " tracee: %ps\n"
199+ " tracer: %ps\n"
200+ " saving registers: %s\n"
201+ " assist recursion: %s\n"
202+ " assist RCU: %s\n",
203+ nr_ops_relevant, tracee_relevant, tracer_relevant,
204+ nr_ops_irrelevant, tracee_irrelevant, tracer_irrelevant,
205+ save_regs ? "YES" : "NO",
206+ assist_recursion ? "YES" : "NO",
207+ assist_rcu ? "YES" : "NO");
208+
209+ ops_relevant = ops_alloc_init(tracee_relevant, tracer_relevant,
210+ flags, nr_ops_relevant);
211+ ops_irrelevant = ops_alloc_init(tracee_irrelevant, tracer_irrelevant,
212+ flags, nr_ops_irrelevant);
213+
214+ start = ktime_get();
215+ for (unsigned int i = 0; i < nr_function_calls; i++)
216+ tracee_relevant();
217+ end = ktime_get();
218+
219+ ops_check(ops_relevant, nr_ops_relevant, nr_function_calls);
220+ ops_check(ops_irrelevant, nr_ops_irrelevant, 0);
221+
222+ period = ktime_to_ns(ktime_sub(end, start));
223+
224+ pr_info("Attempted %u calls to %ps in %lluns (%lluns / call)\n",
225+ nr_function_calls, tracee_relevant,
226+ period, div_u64(period, nr_function_calls));
227+
228+ if (persist)
229+ return 0;
230+
231+ ops_destroy(ops_relevant, nr_ops_relevant);
232+ ops_destroy(ops_irrelevant, nr_ops_irrelevant);
233+
234+ /*
235+ * The benchmark completed sucessfully, but there's no reason to keep
236+ * the module around. Return an error do the user doesn't have to
237+ * manually unload the module.
238+ */
239+ return -EINVAL;
240+}
241+module_init(ftrace_ops_sample_init);
242+
243+static void __exit ftrace_ops_sample_exit(void)
244+{
245+ ops_destroy(ops_relevant, nr_ops_relevant);
246+ ops_destroy(ops_irrelevant, nr_ops_irrelevant);
247+}
248+module_exit(ftrace_ops_sample_exit);
249+
250+MODULE_AUTHOR("Mark Rutland");
251+MODULE_DESCRIPTION("Example of using custom ftrace_ops");
252+MODULE_LICENSE("GPL");
samples/user_events/example.c+2−2
@@ -23,8 +23,8 @@ · 22 unmodified lines
2323 #endif
2424
2525 /* Assumes debugfs is mounted */
26−const char *data_file = "/sys/kernel/debug/tracing/user_events_data";
27−const char *status_file = "/sys/kernel/debug/tracing/user_events_status";
26+const char *data_file = "/sys/kernel/tracing/user_events_data";
27+const char *status_file = "/sys/kernel/tracing/user_events_status";
2828
2929 static int event_status(long **status)
3030 {
scripts/tracing/draw_functrace.py+3−3
@@ -12,9 +12,9 @@ calls. Only the functions's names and the call time are provided. · 11 unmodified lines
1212
1313 Usage:
1414 Be sure that you have CONFIG_FUNCTION_TRACER
15− # mount -t debugfs nodev /sys/kernel/debug
16− # echo function > /sys/kernel/debug/tracing/current_tracer
17− $ cat /sys/kernel/debug/tracing/trace_pipe > ~/raw_trace_func
15+ # mount -t tracefs nodev /sys/kernel/tracing
16+ # echo function > /sys/kernel/tracing/current_tracer
17+ $ cat /sys/kernel/tracing/trace_pipe > ~/raw_trace_func
1818 Wait some times but not too much, the script is a bit slow.
1919 Break the pipe (Ctrl + Z)
2020 $ scripts/tracing/draw_functrace.py < ~/raw_trace_func > draw_functrace
tools/lib/api/fs/tracing_path.c+2−2
@@ -14,8 +14,8 @@ · 13 unmodified lines
1414 #include "tracing_path.h"
1515
1616 static char tracing_mnt[PATH_MAX] = "/sys/kernel/debug";
17−static char tracing_path[PATH_MAX] = "/sys/kernel/debug/tracing";
18−static char tracing_events_path[PATH_MAX] = "/sys/kernel/debug/tracing/events";
17+static char tracing_path[PATH_MAX] = "/sys/kernel/tracing";
18+static char tracing_events_path[PATH_MAX] = "/sys/kernel/tracing/events";
1919
2020 static void __tracing_path_set(const char *tracing, const char *mountpoint)
2121 {
tools/testing/selftests/ftrace/test.d/filter/event-filter-function.tc+58−0
@@ -0,0 +1,58 @@
1+#!/bin/sh
2+# SPDX-License-Identifier: GPL-2.0
3+# description: event filter function - test event filtering on functions
4+# requires: set_event events/kmem/kmem_cache_free/filter
5+# flags: instance
6+
7+fail() { #msg
8+ echo $1
9+ exit_fail
10+}
11+
12+echo "Test event filter function name"
13+echo 0 > tracing_on
14+echo 0 > events/enable
15+echo > trace
16+echo 'call_site.function == exit_mmap' > events/kmem/kmem_cache_free/filter
17+echo 1 > events/kmem/kmem_cache_free/enable
18+echo 1 > tracing_on
19+ls > /dev/null
20+echo 0 > events/kmem/kmem_cache_free/enable
21+
22+hitcnt=`grep kmem_cache_free trace| grep exit_mmap | wc -l`
23+misscnt=`grep kmem_cache_free trace| grep -v exit_mmap | wc -l`
24+
25+if [ $hitcnt -eq 0 ]; then
26+ exit_fail
27+fi
28+
29+if [ $misscnt -gt 0 ]; then
30+ exit_fail
31+fi
32+
33+address=`grep ' exit_mmap$' /proc/kallsyms | cut -d' ' -f1`
34+
35+echo "Test event filter function address"
36+echo 0 > tracing_on
37+echo 0 > events/enable
38+echo > trace
39+echo "call_site.function == 0x$address" > events/kmem/kmem_cache_free/filter
40+echo 1 > events/kmem/kmem_cache_free/enable
41+echo 1 > tracing_on
42+sleep 1
43+echo 0 > events/kmem/kmem_cache_free/enable
44+
45+hitcnt=`grep kmem_cache_free trace| grep exit_mmap | wc -l`
46+misscnt=`grep kmem_cache_free trace| grep -v exit_mmap | wc -l`
47+
48+if [ $hitcnt -eq 0 ]; then
49+ exit_fail
50+fi
51+
52+if [ $misscnt -gt 0 ]; then
53+ exit_fail
54+fi
55+
56+reset_events_filter
57+
58+exit 0
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-stack.tc+24−0
@@ -0,0 +1,24 @@
1+#!/bin/sh
2+# SPDX-License-Identifier: GPL-2.0
3+# description: event trigger - test inter-event histogram trigger trace action with dynamic string param
4+# requires: set_event synthetic_events events/sched/sched_process_exec/hist "long[]' >> synthetic_events":README
5+
6+fail() { #msg
7+ echo $1
8+ exit_fail
9+}
10+
11+echo "Test create synthetic event with stack"
12+
13+
14+echo 's:wake_lat pid_t pid; u64 delta; unsigned long[] stack;' > dynamic_events
15+echo 'hist:keys=next_pid:ts=common_timestamp.usecs,st=stacktrace if prev_state == 1||prev_state == 2' >> events/sched/sched_switch/trigger
16+echo 'hist:keys=prev_pid:delta=common_timestamp.usecs-$ts,s=$st:onmax($delta).trace(wake_lat,prev_pid,$delta,$s)' >> events/sched/sched_switch/trigger
17+echo 1 > events/synthetic/wake_lat/enable
18+sleep 1
19+
20+if ! grep -q "=>.*sched" trace; then
21+ fail "Failed to create synthetic event with stack"
22+fi
23+
24+exit 0
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-syntax.tc+6−0
@@ -70,6 +70,12 @@ grep "myevent[[:space:]]unsigned long var" synthetic_events · 69 unmodified lines
7070 echo "myevent char var[10]" > synthetic_events
7171 grep "myevent[[:space:]]char\[10\] var" synthetic_events
7272
73+if grep -q 'long\[\]' README; then
74+ # test stacktrace type
75+ echo "myevent unsigned long[] var" > synthetic_events
76+ grep "myevent[[:space:]]unsigned long\[\] var" synthetic_events
77+fi
78+
7379 do_reset
7480
7581 exit 0
tools/tracing/latency/latency-collector.c+1−1
@@ -1584,7 +1584,7 @@ static void *do_printloop(void *arg) · 1583 unmodified lines
15841584 /*
15851585 * Toss a coin to decide if we want to sleep before printing
15861586 * out the backtrace. The reason for this is that opening
1587− * /sys/kernel/debug/tracing/trace will cause a blackout of
1587+ * /sys/kernel/tracing/trace will cause a blackout of
15881588 * hundreds of ms, where no latencies will be noted by the
15891589 * latency tracer. Thus by randomly sleeping we try to avoid
15901590 * missing traces systematically due to this. With this option