ftrace.txt 66.7 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.
Steven Rostedt's avatar
Steven Rostedt committed
10

11
Written for: 2.6.28-rc2
Steven Rostedt's avatar
Steven Rostedt committed
12
13
14
15
16
17

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
18
19
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
20
21

Although ftrace is the function tracer, it also includes an
Ingo Molnar's avatar
Ingo Molnar committed
22
23
24
25
26
27
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
28
29
30
31
32


The File System
---------------

Ingo Molnar's avatar
Ingo Molnar committed
33
34
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
35
36
37
38
39
40

To mount the debugfs system:

  # mkdir /debug
  # mount -t debugfs nodev /debug

Ingo Molnar's avatar
Ingo Molnar committed
41
42
( Note: it is more common to mount at /sys/kernel/debug, but for
  simplicity this document will use /debug)
Steven Rostedt's avatar
Steven Rostedt committed
43
44
45
46
47
48
49
50
51
52

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  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.

  tracing_enabled:

	This sets or displays whether the current_tracer
	is activated and tracing or not. Echo 0 into this
	file to disable the tracer or 1 to enable it.

  trace:

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

  latency_trace:

	This file shows the same trace but the information
	is organized more to display possible latencies
	in the system (described below).

  trace_pipe:

	The output is the same as the "trace" file but this
	file is meant to be streamed with live tracing.
	Reads from this file will block until new data
	is retrieved. Unlike the "trace" and "latency_trace"
	files, 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" and
	"latency_trace" files are static, and if the
	tracer is not adding more data, they will display
	the same information every time they are read.

  trace_options:

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

103
  tracing_max_latency:
Ingo Molnar's avatar
Ingo Molnar committed
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170

	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
	will also be stored, and displayed by either
	"trace" or "latency_trace".  A new max trace will
	only be recorded if the latency is greater than
	the value in this file. (in microseconds)

  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
	  due to buffer managment overhead. )

	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.

  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
171
172
173
174
175


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

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

Ingo Molnar's avatar
Ingo Molnar committed
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
  "function"

	Function call tracer to trace all kernel functions.

  "function_graph_tracer"

	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.

  "sched_switch"

	Traces the context switches and wakeups between tasks.

  "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
	trace via the latency_trace file.
Steven Rostedt's avatar
Steven Rostedt committed
202

Ingo Molnar's avatar
Ingo Molnar committed
203
  "preemptoff"
204

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

Ingo Molnar's avatar
Ingo Molnar committed
208
  "preemptirqsoff"
Steven Rostedt's avatar
Steven Rostedt committed
209

Ingo Molnar's avatar
Ingo Molnar committed
210
211
212
	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
213

Ingo Molnar's avatar
Ingo Molnar committed
214
  "wakeup"
Steven Rostedt's avatar
Steven Rostedt committed
215

Ingo Molnar's avatar
Ingo Molnar committed
216
217
218
	Traces and records the max latency that it takes for
	the highest priority task to get scheduled after
	it has been woken up.
Steven Rostedt's avatar
Steven Rostedt committed
219

Ingo Molnar's avatar
Ingo Molnar committed
220
  "hw-branch-tracer"
Steven Rostedt's avatar
Steven Rostedt committed
221

Ingo Molnar's avatar
Ingo Molnar committed
222
223
224
225
226
227
228
229
	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.
230

Steven Rostedt's avatar
Steven Rostedt committed
231
232
233
234

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

Ingo Molnar's avatar
Ingo Molnar committed
235
236
237
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
238
239
240
241

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

Steven Rostedt's avatar
Steven Rostedt committed
242
Here is an example of the output format of the file "trace"
Steven Rostedt's avatar
Steven Rostedt committed
243
244

                             --------
Steven Rostedt's avatar
Steven Rostedt committed
245
# tracer: function
Steven Rostedt's avatar
Steven Rostedt committed
246
247
248
249
250
251
252
253
#
#           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
254
255
256
257
258
259
260
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
261

