ftrace.txt 68.9 KB
Newer Older
Steven Rostedt's avatar
Steven Rostedt committed
1
2
3
4
		ftrace - Function Tracer
		========================

Copyright 2008 Red Hat Inc.
Steven Rostedt's avatar
Steven Rostedt committed
5
6
   Author:   Steven Rostedt <srostedt@redhat.com>
  License:   The GNU Free Documentation License, Version 1.2
Steven Rostedt's avatar
Steven Rostedt committed
7
               (dual licensed under the GPL v2)
Steven Rostedt's avatar
Steven Rostedt committed
8
9
Reviewers:   Elias Oltmanns, Randy Dunlap, Andrew Morton,
	     John Kacur, and David Teigland.
10
Written for: 2.6.28-rc2
Steven Rostedt's avatar
Steven Rostedt committed
11
12
13
14
15
16

Introduction
------------

Ftrace is an internal tracer designed to help out developers and
designers of systems to find what is going on inside the kernel.
Ingo Molnar's avatar
Ingo Molnar committed
17
18
It can be used for debugging or analyzing latencies and
performance issues that take place outside of user-space.
Steven Rostedt's avatar
Steven Rostedt committed
19
20

Although ftrace is the function tracer, it also includes an
Ingo Molnar's avatar
Ingo Molnar committed
21
22
23
24
25
26
infrastructure that allows for other types of tracing. Some of
the tracers that are currently in ftrace include a tracer to
trace context switches, the time it takes for a high priority
task to run after it was woken up, the time interrupts are
disabled, and more (ftrace allows for tracer plugins, which
means that the list of tracers can always grow).
Steven Rostedt's avatar
Steven Rostedt committed
27
28


29
30
31
32
33
34
Implementation Details
----------------------

See ftrace-design.txt for details for arch porters and such.


Steven Rostedt's avatar
Steven Rostedt committed
35
36
37
The File System
---------------

Ingo Molnar's avatar
Ingo Molnar committed
38
39
Ftrace uses the debugfs file system to hold the control files as
well as the files to display output.
Steven Rostedt's avatar
Steven Rostedt committed
40

41
42
43
44
45
46
47
48
49
When debugfs is configured into the kernel (which selecting any ftrace
option will do) the directory /sys/kernel/debug will be created. To mount
this directory, you can add to your /etc/fstab file:

 debugfs       /sys/kernel/debug          debugfs defaults        0       0

Or you can mount it at run time with:

 mount -t debugfs nodev /sys/kernel/debug
Steven Rostedt's avatar
Steven Rostedt committed
50

51
52
For quicker access to that directory you may want to make a soft link to
it:
Steven Rostedt's avatar
Steven Rostedt committed
53

54
55
56
57
58
59
60
 ln -s /sys/kernel/debug /debug

Any selected ftrace option will also create a directory called tracing
within the debugfs. The rest of the document will assume that you are in
the ftrace directory (cd /sys/kernel/debug/tracing) and will only concentrate
on the files within that directory and not distract from the content with
the extended "/sys/kernel/debug/tracing" path name.
Steven Rostedt's avatar
Steven Rostedt committed
61
62
63
64
65
66
67
68
69
70

That's it! (assuming that you have ftrace configured into your kernel)

After mounting the debugfs, you can see a directory called
"tracing".  This directory contains the control and output files
of ftrace. Here is a list of some of the key files:


 Note: all time values are in microseconds.

Ingo Molnar's avatar
Ingo Molnar committed
71
72
73
74
75
76
77
78
79
80
81
82
  current_tracer:

	This is used to set or display the current tracer
	that is configured.

  available_tracers:

	This holds the different types of tracers that
	have been compiled into the kernel. The
	tracers listed here can be configured by
	echoing their name into current_tracer.

83
  tracing_on:
Ingo Molnar's avatar
Ingo Molnar committed
84

85
86
87
	This sets or displays whether writing to the trace
	ring buffer is enabled. Echo 0 into this file to disable
	the tracer or 1 to enable it.
Ingo Molnar's avatar
Ingo Molnar committed
88
89
90
91
92
93
94
95
96
97

  trace:

	This file holds the output of the trace in a human
	readable format (described below).

  trace_pipe:

	The output is the same as the "trace" file but this
	file is meant to be streamed with live tracing.
98
99
100
101
102
103
104
105
106
	Reads from this file will block until new data is
	retrieved.  Unlike the "trace" file, this file is a
	consumer. This means reading from this file causes
	sequential reads to display more current data. Once
	data is read from this file, it is consumed, and
	will not be read again with a sequential read. The
	"trace" file is static, and if the tracer is not
	adding more data,they will display the same
	information every time they are read.
Ingo Molnar's avatar
Ingo Molnar committed
107
108
109
110
111
112
113

  trace_options:

	This file lets the user control the amount of data
	that is displayed in one of the above output
	files.

114
  tracing_max_latency:
Ingo Molnar's avatar
Ingo Molnar committed
115
116
117
118

	Some of the tracers record the max latency.
	For example, the time interrupts are disabled.
	This time is saved in this file. The max trace
119
120
121
122
	will also be stored, and displayed by "trace".
	A new max trace will only be recorded if the
	latency is greater than the value in this
	file. (in microseconds)
Ingo Molnar's avatar
Ingo Molnar committed
123
124
125
126
127
128
129
130
131
132
133
134
135

  buffer_size_kb:

	This sets or displays the number of kilobytes each CPU
	buffer can hold. The tracer buffers are the same size
	for each CPU. The displayed number is the size of the
	CPU buffer and not total size of all buffers. The
	trace buffers are allocated in pages (blocks of memory
	that the kernel uses for allocation, usually 4 KB in size).
	If the last page allocated has room for more bytes
	than requested, the rest of the page will be used,
	making the actual allocation bigger than requested.
	( Note, the size may not be a multiple of the page size
136
	  due to buffer management overhead. )
Ingo Molnar's avatar
Ingo Molnar committed
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157

	This can only be updated when the current_tracer
	is set to "nop".

  tracing_cpumask:

	This is a mask that lets the user only trace
	on specified CPUS. The format is a hex string
	representing the CPUS.

  set_ftrace_filter:

	When dynamic ftrace is configured in (see the
	section below "dynamic ftrace"), the code is dynamically
	modified (code text rewrite) to disable calling of the
	function profiler (mcount). This lets tracing be configured
	in with practically no overhead in performance.  This also
	has a side effect of enabling or disabling specific functions
	to be traced. Echoing names of functions into this file
	will limit the trace to only those functions.