Ingo Molnar's avatar
Ingo Molnar committed
262
263
The sched_switch tracer also includes tracing of task wakeups
and context switches.
Steven Rostedt's avatar
Steven Rostedt committed
264
265
266
267
268
269
270
271

     ksoftirqd/1-7     [01]  1453.070013:      7:115:R   +  2916:115:S
     ksoftirqd/1-7     [01]  1453.070013:      7:115:R   +    10:115:S
     ksoftirqd/1-7     [01]  1453.070013:      7:115:R ==>    10:115:R
        events/1-10    [01]  1453.070013:     10:115:S ==>  2916:115:R
     kondemand/1-2916  [01]  1453.070013:   2916:115:S ==>     7:115:R
     ksoftirqd/1-7     [01]  1453.070013:      7:115:S ==>     0:140:R

Ingo Molnar's avatar
Ingo Molnar committed
272
273
Wake ups are represented by a "+" and the context switches are
shown as "==>".  The format is:
Steven Rostedt's avatar
Steven Rostedt committed
274
275
276
277
278
279
280
281
282
283
284
285
286

 Context switches:

       Previous task              Next Task

  <pid>:<prio>:<state>  ==>  <pid>:<prio>:<state>

 Wake ups:

       Current task               Task waking up

  <pid>:<prio>:<state>    +  <pid>:<prio>:<state>

Ingo Molnar's avatar
Ingo Molnar committed
287
288
289
290
291
292
The prio is the internal kernel priority, which is the inverse
of the priority that is usually displayed by user-space tools.
Zero represents the highest priority (99). Prio 100 starts the
"nice" priorities with 100 being equal to nice -20 and 139 being
nice 19. The prio "140" is reserved for the idle task which is
the lowest priority thread (pid 0).
Steven Rostedt's avatar
Steven Rostedt committed
293
294
295
296
297


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

Ingo Molnar's avatar
Ingo Molnar committed
298
299
300
For traces that display latency times, the latency_trace file
gives somewhat more information to see why a latency happened.
Here is a typical trace.
Steven Rostedt's avatar
Steven Rostedt committed
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326

# 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
327
328
329
330
331
332
333
334
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
335

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

Ingo Molnar's avatar
Ingo Molnar committed
339
340
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
341
342
343
344
345
346
347
348
349
350
351

  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
352
  CPU#: The CPU which the process was running on.
Steven Rostedt's avatar
Steven Rostedt committed
353
354

  irqs-off: 'd' interrupts are disabled. '.' otherwise.
355
356
357
	    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
358
359
360
361

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

  hardirq/softirq:
Steven Rostedt's avatar
Steven Rostedt committed
362
	'H' - hard irq occurred inside a softirq.
Steven Rostedt's avatar
Steven Rostedt committed
363
364
365
366
367
368
369
370
	'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.

Steven Rostedt's avatar
Steven Rostedt committed
371
  time: This differs from the trace file output. The trace file output
Steven Rostedt's avatar
Steven Rostedt committed
372
	includes an absolute timestamp. The timestamp used by the
Steven Rostedt's avatar
Steven Rostedt committed
373
	latency_trace file is relative to the start of the trace.
Steven Rostedt's avatar
Steven Rostedt committed
374
375

  delay: This is just to help catch your eye a bit better. And
Ingo Molnar's avatar
Ingo Molnar committed
376
377
378
379
380
381
	 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
382
383
384
385

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


386
387
trace_options
-------------
Steven Rostedt's avatar
Steven Rostedt committed
388

Ingo Molnar's avatar
Ingo Molnar committed
389
390
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
391

392
  cat /debug/tracing/trace_options
Steven Rostedt's avatar
Steven Rostedt committed
393
  print-parent nosym-offset nosym-addr noverbose noraw nohex nobin \
Ingo Molnar's avatar
Ingo Molnar committed
394
  noblock nostacktrace nosched-tree nouserstacktrace nosym-userobj
Steven Rostedt's avatar
Steven Rostedt committed
395

Ingo Molnar's avatar
Ingo Molnar committed
396
397
To disable one of the options, echo in the option prepended with
"no".
Steven Rostedt's avatar
Steven Rostedt committed
398

399
  echo noprint-parent > /debug/tracing/trace_options
Steven Rostedt's avatar
Steven Rostedt committed
400
401
402

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

403
  echo sym-offset > /debug/tracing/trace_options
Steven Rostedt's avatar
Steven Rostedt committed
404
405
406

Here are the available options:

Ingo Molnar's avatar
Ingo Molnar committed
407
408
  print-parent - On function traces, display the calling (parent)
		 function as well as the function being traced.
Steven Rostedt's avatar
Steven Rostedt committed
409
410
411
412
413
414
415
416

  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
417
418
419
420
  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
421
422
423
424

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

Ingo Molnar's avatar
Ingo Molnar committed
425
426
  sym-addr - this will also display the function address as well
	     as the function name.
Steven Rostedt's avatar
Steven Rostedt committed
427
428
429
430
431
432
433
434
435

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

  verbose - This deals with the latency_trace file.

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

Ingo Molnar's avatar
Ingo Molnar committed
436
437
438
  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
439

Ingo Molnar's avatar
Ingo Molnar committed
440
441
  hex - Similar to raw, but the numbers will be in a hexadecimal
	format.
Steven Rostedt's avatar
Steven Rostedt committed
442
443
444
445
446

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

  block - TBD (needs update)

Ingo Molnar's avatar
Ingo Molnar committed
447
448
449
450
  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
451

Ingo Molnar's avatar
Ingo Molnar committed
452
453
  userstacktrace - This option changes the trace. It records a
		   stacktrace of the current userspace thread.
454

Ingo Molnar's avatar
Ingo Molnar committed
455
456
457
458
459
460
  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
461

Ingo Molnar's avatar
Ingo Molnar committed
462
463
		The lookup is performed when you read
		trace,trace_pipe,latency_trace. Example:
464
465
466
467

		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
468
469
470
  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
471
472
473
474
475


sched_switch
------------

Steven Rostedt's avatar
Steven Rostedt committed
476
This tracer simply records schedule switches. Here is an example
Steven Rostedt's avatar
Steven Rostedt committed
477
of how to use it.
Steven Rostedt's avatar
Steven Rostedt committed
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506

 # echo sched_switch > /debug/tracing/current_tracer
 # echo 1 > /debug/tracing/tracing_enabled
 # sleep 1
 # echo 0 > /debug/tracing/tracing_enabled
 # cat /debug/tracing/trace

# tracer: sched_switch
#
#           TASK-PID   CPU#    TIMESTAMP  FUNCTION
#              | |      |          |         |
            bash-3997  [01]   240.132281:   3997:120:R   +  4055:120:R
            bash-3997  [01]   240.132284:   3997:120:R ==>  4055:120:R
           sleep-4055  [01]   240.132371:   4055:120:S ==>  3997:120:R
            bash-3997  [01]   240.132454:   3997:120:R   +  4055:120:S
            bash-3997  [01]   240.132457:   3997:120:R ==>  4055:120:R
           sleep-4055  [01]   240.132460:   4055:120:D ==>  3997:120:R
            bash-3997  [01]   240.132463:   3997:120:R   +  4055:120:D
            bash-3997  [01]   240.132465:   3997:120:R ==>  4055:120:R
          <idle>-0     [00]   240.132589:      0:140:R   +     4:115:S
          <idle>-0     [00]   240.132591:      0:140:R ==>     4:115:R
     ksoftirqd/0-4     [00]   240.132595:      4:115:S ==>     0:140:R
          <idle>-0     [00]   240.132598:      0:140:R   +     4:115:S
          <idle>-0     [00]   240.132599:      0:140:R ==>     4:115:R
     ksoftirqd/0-4     [00]   240.132603:      4:115:S ==>     0:140:R
           sleep-4055  [01]   240.133058:   4055:120:S ==>  3997:120:R
 [...]