158
159
160
	This interface also allows for commands to be used. See the
	"Filter commands" section for more details.

Ingo Molnar's avatar
Ingo Molnar committed
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
  set_ftrace_notrace:

	This has an effect opposite to that of
	set_ftrace_filter. Any function that is added here will not
	be traced. If a function exists in both set_ftrace_filter
	and set_ftrace_notrace,	the function will _not_ be traced.

  set_ftrace_pid:

	Have the function tracer only trace a single thread.

  set_graph_function:

	Set a "trigger" function where tracing should start
	with the function graph tracer (See the section
	"dynamic ftrace" for more details).

  available_filter_functions:

	This lists the functions that ftrace
	has processed and can trace. These are the function
	names that you can pass to "set_ftrace_filter" or
	"set_ftrace_notrace". (See the section "dynamic ftrace"
	below for more details.)
Steven Rostedt's avatar
Steven Rostedt committed
185
186
187
188
189


The Tracers
-----------

Steven Rostedt's avatar
Steven Rostedt committed
190
Here is the list of current tracers that may be configured.
Steven Rostedt's avatar
Steven Rostedt committed
191

Ingo Molnar's avatar
Ingo Molnar committed
192
193
194
195
  "function"

	Function call tracer to trace all kernel functions.

196
  "function_graph"
Ingo Molnar's avatar
Ingo Molnar committed
197
198
199
200
201
202
203
204
205
206
207
208
209
210

	Similar to the function tracer except that the
	function tracer probes the functions on their entry
	whereas the function graph tracer traces on both entry
	and exit of the functions. It then provides the ability
	to draw a graph of function calls similar to C code
	source.

  "irqsoff"

	Traces the areas that disable interrupts and saves
	the trace with the longest max latency.
	See tracing_max_latency. When a new max is recorded,
	it replaces the old trace. It is best to view this
211
	trace with the latency-format option enabled.
Steven Rostedt's avatar
Steven Rostedt committed
212

Ingo Molnar's avatar
Ingo Molnar committed
213
  "preemptoff"
214

Ingo Molnar's avatar
Ingo Molnar committed
215
216
	Similar to irqsoff but traces and records the amount of
	time for which preemption is disabled.
Steven Rostedt's avatar
Steven Rostedt committed
217

Ingo Molnar's avatar
Ingo Molnar committed
218
  "preemptirqsoff"
Steven Rostedt's avatar
Steven Rostedt committed
219

Ingo Molnar's avatar
Ingo Molnar committed
220
221
222
	Similar to irqsoff and preemptoff, but traces and
	records the largest time for which irqs and/or preemption
	is disabled.
Steven Rostedt's avatar
Steven Rostedt committed
223

Ingo Molnar's avatar
Ingo Molnar committed
224
  "wakeup"
Steven Rostedt's avatar
Steven Rostedt committed
225

Ingo Molnar's avatar
Ingo Molnar committed
226
227
228
	Traces and records the max latency that it takes for
	the highest priority task to get scheduled after
	it has been woken up.
229
230
231
232
233
234
235
        Traces all tasks as an average developer would expect.

  "wakeup_rt"

        Traces and records the max latency that it takes for just
        RT tasks (as the current "wakeup" does). This is useful
        for those interested in wake up timings of RT tasks.
Steven Rostedt's avatar
Steven Rostedt committed
236

Ingo Molnar's avatar
Ingo Molnar committed
237
  "hw-branch-tracer"
Steven Rostedt's avatar
Steven Rostedt committed
238

Ingo Molnar's avatar
Ingo Molnar committed
239
240
241
242
243
244
245
246
	Uses the BTS CPU feature on x86 CPUs to traces all
	branches executed.

  "nop"

	This is the "trace nothing" tracer. To remove all
	tracers from tracing simply echo "nop" into
	current_tracer.
247

Steven Rostedt's avatar
Steven Rostedt committed
248
249
250
251

Examples of using the tracer
----------------------------

Ingo Molnar's avatar
Ingo Molnar committed
252
253
254
Here are typical examples of using the tracers when controlling
them only with the debugfs interface (without using any
user-land utilities).
Steven Rostedt's avatar
Steven Rostedt committed
255
256
257
258

Output format:
--------------

Steven Rostedt's avatar
Steven Rostedt committed
259
Here is an example of the output format of the file "trace"
Steven Rostedt's avatar
Steven Rostedt committed
260
261

                             --------
Steven Rostedt's avatar
Steven Rostedt committed
262
# tracer: function
Steven Rostedt's avatar
Steven Rostedt committed
263
264
265
266
267
268
269
270
#
#           TASK-PID   CPU#    TIMESTAMP  FUNCTION
#              | |      |          |         |
            bash-4251  [01] 10152.583854: path_put <-path_walk
            bash-4251  [01] 10152.583855: dput <-path_put
            bash-4251  [01] 10152.583855: _atomic_dec_and_lock <-dput
                             --------

Ingo Molnar's avatar
Ingo Molnar committed
271
272
273
274
275
276
277
A header is printed with the tracer name that is represented by
the trace. In this case the tracer is "function". Then a header
showing the format. Task name "bash", the task PID "4251", the
CPU that it was running on "01", the timestamp in <secs>.<usecs>
format, the function name that was traced "path_put" and the
parent function that called this function "path_walk". The
timestamp is the time at which the function was entered.
Steven Rostedt's avatar
Steven Rostedt committed
278
279
280
281

Latency trace format
--------------------

282
283
When the latency-format option is enabled, the trace file gives
somewhat more information to see why a latency happened.
Ingo Molnar's avatar
Ingo Molnar committed
284
Here is a typical trace.
Steven Rostedt's avatar
Steven Rostedt committed
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310

# tracer: irqsoff
#
irqsoff latency trace v1.1.5 on 2.6.26-rc8
--------------------------------------------------------------------
 latency: 97 us, #3/3, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
    -----------------
    | task: swapper-0 (uid:0 nice:0 policy:0 rt_prio:0)
    -----------------
 => started at: apic_timer_interrupt
 => ended at:   do_softirq

#                _------=> CPU#
#               / _-----=> irqs-off
#              | / _----=> need-resched
#              || / _---=> hardirq/softirq
#              ||| / _--=> preempt-depth
#              |||| /
#              |||||     delay
#  cmd     pid ||||| time  |   caller
#     \   /    |||||   \   |   /
  <idle>-0     0d..1    0us+: trace_hardirqs_off_thunk (apic_timer_interrupt)
  <idle>-0     0d.s.   97us : __do_softirq (do_softirq)
  <idle>-0     0d.s1   98us : trace_hardirqs_on (do_softirq)


Ingo Molnar's avatar
Ingo Molnar committed
311
312
313
314
315
316
317
318
This shows that the current tracer is "irqsoff" tracing the time
for which interrupts were disabled. It gives the trace version
and the version of the kernel upon which this was executed on
(2.6.26-rc8). Then it displays the max latency in microsecs (97
us). The number of trace entries displayed and the total number
recorded (both are three: #3/3). The type of preemption that was
used (PREEMPT). VP, KP, SP, and HP are always zero and are
reserved for later use. #P is the number of online CPUS (#P:2).
Steven Rostedt's avatar
Steven Rostedt committed
319

Ingo Molnar's avatar
Ingo Molnar committed
320
321
The task is the process that was running when the latency
occurred. (swapper pid: 0).
Steven Rostedt's avatar
Steven Rostedt committed
322

Ingo Molnar's avatar
Ingo Molnar committed
323
324
The start and stop (the functions in which the interrupts were
disabled and enabled respectively) that caused the latencies:
Steven Rostedt's avatar
Steven Rostedt committed
325
326
327
328
329
330
331
332
333
334
335

  apic_timer_interrupt is where the interrupts were disabled.
  do_softirq is where they were enabled again.

The next lines after the header are the trace itself. The header
explains which is which.

  cmd: The name of the process in the trace.

  pid: The PID of that process.

Steven Rostedt's avatar
Steven Rostedt committed
336
  CPU#: The CPU which the process was running on.
Steven Rostedt's avatar
Steven Rostedt committed
337
338

  irqs-off: 'd' interrupts are disabled. '.' otherwise.
339
340
341
	    Note: If the architecture does not support a way to
		  read the irq flags variable, an 'X' will always
		  be printed here.
Steven Rostedt's avatar
Steven Rostedt committed
342
343
344
345

  need-resched: 'N' task need_resched is set, '.' otherwise.

  hardirq/softirq:
Steven Rostedt's avatar
Steven Rostedt committed
346
	'H' - hard irq occurred inside a softirq.
Steven Rostedt's avatar
Steven Rostedt committed
347
348
349
350
351
352
353
354
	'h' - hard irq is running
	's' - soft irq is running
	'.' - normal context.

  preempt-depth: The level of preempt_disabled

The above is mostly meaningful for kernel developers.

355
356
357
358
  time: When the latency-format option is enabled, the trace file
	output includes a timestamp relative to the start of the
	trace. This differs from the output when latency-format
	is disabled, which includes an absolute timestamp.
Steven Rostedt's avatar
Steven Rostedt committed
359
360

  delay: This is just to help catch your eye a bit better. And
Ingo Molnar's avatar
Ingo Molnar committed
361
362
363
364
365
366
	 needs to be fixed to be only relative to the same CPU.
	 The marks are determined by the difference between this
	 current trace and the next trace.
	  '!' - greater than preempt_mark_thresh (default 100)
	  '+' - greater than 1 microsecond
	  ' ' - less than or equal to 1 microsecond.
Steven Rostedt's avatar
Steven Rostedt committed
367
368
369
370

  The rest is the same as the 'trace' file.


371
372
trace_options
-------------
Steven Rostedt's avatar
Steven Rostedt committed
373

Ingo Molnar's avatar
Ingo Molnar committed
374
375
The trace_options file is used to control what gets printed in
the trace output. To see what is available, simply cat the file:
Steven Rostedt's avatar
Steven Rostedt committed
376

377
  cat trace_options
Steven Rostedt's avatar
Steven Rostedt committed
378
  print-parent nosym-offset nosym-addr noverbose noraw nohex nobin \
Ingo Molnar's avatar
Ingo Molnar committed
379
  noblock nostacktrace nosched-tree nouserstacktrace nosym-userobj
Steven Rostedt's avatar
Steven Rostedt committed
380

Ingo Molnar's avatar
Ingo Molnar committed
381
382
To disable one of the options, echo in the option prepended with
"no".
Steven Rostedt's avatar
Steven Rostedt committed
383

384
  echo noprint-parent > trace_options
Steven Rostedt's avatar
Steven Rostedt committed
385
386
387

To enable an option, leave off the "no".

388
  echo sym-offset > trace_options
Steven Rostedt's avatar
Steven Rostedt committed
389
390
391

Here are the available options:

Ingo Molnar's avatar
Ingo Molnar committed
392
393
  print-parent - On function traces, display the calling (parent)
		 function as well as the function being traced.
Steven Rostedt's avatar
Steven Rostedt committed
394
395
396
397
398
399
400
401

  print-parent:
   bash-4000  [01]  1477.606694: simple_strtoul <-strict_strtoul

  noprint-parent:
   bash-4000  [01]  1477.606694: simple_strtoul


Ingo Molnar's avatar
Ingo Molnar committed
402
403
404
405
  sym-offset - Display not only the function name, but also the
	       offset in the function. For example, instead of
	       seeing just "ktime_get", you will see
	       "ktime_get+0xb/0x20".
Steven Rostedt's avatar
Steven Rostedt committed
406
407
408
409

  sym-offset:
   bash-4000  [01]  1477.606694: simple_strtoul+0x6/0xa0

Ingo Molnar's avatar
Ingo Molnar committed
410
411
  sym-addr - this will also display the function address as well
	     as the function name.
Steven Rostedt's avatar
Steven Rostedt committed
412
413
414
415

  sym-addr:
   bash-4000  [01]  1477.606694: simple_strtoul <c0339346>

416
417
  verbose - This deals with the trace file when the
            latency-format option is enabled.
Steven Rostedt's avatar
Steven Rostedt committed
418
419
420
421

    bash  4000 1 0 00000000 00010a95 [58127d26] 1720.415ms \
    (+0.000ms): simple_strtoul (strict_strtoul)

Ingo Molnar's avatar
Ingo Molnar committed
422
423
424
  raw - This will display raw numbers. This option is best for
	use with user applications that can translate the raw
	numbers better than having it done in the kernel.
Steven Rostedt's avatar
Steven Rostedt committed
425

Ingo Molnar's avatar
Ingo Molnar committed
426
427
  hex - Similar to raw, but the numbers will be in a hexadecimal
	format.
Steven Rostedt's avatar
Steven Rostedt committed
428
429
430
431
432

  bin - This will print out the formats in raw binary.

  block - TBD (needs update)

Ingo Molnar's avatar
Ingo Molnar committed
433
434
435
436
  stacktrace - This is one of the options that changes the trace
	       itself. When a trace is recorded, so is the stack
	       of functions. This allows for back traces of
	       trace sites.
Steven Rostedt's avatar
Steven Rostedt committed
437

Ingo Molnar's avatar
Ingo Molnar committed
438
439
  userstacktrace - This option changes the trace. It records a
		   stacktrace of the current userspace thread.
440

Ingo Molnar's avatar
Ingo Molnar committed
441
442
443
444
445
446
  sym-userobj - when user stacktrace are enabled, look up which
		object the address belongs to, and print a
		relative address. This is especially useful when
		ASLR is on, otherwise you don't get a chance to
		resolve the address to object/file/line after
		the app is no longer running
447

Ingo Molnar's avatar
Ingo Molnar committed
448
		The lookup is performed when you read
449
		trace,trace_pipe. Example:
450
451
452
453

		a.out-1623  [000] 40874.465068: /root/a.out[+0x480] <-/root/a.out[+0
x494] <- /root/a.out[+0x4a8] <- /lib/libc-2.7.so[+0x1e1a6]

Ingo Molnar's avatar
Ingo Molnar committed
454
455
456
  sched-tree - trace all tasks that are on the runqueue, at
	       every scheduling event. Will add overhead if
	       there's a lot of tasks running at once.
Steven Rostedt's avatar
Steven Rostedt committed
457

458
459
460
461
462
  latency-format - This option changes the trace. When
                   it is enabled, the trace displays
                   additional information about the
                   latencies, as described in "Latency
                   trace format".
Steven Rostedt's avatar
Steven Rostedt committed
463

464
465
466
467
468
  overwrite - This controls what happens when the trace buffer is
              full. If "1" (default), the oldest events are
              discarded and overwritten. If "0", then the newest
              events are discarded.

Steven Rostedt's avatar
Steven Rostedt committed
469
470
471
ftrace_enabled
--------------

Ingo Molnar's avatar
Ingo Molnar committed
472
473
474
475
The following tracers (listed below) give different output
depending on whether or not the sysctl ftrace_enabled is set. To
set ftrace_enabled, one can either use the sysctl function or
set it via the proc file system interface.
Steven Rostedt's avatar
Steven Rostedt committed
476
477
478
479
480
481
482

  sysctl kernel.ftrace_enabled=1

 or

  echo 1 > /proc/sys/kernel/ftrace_enabled

Ingo Molnar's avatar
Ingo Molnar committed
483
484
To disable ftrace_enabled simply replace the '1' with '0' in the
above commands.
Steven Rostedt's avatar
Steven Rostedt committed
485

Ingo Molnar's avatar
Ingo Molnar committed
486
487
488
When ftrace_enabled is set the tracers will also record the
functions that are within the trace. The descriptions of the
tracers will also show an example with ftrace enabled.
Steven Rostedt's avatar
Steven Rostedt committed
489
490
491
492
493
494
495


irqsoff
-------

When interrupts are disabled, the CPU can not react to any other
external event (besides NMIs and SMIs). This prevents the timer
Ingo Molnar's avatar
Ingo Molnar committed
496
497
498
interrupt from triggering or the mouse interrupt from letting
the kernel know of a new mouse event. The result is a latency
with the reaction time.
Steven Rostedt's avatar
Steven Rostedt committed
499

Ingo Molnar's avatar
Ingo Molnar committed
500
501
502
503
504
The irqsoff tracer tracks the time for which interrupts are
disabled. When a new maximum latency is hit, the tracer saves
the trace leading up to that latency point so that every time a
new maximum is reached, the old saved trace is discarded and the
new trace is saved.
Steven Rostedt's avatar
Steven Rostedt committed
505

Ingo Molnar's avatar
Ingo Molnar committed
506
507
To reset the maximum, echo 0 into tracing_max_latency. Here is
an example:
Steven Rostedt's avatar
Steven Rostedt committed
508

509
 # echo irqsoff > current_tracer
510
 # echo latency-format > trace_options
511
 # echo 0 > tracing_max_latency
512
 # echo 1 > tracing_on
Steven Rostedt's avatar
Steven Rostedt committed
513
514
 # ls -ltr
 [...]
515
 # echo 0 > tracing_on
516
 # cat trace
Steven Rostedt's avatar
Steven Rostedt committed
517
518
# tracer: irqsoff
#
Steven Rostedt's avatar
Steven Rostedt committed
519
irqsoff latency trace v1.1.5 on 2.6.26
Steven Rostedt's avatar
Steven Rostedt committed
520
--------------------------------------------------------------------
Steven Rostedt's avatar
Steven Rostedt committed
521
 latency: 12 us, #3/3, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
Steven Rostedt's avatar
Steven Rostedt committed
522
    -----------------
Steven Rostedt's avatar
Steven Rostedt committed
523
    | task: bash-3730 (uid:0 nice:0 policy:0 rt_prio:0)
Steven Rostedt's avatar
Steven Rostedt committed
524
    -----------------
Steven Rostedt's avatar
Steven Rostedt committed
525
526
 => started at: sys_setpgid
 => ended at:   sys_setpgid
Steven Rostedt's avatar
Steven Rostedt committed
527
528
529
530
531
532
533
534
535
536

#                _------=> CPU#
#               / _-----=> irqs-off
#              | / _----=> need-resched
#              || / _---=> hardirq/softirq
#              ||| / _--=> preempt-depth
#              |||| /
#              |||||     delay
#  cmd     pid ||||| time  |   caller
#     \   /    |||||   \   |   /
Steven Rostedt's avatar
Steven Rostedt committed
537
538
539
    bash-3730  1d...    0us : _write_lock_irq (sys_setpgid)
    bash-3730  1d..1    1us+: _write_unlock_irq (sys_setpgid)
    bash-3730  1d..2   14us : trace_hardirqs_on (sys_setpgid)
Steven Rostedt's avatar
Steven Rostedt committed
540
541


Steven Rostedt's avatar
Steven Rostedt committed
542
Here we see that that we had a latency of 12 microsecs (which is
Ingo Molnar's avatar
Ingo Molnar committed
543
544
545
546
547
very good). The _write_lock_irq in sys_setpgid disabled
interrupts. The difference between the 12 and the displayed
timestamp 14us occurred because the clock was incremented
between the time of recording the max latency and the time of
recording the function that had that latency.
Steven Rostedt's avatar
Steven Rostedt committed
548

Steven Rostedt's avatar
Steven Rostedt committed
549
550
Note the above example had ftrace_enabled not set. If we set the
ftrace_enabled, we get a much larger output:
Steven Rostedt's avatar
Steven Rostedt committed
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597

# tracer: irqsoff
#
irqsoff latency trace v1.1.5 on 2.6.26-rc8
--------------------------------------------------------------------
 latency: 50 us, #101/101, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
    -----------------
    | task: ls-4339 (uid:0 nice:0 policy:0 rt_prio:0)
    -----------------
 => started at: __alloc_pages_internal
 => ended at:   __alloc_pages_internal

#                _------=> CPU#
#               / _-----=> irqs-off
#              | / _----=> need-resched
#              || / _---=> hardirq/softirq
#              ||| / _--=> preempt-depth
#              |||| /
#              |||||     delay
#  cmd     pid ||||| time  |   caller
#     \   /    |||||   \   |   /
      ls-4339  0...1    0us+: get_page_from_freelist (__alloc_pages_internal)
      ls-4339  0d..1    3us : rmqueue_bulk (get_page_from_freelist)
      ls-4339  0d..1    3us : _spin_lock (rmqueue_bulk)
      ls-4339  0d..1    4us : add_preempt_count (_spin_lock)
      ls-4339  0d..2    4us : __rmqueue (rmqueue_bulk)
      ls-4339  0d..2    5us : __rmqueue_smallest (__rmqueue)
      ls-4339  0d..2    5us : __mod_zone_page_state (__rmqueue_smallest)
      ls-4339  0d..2    6us : __rmqueue (rmqueue_bulk)
      ls-4339  0d..2    6us : __rmqueue_smallest (__rmqueue)
      ls-4339  0d..2    7us : __mod_zone_page_state (__rmqueue_smallest)
      ls-4339  0d..2    7us : __rmqueue (rmqueue_bulk)
      ls-4339  0d..2    8us : __rmqueue_smallest (__rmqueue)
[...]
      ls-4339  0d..2   46us : __rmqueue_smallest (__rmqueue)
      ls-4339  0d..2   47us : __mod_zone_page_state (__rmqueue_smallest)
      ls-4339  0d..2   47us : __rmqueue (rmqueue_bulk)
      ls-4339  0d..2   48us : __rmqueue_smallest (__rmqueue)
      ls-4339  0d..2   48us : __mod_zone_page_state (__rmqueue_smallest)
      ls-4339  0d..2   49us : _spin_unlock (rmqueue_bulk)
      ls-4339  0d..2   49us : sub_preempt_count (_spin_unlock)
      ls-4339  0d..1   50us : get_page_from_freelist (__alloc_pages_internal)
      ls-4339  0d..2   51us : trace_hardirqs_on (__alloc_pages_internal)



Here we traced a 50 microsecond latency. But we also see all the
Ingo Molnar's avatar
Ingo Molnar committed
598
599
600
601
functions that were called during that time. Note that by
enabling function tracing, we incur an added overhead. This
overhead may extend the latency times. But nevertheless, this
trace has provided some very helpful debugging information.
Steven Rostedt's avatar
Steven Rostedt committed
602
603
604
605
606


preemptoff
----------

Ingo Molnar's avatar
Ingo Molnar committed
607
608
609
610
When preemption is disabled, we may be able to receive
interrupts but the task cannot be preempted and a higher
priority task must wait for preemption to be enabled again
before it can preempt a lower priority task.
Steven Rostedt's avatar
Steven Rostedt committed
611

Steven Rostedt's avatar
Steven Rostedt committed
612
The preemptoff tracer traces the places that disable preemption.
Ingo Molnar's avatar
Ingo Molnar committed
613
614
615
Like the irqsoff tracer, it records the maximum latency for
which preemption was disabled. The control of preemptoff tracer
is much like the irqsoff tracer.
Steven Rostedt's avatar
Steven Rostedt committed
616

617
 # echo preemptoff > current_tracer
618
 # echo latency-format > trace_options
619
 # echo 0 > tracing_max_latency
620
 # echo 1 > tracing_on
Steven Rostedt's avatar
Steven Rostedt committed
621
622
 # ls -ltr
 [...]
623
 # echo 0 > tracing_on
624
 # cat trace
Steven Rostedt's avatar
Steven Rostedt committed
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
# tracer: preemptoff
#
preemptoff latency trace v1.1.5 on 2.6.26-rc8
--------------------------------------------------------------------
 latency: 29 us, #3/3, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
    -----------------
    | task: sshd-4261 (uid:0 nice:0 policy:0 rt_prio:0)
    -----------------
 => started at: do_IRQ
 => ended at:   __do_softirq

#                _------=> CPU#
#               / _-----=> irqs-off
#              | / _----=> need-resched
#              || / _---=> hardirq/softirq
#              ||| / _--=> preempt-depth
#              |||| /
#              |||||     delay
#  cmd     pid ||||| time  |   caller
#     \   /    |||||   \   |   /
    sshd-4261  0d.h.    0us+: irq_enter (do_IRQ)
    sshd-4261  0d.s.   29us : _local_bh_enable (__do_softirq)
    sshd-4261  0d.s1   30us : trace_preempt_on (__do_softirq)


Ingo Molnar's avatar
Ingo Molnar committed
650
651
652
653
654
655
This has some more changes. Preemption was disabled when an
interrupt came in (notice the 'h'), and was enabled while doing
a softirq. (notice the 's'). But we also see that interrupts
have been disabled when entering the preempt off section and
leaving it (the 'd'). We do not know if interrupts were enabled
in the mean time.
Steven Rostedt's avatar
Steven Rostedt committed
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713

# tracer: preemptoff
#
preemptoff latency trace v1.1.5 on 2.6.26-rc8
--------------------------------------------------------------------
 latency: 63 us, #87/87, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
    -----------------
    | task: sshd-4261 (uid:0 nice:0 policy:0 rt_prio:0)
    -----------------
 => started at: remove_wait_queue
 => ended at:   __do_softirq

#                _------=> CPU#
#               / _-----=> irqs-off
#              | / _----=> need-resched
#              || / _---=> hardirq/softirq
#              ||| / _--=> preempt-depth
#              |||| /
#              |||||     delay
#  cmd     pid ||||| time  |   caller
#     \   /    |||||   \   |   /
    sshd-4261  0d..1    0us : _spin_lock_irqsave (remove_wait_queue)
    sshd-4261  0d..1    1us : _spin_unlock_irqrestore (remove_wait_queue)
    sshd-4261  0d..1    2us : do_IRQ (common_interrupt)
    sshd-4261  0d..1    2us : irq_enter (do_IRQ)
    sshd-4261  0d..1    2us : idle_cpu (irq_enter)
    sshd-4261  0d..1    3us : add_preempt_count (irq_enter)
    sshd-4261  0d.h1    3us : idle_cpu (irq_enter)
    sshd-4261  0d.h.    4us : handle_fasteoi_irq (do_IRQ)
[...]
    sshd-4261  0d.h.   12us : add_preempt_count (_spin_lock)
    sshd-4261  0d.h1   12us : ack_ioapic_quirk_irq (handle_fasteoi_irq)
    sshd-4261  0d.h1   13us : move_native_irq (ack_ioapic_quirk_irq)
    sshd-4261  0d.h1   13us : _spin_unlock (handle_fasteoi_irq)
    sshd-4261  0d.h1   14us : sub_preempt_count (_spin_unlock)
    sshd-4261  0d.h1   14us : irq_exit (do_IRQ)
    sshd-4261  0d.h1   15us : sub_preempt_count (irq_exit)
    sshd-4261  0d..2   15us : do_softirq (irq_exit)
    sshd-4261  0d...   15us : __do_softirq (do_softirq)
    sshd-4261  0d...   16us : __local_bh_disable (__do_softirq)
    sshd-4261  0d...   16us+: add_preempt_count (__local_bh_disable)
    sshd-4261  0d.s4   20us : add_preempt_count (__local_bh_disable)
    sshd-4261  0d.s4   21us : sub_preempt_count (local_bh_enable)
    sshd-4261  0d.s5   21us : sub_preempt_count (local_bh_enable)
[...]
    sshd-4261  0d.s6   41us : add_preempt_count (__local_bh_disable)
    sshd-4261  0d.s6   42us : sub_preempt_count (local_bh_enable)
    sshd-4261  0d.s7   42us : sub_preempt_count (local_bh_enable)
    sshd-4261  0d.s5   43us : add_preempt_count (__local_bh_disable)
    sshd-4261  0d.s5   43us : sub_preempt_count (local_bh_enable_ip)
    sshd-4261  0d.s6   44us : sub_preempt_count (local_bh_enable_ip)
    sshd-4261  0d.s5   44us : add_preempt_count (__local_bh_disable)
    sshd-4261  0d.s5   45us : sub_preempt_count (local_bh_enable)
[...]
    sshd-4261  0d.s.   63us : _local_bh_enable (__do_softirq)
    sshd-4261  0d.s1   64us : trace_preempt_on (__do_softirq)


Ingo Molnar's avatar
Ingo Molnar committed
714
715
716
717
718
719
The above is an example of the preemptoff trace with
ftrace_enabled set. Here we see that interrupts were disabled
the entire time. The irq_enter code lets us know that we entered
an interrupt 'h'. Before that, the functions being traced still
show that it is not in an interrupt, but we can see from the
functions themselves that this is not the case.
Steven Rostedt's avatar
Steven Rostedt committed
720

Ingo Molnar's avatar
Ingo Molnar committed
721
722
723
724
725
726
727
728
Notice that __do_softirq when called does not have a
preempt_count. It may seem that we missed a preempt enabling.
What really happened is that the preempt count is held on the
thread's stack and we switched to the softirq stack (4K stacks
in effect). The code does not copy the preempt count, but
because interrupts are disabled, we do not need to worry about
it. Having a tracer like this is good for letting people know
what really happens inside the kernel.
Steven Rostedt's avatar
Steven Rostedt committed
729
730
731
732
733