Ingo Molnar's avatar
Ingo Molnar committed
507
508
509
510
As we have discussed previously about this format, the header
shows the name of the trace and points to the options. The
"FUNCTION" is a misnomer since here it represents the wake ups
and context switches.
Steven Rostedt's avatar
Steven Rostedt committed
511

Ingo Molnar's avatar
Ingo Molnar committed
512
513
514
515
516
517
518
519
The sched_switch file only lists the wake ups (represented with
'+') and context switches ('==>') with the previous task or
current task first followed by the next task or task waking up.
The format for both of these is PID:KERNEL-PRIO:TASK-STATE.
Remember that the KERNEL-PRIO is the inverse of the actual
priority with zero (0) being the highest priority and the nice
values starting at 100 (nice -20). Below is a quick chart to map
the kernel priority to user land priorities.
Steven Rostedt's avatar
Steven Rostedt committed
520
521
522
523
524
525
526
527
528

  Kernel priority: 0 to 99    ==> user RT priority 99 to 0
  Kernel priority: 100 to 139 ==> user nice -20 to 19
  Kernel priority: 140        ==> idle task priority

The task states are:

 R - running : wants to run, may not actually be running
 S - sleep   : process is waiting to be woken up (handles signals)
Steven Rostedt's avatar
Steven Rostedt committed
529
530
 D - disk sleep (uninterruptible sleep) : process must be woken up
					(ignores signals)
Steven Rostedt's avatar
Steven Rostedt committed
531
532
533
534
535
536
537
538
539
 T - stopped : process suspended
 t - traced  : process is being traced (with something like gdb)
 Z - zombie  : process waiting to be cleaned up
 X - unknown


ftrace_enabled
--------------

Ingo Molnar's avatar
Ingo Molnar committed
540
541
542
543
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
544
545
546
547
548
549
550

  sysctl kernel.ftrace_enabled=1

 or

  echo 1 > /proc/sys/kernel/ftrace_enabled

Ingo Molnar's avatar
Ingo Molnar committed
551
552
To disable ftrace_enabled simply replace the '1' with '0' in the
above commands.
Steven Rostedt's avatar
Steven Rostedt committed
553

Ingo Molnar's avatar
Ingo Molnar committed
554
555
556
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
557
558
559
560
561
562
563


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
564
565
566
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
567

Ingo Molnar's avatar
Ingo Molnar committed
568
569
570
571
572
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
573

Ingo Molnar's avatar
Ingo Molnar committed
574
575
To reset the maximum, echo 0 into tracing_max_latency. Here is
an example:
Steven Rostedt's avatar
Steven Rostedt committed
576
577
578
579
580
581
582
583
584
585

 # echo irqsoff > /debug/tracing/current_tracer
 # echo 0 > /debug/tracing/tracing_max_latency
 # echo 1 > /debug/tracing/tracing_enabled
 # ls -ltr
 [...]
 # echo 0 > /debug/tracing/tracing_enabled
 # cat /debug/tracing/latency_trace
# tracer: irqsoff
#
Steven Rostedt's avatar
Steven Rostedt committed
586
irqsoff latency trace v1.1.5 on 2.6.26
Steven Rostedt's avatar
Steven Rostedt committed
587
--------------------------------------------------------------------
Steven Rostedt's avatar
Steven Rostedt committed
588
 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
589
    -----------------
Steven Rostedt's avatar
Steven Rostedt committed
590
    | task: bash-3730 (uid:0 nice:0 policy:0 rt_prio:0)
Steven Rostedt's avatar
Steven Rostedt committed
591
    -----------------