preemptirqsoff
--------------

Ingo Molnar's avatar
Ingo Molnar committed
734
735
736
737
Knowing the locations that have interrupts disabled or
preemption disabled for the longest times is helpful. But
sometimes we would like to know when either preemption and/or
interrupts are disabled.
Steven Rostedt's avatar
Steven Rostedt committed
738

Steven Rostedt's avatar
Steven Rostedt committed
739
Consider the following code:
Steven Rostedt's avatar
Steven Rostedt committed
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756

    local_irq_disable();
    call_function_with_irqs_off();
    preempt_disable();
    call_function_with_irqs_and_preemption_off();
    local_irq_enable();
    call_function_with_preemption_off();
    preempt_enable();

The irqsoff tracer will record the total length of
call_function_with_irqs_off() and
call_function_with_irqs_and_preemption_off().

The preemptoff tracer will record the total length of
call_function_with_irqs_and_preemption_off() and
call_function_with_preemption_off().

Ingo Molnar's avatar
Ingo Molnar committed
757
758
759
760
But neither will trace the time that interrupts and/or
preemption is disabled. This total time is the time that we can
not schedule. To record this time, use the preemptirqsoff
tracer.
Steven Rostedt's avatar
Steven Rostedt committed
761

Ingo Molnar's avatar
Ingo Molnar committed
762
763
Again, using this trace is much like the irqsoff and preemptoff
tracers.
Steven Rostedt's avatar
Steven Rostedt committed
764

765
 # echo preemptirqsoff > current_tracer
766
 # echo latency-format > trace_options
767
 # echo 0 > tracing_max_latency
768
 # echo 1 > tracing_on
Steven Rostedt's avatar
Steven Rostedt committed
769
770
 # ls -ltr
 [...]
771
 # echo 0 > tracing_on
772
 # cat trace
Steven Rostedt's avatar
Steven Rostedt committed
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
# tracer: preemptirqsoff
#
preemptirqsoff latency trace v1.1.5 on 2.6.26-rc8
--------------------------------------------------------------------
 latency: 293 us, #3/3, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
    -----------------
    | task: ls-4860 (uid:0 nice:0 policy:0 rt_prio:0)
    -----------------
 => started at: apic_timer_interrupt
 => ended at:   __do_softirq

#                _------=> CPU#
#               / _-----=> irqs-off
#              | / _----=> need-resched
#              || / _---=> hardirq/softirq
#              ||| / _--=> preempt-depth
#              |||| /
#              |||||     delay
#  cmd     pid ||||| time  |   caller
#     \   /    |||||   \   |   /
      ls-4860  0d...    0us!: trace_hardirqs_off_thunk (apic_timer_interrupt)
      ls-4860  0d.s.  294us : _local_bh_enable (__do_softirq)
      ls-4860  0d.s1  294us : trace_preempt_on (__do_softirq)