Steven Rostedt's avatar
Steven Rostedt committed
592
593
 => started at: sys_setpgid
 => ended at:   sys_setpgid
Steven Rostedt's avatar
Steven Rostedt committed
594
595
596
597
598
599
600
601
602
603

#                _------=> CPU#
#               / _-----=> irqs-off
#              | / _----=> need-resched
#              || / _---=> hardirq/softirq
#              ||| / _--=> preempt-depth
#              |||| /
#              |||||     delay
#  cmd     pid ||||| time  |   caller
#     \   /    |||||   \   |   /
Steven Rostedt's avatar
Steven Rostedt committed
604
605
606
    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
607
608


Steven Rostedt's avatar
Steven Rostedt committed
609
Here we see that that we had a latency of 12 microsecs (which is
Ingo Molnar's avatar
Ingo Molnar committed
610
611
612
613
614
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
615

Steven Rostedt's avatar
Steven Rostedt committed
616
617
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
618
619
620
621
622
623
624
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
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664

# 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
665
666
667
668
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
669
670
671
672
673


preemptoff
----------

Ingo Molnar's avatar
Ingo Molnar committed
674
675
676
677
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
678

Steven Rostedt's avatar
Steven Rostedt committed
679
The preemptoff tracer traces the places that disable preemption.
Ingo Molnar's avatar
Ingo Molnar committed
680
681
682
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
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
714
715

 # echo preemptoff > /debug/tracing/current_tracer
 # echo 0 > /debug/tracing/tracing_max_latency
 # echo 1 > /debug/tracing/tracing_enabled
 # ls -ltr
 [...]
 # echo 0 > /debug/tracing/tracing_enabled
 # cat /debug/tracing/latency_trace
# 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
716
717
718
719
720
721
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
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779

# 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
780
781
782
783
784
785
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
786

Ingo Molnar's avatar
Ingo Molnar committed
787
788
789
790
791
792
793
794
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
795
796
797
798
799


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

Ingo Molnar's avatar
Ingo Molnar committed
800
801
802
803
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
804

Steven Rostedt's avatar
Steven Rostedt committed
805
Consider the following code:
Steven Rostedt's avatar
Steven Rostedt committed
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822

    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
823
824
825
826
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
827

Ingo Molnar's avatar
Ingo Molnar committed
828
829
Again, using this trace is much like the irqsoff and preemptoff
tracers.
Steven Rostedt's avatar
Steven Rostedt committed
830

Steven Rostedt's avatar
Steven Rostedt committed
831
 # echo preemptirqsoff > /debug/tracing/current_tracer
Steven Rostedt's avatar
Steven Rostedt committed
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
 # echo 0 > /debug/tracing/tracing_max_latency
 # echo 1 > /debug/tracing/tracing_enabled
 # ls -ltr
 [...]
 # echo 0 > /debug/tracing/tracing_enabled
 # cat /debug/tracing/latency_trace
# 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
865
866
867
868
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
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955

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
956
957
958
959
960
961
962
963
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
964
965
966
967
968


wakeup
------

Ingo Molnar's avatar
Ingo Molnar committed
969
970
971
972
973
974
975
976
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
977

Steven Rostedt's avatar
Steven Rostedt committed
978
Real-Time environments are interested in the worst case latency.
Ingo Molnar's avatar
Ingo Molnar committed
979
980
981
982
983
984
985
986
987
988
989
990
991
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
992
993
994
995
996
997
998
999
1000

 # echo wakeup > /debug/tracing/current_tracer
 # echo 0 > /debug/tracing/tracing_max_latency
 # echo 1 > /debug/tracing/tracing_enabled
 # chrt -f 5 sleep 1
 # echo 0 > /debug/tracing/tracing_enabled
 # cat /debug/tracing/latency_trace
# tracer: wakeup
#
For faster browsing, not all history is shown. View entire blame