The trace_hardirqs_off_thunk is called from assembly on x86 when
Ingo Molnar's avatar
Ingo Molnar committed
800
801
802
803
interrupts are disabled in the assembly code. Without the
function tracing, we do not know if interrupts were enabled
within the preemption points. We do see that it started with
preemption enabled.
Steven Rostedt's avatar
Steven Rostedt committed
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890

Here is a trace with ftrace_enabled set:


# tracer: preemptirqsoff
#
preemptirqsoff latency trace v1.1.5 on 2.6.26-rc8
--------------------------------------------------------------------
 latency: 105 us, #183/183, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
    -----------------
    | task: sshd-4261 (uid:0 nice:0 policy:0 rt_prio:0)
    -----------------
 => started at: write_chan
 => ended at:   __do_softirq

#                _------=> CPU#
#               / _-----=> irqs-off
#              | / _----=> need-resched
#              || / _---=> hardirq/softirq
#              ||| / _--=> preempt-depth
#              |||| /
#              |||||     delay
#  cmd     pid ||||| time  |   caller
#     \   /    |||||   \   |   /
      ls-4473  0.N..    0us : preempt_schedule (write_chan)
      ls-4473  0dN.1    1us : _spin_lock (schedule)
      ls-4473  0dN.1    2us : add_preempt_count (_spin_lock)
      ls-4473  0d..2    2us : put_prev_task_fair (schedule)
[...]
      ls-4473  0d..2   13us : set_normalized_timespec (ktime_get_ts)
      ls-4473  0d..2   13us : __switch_to (schedule)
    sshd-4261  0d..2   14us : finish_task_switch (schedule)
    sshd-4261  0d..2   14us : _spin_unlock_irq (finish_task_switch)
    sshd-4261  0d..1   15us : add_preempt_count (_spin_lock_irqsave)
    sshd-4261  0d..2   16us : _spin_unlock_irqrestore (hrtick_set)
    sshd-4261  0d..2   16us : do_IRQ (common_interrupt)
    sshd-4261  0d..2   17us : irq_enter (do_IRQ)
    sshd-4261  0d..2   17us : idle_cpu (irq_enter)
    sshd-4261  0d..2   18us : add_preempt_count (irq_enter)
    sshd-4261  0d.h2   18us : idle_cpu (irq_enter)
    sshd-4261  0d.h.   18us : handle_fasteoi_irq (do_IRQ)
    sshd-4261  0d.h.   19us : _spin_lock (handle_fasteoi_irq)
    sshd-4261  0d.h.   19us : add_preempt_count (_spin_lock)
    sshd-4261  0d.h1   20us : _spin_unlock (handle_fasteoi_irq)
    sshd-4261  0d.h1   20us : sub_preempt_count (_spin_unlock)
[...]
    sshd-4261  0d.h1   28us : _spin_unlock (handle_fasteoi_irq)
    sshd-4261  0d.h1   29us : sub_preempt_count (_spin_unlock)
    sshd-4261  0d.h2   29us : irq_exit (do_IRQ)
    sshd-4261  0d.h2   29us : sub_preempt_count (irq_exit)
    sshd-4261  0d..3   30us : do_softirq (irq_exit)
    sshd-4261  0d...   30us : __do_softirq (do_softirq)
    sshd-4261  0d...   31us : __local_bh_disable (__do_softirq)
    sshd-4261  0d...   31us+: add_preempt_count (__local_bh_disable)
    sshd-4261  0d.s4   34us : add_preempt_count (__local_bh_disable)
[...]
    sshd-4261  0d.s3   43us : sub_preempt_count (local_bh_enable_ip)
    sshd-4261  0d.s4   44us : sub_preempt_count (local_bh_enable_ip)
    sshd-4261  0d.s3   44us : smp_apic_timer_interrupt (apic_timer_interrupt)
    sshd-4261  0d.s3   45us : irq_enter (smp_apic_timer_interrupt)
    sshd-4261  0d.s3   45us : idle_cpu (irq_enter)
    sshd-4261  0d.s3   46us : add_preempt_count (irq_enter)
    sshd-4261  0d.H3   46us : idle_cpu (irq_enter)
    sshd-4261  0d.H3   47us : hrtimer_interrupt (smp_apic_timer_interrupt)
    sshd-4261  0d.H3   47us : ktime_get (hrtimer_interrupt)
[...]
    sshd-4261  0d.H3   81us : tick_program_event (hrtimer_interrupt)
    sshd-4261  0d.H3   82us : ktime_get (tick_program_event)
    sshd-4261  0d.H3   82us : ktime_get_ts (ktime_get)
    sshd-4261  0d.H3   83us : getnstimeofday (ktime_get_ts)
    sshd-4261  0d.H3   83us : set_normalized_timespec (ktime_get_ts)
    sshd-4261  0d.H3   84us : clockevents_program_event (tick_program_event)
    sshd-4261  0d.H3   84us : lapic_next_event (clockevents_program_event)
    sshd-4261  0d.H3   85us : irq_exit (smp_apic_timer_interrupt)
    sshd-4261  0d.H3   85us : sub_preempt_count (irq_exit)
    sshd-4261  0d.s4   86us : sub_preempt_count (irq_exit)
    sshd-4261  0d.s3   86us : add_preempt_count (__local_bh_disable)
[...]
    sshd-4261  0d.s1   98us : sub_preempt_count (net_rx_action)
    sshd-4261  0d.s.   99us : add_preempt_count (_spin_lock_irq)
    sshd-4261  0d.s1   99us+: _spin_unlock_irq (run_timer_softirq)
    sshd-4261  0d.s.  104us : _local_bh_enable (__do_softirq)
    sshd-4261  0d.s.  104us : sub_preempt_count (_local_bh_enable)
    sshd-4261  0d.s.  105us : _local_bh_enable (__do_softirq)
    sshd-4261  0d.s1  105us : trace_preempt_on (__do_softirq)


Ingo Molnar's avatar
Ingo Molnar committed
891
892
893
894
895
896
897
898
This is a very interesting trace. It started with the preemption
of the ls task. We see that the task had the "need_resched" bit
set via the 'N' in the trace.  Interrupts were disabled before
the spin_lock at the beginning of the trace. We see that a
schedule took place to run sshd.  When the interrupts were
enabled, we took an interrupt. On return from the interrupt
handler, the softirq ran. We took another interrupt while
running the softirq as we see from the capital 'H'.
Steven Rostedt's avatar
Steven Rostedt committed
899
900
901
902
903


wakeup
------

Ingo Molnar's avatar
Ingo Molnar committed
904
905
906
907
908
909
910
911
In a Real-Time environment it is very important to know the
wakeup time it takes for the highest priority task that is woken
up to the time that it executes. This is also known as "schedule
latency". I stress the point that this is about RT tasks. It is
also important to know the scheduling latency of non-RT tasks,
but the average schedule latency is better for non-RT tasks.
Tools like LatencyTop are more appropriate for such
measurements.
Steven Rostedt's avatar
Steven Rostedt committed
912

Steven Rostedt's avatar
Steven Rostedt committed
913
Real-Time environments are interested in the worst case latency.
Ingo Molnar's avatar
Ingo Molnar committed
914
915
916
917
918
919
920
921
922
923
924
925
926
That is the longest latency it takes for something to happen,
and not the average. We can have a very fast scheduler that may
only have a large latency once in a while, but that would not
work well with Real-Time tasks.  The wakeup tracer was designed
to record the worst case wakeups of RT tasks. Non-RT tasks are
not recorded because the tracer only records one worst case and
tracing non-RT tasks that are unpredictable will overwrite the
worst case latency of RT tasks.

Since this tracer only deals with RT tasks, we will run this
slightly differently than we did with the previous tracers.
Instead of performing an 'ls', we will run 'sleep 1' under
'chrt' which changes the priority of the task.
Steven Rostedt's avatar
Steven Rostedt committed
927

928
 # echo wakeup > current_tracer
929
 # echo latency-format > trace_options
930
 # echo 0 > tracing_max_latency
931
 # echo 1 > tracing_on
Steven Rostedt's avatar
Steven Rostedt committed
932
 # chrt -f 5 sleep 1
933
 # echo 0 > tracing_on
934
 # cat trace
Steven Rostedt's avatar
Steven Rostedt committed
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
# tracer: wakeup
#
wakeup latency trace v1.1.5 on 2.6.26-rc8
--------------------------------------------------------------------
 latency: 4 us, #2/2, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
    -----------------
    | task: sleep-4901 (uid:0 nice:0 policy:1 rt_prio:5)
    -----------------

#                _------=> CPU#
#               / _-----=> irqs-off
#              | / _----=> need-resched
#              || / _---=> hardirq/softirq
#              ||| / _--=> preempt-depth
#              |||| /
#              |||||     delay
#  cmd     pid ||||| time  |   caller
#     \   /    |||||   \   |   /
  <idle>-0     1d.h4    0us+: try_to_wake_up (wake_up_process)
  <idle>-0     1d..4    4us : schedule (cpu_idle)


Ingo Molnar's avatar
Ingo Molnar committed
957
958
959
960
961
Running this on an idle system, we see that it only took 4
microseconds to perform the task switch.  Note, since the trace
marker in the schedule is before the actual "switch", we stop
the tracing when the recorded task is about to schedule in. This
may change if we add a new marker at the end of the scheduler.
Steven Rostedt's avatar
Steven Rostedt committed
962

Ingo Molnar's avatar
Ingo Molnar committed
963
964
965
966
Notice that the recorded task is 'sleep' with the PID of 4901
and it has an rt_prio of 5. This priority is user-space priority
and not the internal kernel priority. The policy is 1 for
SCHED_FIFO and 2 for SCHED_RR.
Steven Rostedt's avatar
Steven Rostedt committed
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000

Doing the same with chrt -r 5 and ftrace_enabled set.

# tracer: wakeup
#
wakeup latency trace v1.1.5 on 2.6.26-rc8
--------------------------------------------------------------------
 latency: 50 us, #60/60, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
    -----------------
    | task: sleep-4068 (uid:0 nice:0 policy:2 rt_prio:5)
    -----------------

#                _------=> CPU#
#               / _-----=> irqs-off
#              | / _----=> need-resched
#              || / _---=> hardirq/softirq
#              ||| / _--=> preempt-depth
#              |||| /
#              |||||     delay
#  cmd     pid ||||| time  |   caller
#     \   /    |||||   \   |   /
ksoftirq-7     1d.H3    0us : try_to_wake_up (wake_up_process)
ksoftirq-7     1d.H4    1us : sub_preempt_count (marker_probe_cb)
ksoftirq-7     1d.H3    2us : check_preempt_wakeup (try_to_wake_up)
ksoftirq-7     1d.H3    3us : update_curr (check_preempt_wakeup)
ksoftirq-7     1d.H3    4us : calc_delta_mine (update_curr)
ksoftirq-7     1d.H3    5us : __resched_task (check_preempt_wakeup)
ksoftirq-7     1d.H3    6us : task_wake_up_rt (try_to_wake_up)
ksoftirq-7     1d.H3    7us : _spin_unlock_irqrestore (try_to_wake_up)
[...]
ksoftirq-7     1d.H2   17us : irq_exit (smp_apic_timer_interrupt)
ksoftirq-7     1d.H2   18us : sub_preempt_count (irq_exit)
ksoftirq-7     1d.s3   19us : sub_preempt_count (irq_exit)
ksoftirq-7     1..s2   20us : rcu_process_callbacks (__do_softirq)