xref: /OK3568_Linux_fs/kernel/Documentation/trace/ftrace-design.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun======================
2*4882a593SmuzhiyunFunction Tracer Design
3*4882a593Smuzhiyun======================
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun:Author: Mike Frysinger
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun.. caution::
8*4882a593Smuzhiyun	This document is out of date. Some of the description below doesn't
9*4882a593Smuzhiyun	match current implementation now.
10*4882a593Smuzhiyun
11*4882a593SmuzhiyunIntroduction
12*4882a593Smuzhiyun------------
13*4882a593Smuzhiyun
14*4882a593SmuzhiyunHere we will cover the architecture pieces that the common function tracing
15*4882a593Smuzhiyuncode relies on for proper functioning.  Things are broken down into increasing
16*4882a593Smuzhiyuncomplexity so that you can start simple and at least get basic functionality.
17*4882a593Smuzhiyun
18*4882a593SmuzhiyunNote that this focuses on architecture implementation details only.  If you
19*4882a593Smuzhiyunwant more explanation of a feature in terms of common code, review the common
20*4882a593Smuzhiyunftrace.txt file.
21*4882a593Smuzhiyun
22*4882a593SmuzhiyunIdeally, everyone who wishes to retain performance while supporting tracing in
23*4882a593Smuzhiyuntheir kernel should make it all the way to dynamic ftrace support.
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun
26*4882a593SmuzhiyunPrerequisites
27*4882a593Smuzhiyun-------------
28*4882a593Smuzhiyun
29*4882a593SmuzhiyunFtrace relies on these features being implemented:
30*4882a593Smuzhiyun  - STACKTRACE_SUPPORT - implement save_stack_trace()
31*4882a593Smuzhiyun  - TRACE_IRQFLAGS_SUPPORT - implement include/asm/irqflags.h
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun
34*4882a593SmuzhiyunHAVE_FUNCTION_TRACER
35*4882a593Smuzhiyun--------------------
36*4882a593Smuzhiyun
37*4882a593SmuzhiyunYou will need to implement the mcount and the ftrace_stub functions.
38*4882a593Smuzhiyun
39*4882a593SmuzhiyunThe exact mcount symbol name will depend on your toolchain.  Some call it
40*4882a593Smuzhiyun"mcount", "_mcount", or even "__mcount".  You can probably figure it out by
41*4882a593Smuzhiyunrunning something like::
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun	$ echo 'main(){}' | gcc -x c -S -o - - -pg | grep mcount
44*4882a593Smuzhiyun	        call    mcount
45*4882a593Smuzhiyun
46*4882a593SmuzhiyunWe'll make the assumption below that the symbol is "mcount" just to keep things
47*4882a593Smuzhiyunnice and simple in the examples.
48*4882a593Smuzhiyun
49*4882a593SmuzhiyunKeep in mind that the ABI that is in effect inside of the mcount function is
50*4882a593Smuzhiyun*highly* architecture/toolchain specific.  We cannot help you in this regard,
51*4882a593Smuzhiyunsorry.  Dig up some old documentation and/or find someone more familiar than
52*4882a593Smuzhiyunyou to bang ideas off of.  Typically, register usage (argument/scratch/etc...)
53*4882a593Smuzhiyunis a major issue at this point, especially in relation to the location of the
54*4882a593Smuzhiyunmcount call (before/after function prologue).  You might also want to look at
55*4882a593Smuzhiyunhow glibc has implemented the mcount function for your architecture.  It might
56*4882a593Smuzhiyunbe (semi-)relevant.
57*4882a593Smuzhiyun
58*4882a593SmuzhiyunThe mcount function should check the function pointer ftrace_trace_function
59*4882a593Smuzhiyunto see if it is set to ftrace_stub.  If it is, there is nothing for you to do,
60*4882a593Smuzhiyunso return immediately.  If it isn't, then call that function in the same way
61*4882a593Smuzhiyunthe mcount function normally calls __mcount_internal -- the first argument is
62*4882a593Smuzhiyunthe "frompc" while the second argument is the "selfpc" (adjusted to remove the
63*4882a593Smuzhiyunsize of the mcount call that is embedded in the function).
64*4882a593Smuzhiyun
65*4882a593SmuzhiyunFor example, if the function foo() calls bar(), when the bar() function calls
66*4882a593Smuzhiyunmcount(), the arguments mcount() will pass to the tracer are:
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun  - "frompc" - the address bar() will use to return to foo()
69*4882a593Smuzhiyun  - "selfpc" - the address bar() (with mcount() size adjustment)
70*4882a593Smuzhiyun
71*4882a593SmuzhiyunAlso keep in mind that this mcount function will be called *a lot*, so
72*4882a593Smuzhiyunoptimizing for the default case of no tracer will help the smooth running of
73*4882a593Smuzhiyunyour system when tracing is disabled.  So the start of the mcount function is
74*4882a593Smuzhiyuntypically the bare minimum with checking things before returning.  That also
75*4882a593Smuzhiyunmeans the code flow should usually be kept linear (i.e. no branching in the nop
76*4882a593Smuzhiyuncase).  This is of course an optimization and not a hard requirement.
77*4882a593Smuzhiyun
78*4882a593SmuzhiyunHere is some pseudo code that should help (these functions should actually be
79*4882a593Smuzhiyunimplemented in assembly)::
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun	void ftrace_stub(void)
82*4882a593Smuzhiyun	{
83*4882a593Smuzhiyun		return;
84*4882a593Smuzhiyun	}
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun	void mcount(void)
87*4882a593Smuzhiyun	{
88*4882a593Smuzhiyun		/* save any bare state needed in order to do initial checking */
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun		extern void (*ftrace_trace_function)(unsigned long, unsigned long);
91*4882a593Smuzhiyun		if (ftrace_trace_function != ftrace_stub)
92*4882a593Smuzhiyun			goto do_trace;
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun		/* restore any bare state */
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun		return;
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun	do_trace:
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun		/* save all state needed by the ABI (see paragraph above) */
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun		unsigned long frompc = ...;
103*4882a593Smuzhiyun		unsigned long selfpc = <return address> - MCOUNT_INSN_SIZE;
104*4882a593Smuzhiyun		ftrace_trace_function(frompc, selfpc);
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun		/* restore all state needed by the ABI */
107*4882a593Smuzhiyun	}
108*4882a593Smuzhiyun
109*4882a593SmuzhiyunDon't forget to export mcount for modules !
110*4882a593Smuzhiyun::
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun	extern void mcount(void);
113*4882a593Smuzhiyun	EXPORT_SYMBOL(mcount);
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun
116*4882a593SmuzhiyunHAVE_FUNCTION_GRAPH_TRACER
117*4882a593Smuzhiyun--------------------------
118*4882a593Smuzhiyun
119*4882a593SmuzhiyunDeep breath ... time to do some real work.  Here you will need to update the
120*4882a593Smuzhiyunmcount function to check ftrace graph function pointers, as well as implement
121*4882a593Smuzhiyunsome functions to save (hijack) and restore the return address.
122*4882a593Smuzhiyun
123*4882a593SmuzhiyunThe mcount function should check the function pointers ftrace_graph_return
124*4882a593Smuzhiyun(compare to ftrace_stub) and ftrace_graph_entry (compare to
125*4882a593Smuzhiyunftrace_graph_entry_stub).  If either of those is not set to the relevant stub
126*4882a593Smuzhiyunfunction, call the arch-specific function ftrace_graph_caller which in turn
127*4882a593Smuzhiyuncalls the arch-specific function prepare_ftrace_return.  Neither of these
128*4882a593Smuzhiyunfunction names is strictly required, but you should use them anyway to stay
129*4882a593Smuzhiyunconsistent across the architecture ports -- easier to compare & contrast
130*4882a593Smuzhiyunthings.
131*4882a593Smuzhiyun
132*4882a593SmuzhiyunThe arguments to prepare_ftrace_return are slightly different than what are
133*4882a593Smuzhiyunpassed to ftrace_trace_function.  The second argument "selfpc" is the same,
134*4882a593Smuzhiyunbut the first argument should be a pointer to the "frompc".  Typically this is
135*4882a593Smuzhiyunlocated on the stack.  This allows the function to hijack the return address
136*4882a593Smuzhiyuntemporarily to have it point to the arch-specific function return_to_handler.
137*4882a593SmuzhiyunThat function will simply call the common ftrace_return_to_handler function and
138*4882a593Smuzhiyunthat will return the original return address with which you can return to the
139*4882a593Smuzhiyunoriginal call site.
140*4882a593Smuzhiyun
141*4882a593SmuzhiyunHere is the updated mcount pseudo code::
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun	void mcount(void)
144*4882a593Smuzhiyun	{
145*4882a593Smuzhiyun	...
146*4882a593Smuzhiyun		if (ftrace_trace_function != ftrace_stub)
147*4882a593Smuzhiyun			goto do_trace;
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun	+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
150*4882a593Smuzhiyun	+	extern void (*ftrace_graph_return)(...);
151*4882a593Smuzhiyun	+	extern void (*ftrace_graph_entry)(...);
152*4882a593Smuzhiyun	+	if (ftrace_graph_return != ftrace_stub ||
153*4882a593Smuzhiyun	+	    ftrace_graph_entry != ftrace_graph_entry_stub)
154*4882a593Smuzhiyun	+		ftrace_graph_caller();
155*4882a593Smuzhiyun	+#endif
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun		/* restore any bare state */
158*4882a593Smuzhiyun	...
159*4882a593Smuzhiyun
160*4882a593SmuzhiyunHere is the pseudo code for the new ftrace_graph_caller assembly function::
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun	#ifdef CONFIG_FUNCTION_GRAPH_TRACER
163*4882a593Smuzhiyun	void ftrace_graph_caller(void)
164*4882a593Smuzhiyun	{
165*4882a593Smuzhiyun		/* save all state needed by the ABI */
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun		unsigned long *frompc = &...;
168*4882a593Smuzhiyun		unsigned long selfpc = <return address> - MCOUNT_INSN_SIZE;
169*4882a593Smuzhiyun		/* passing frame pointer up is optional -- see below */
170*4882a593Smuzhiyun		prepare_ftrace_return(frompc, selfpc, frame_pointer);
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun		/* restore all state needed by the ABI */
173*4882a593Smuzhiyun	}
174*4882a593Smuzhiyun	#endif
175*4882a593Smuzhiyun
176*4882a593SmuzhiyunFor information on how to implement prepare_ftrace_return(), simply look at the
177*4882a593Smuzhiyunx86 version (the frame pointer passing is optional; see the next section for
178*4882a593Smuzhiyunmore information).  The only architecture-specific piece in it is the setup of
179*4882a593Smuzhiyunthe fault recovery table (the asm(...) code).  The rest should be the same
180*4882a593Smuzhiyunacross architectures.
181*4882a593Smuzhiyun
182*4882a593SmuzhiyunHere is the pseudo code for the new return_to_handler assembly function.  Note
183*4882a593Smuzhiyunthat the ABI that applies here is different from what applies to the mcount
184*4882a593Smuzhiyuncode.  Since you are returning from a function (after the epilogue), you might
185*4882a593Smuzhiyunbe able to skimp on things saved/restored (usually just registers used to pass
186*4882a593Smuzhiyunreturn values).
187*4882a593Smuzhiyun::
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun	#ifdef CONFIG_FUNCTION_GRAPH_TRACER
190*4882a593Smuzhiyun	void return_to_handler(void)
191*4882a593Smuzhiyun	{
192*4882a593Smuzhiyun		/* save all state needed by the ABI (see paragraph above) */
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun		void (*original_return_point)(void) = ftrace_return_to_handler();
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun		/* restore all state needed by the ABI */
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun		/* this is usually either a return or a jump */
199*4882a593Smuzhiyun		original_return_point();
200*4882a593Smuzhiyun	}
201*4882a593Smuzhiyun	#endif
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun
204*4882a593SmuzhiyunHAVE_FUNCTION_GRAPH_FP_TEST
205*4882a593Smuzhiyun---------------------------
206*4882a593Smuzhiyun
207*4882a593SmuzhiyunAn arch may pass in a unique value (frame pointer) to both the entering and
208*4882a593Smuzhiyunexiting of a function.  On exit, the value is compared and if it does not
209*4882a593Smuzhiyunmatch, then it will panic the kernel.  This is largely a sanity check for bad
210*4882a593Smuzhiyuncode generation with gcc.  If gcc for your port sanely updates the frame
211*4882a593Smuzhiyunpointer under different optimization levels, then ignore this option.
212*4882a593Smuzhiyun
213*4882a593SmuzhiyunHowever, adding support for it isn't terribly difficult.  In your assembly code
214*4882a593Smuzhiyunthat calls prepare_ftrace_return(), pass the frame pointer as the 3rd argument.
215*4882a593SmuzhiyunThen in the C version of that function, do what the x86 port does and pass it
216*4882a593Smuzhiyunalong to ftrace_push_return_trace() instead of a stub value of 0.
217*4882a593Smuzhiyun
218*4882a593SmuzhiyunSimilarly, when you call ftrace_return_to_handler(), pass it the frame pointer.
219*4882a593Smuzhiyun
220*4882a593SmuzhiyunHAVE_FUNCTION_GRAPH_RET_ADDR_PTR
221*4882a593Smuzhiyun--------------------------------
222*4882a593Smuzhiyun
223*4882a593SmuzhiyunAn arch may pass in a pointer to the return address on the stack.  This
224*4882a593Smuzhiyunprevents potential stack unwinding issues where the unwinder gets out of
225*4882a593Smuzhiyunsync with ret_stack and the wrong addresses are reported by
226*4882a593Smuzhiyunftrace_graph_ret_addr().
227*4882a593Smuzhiyun
228*4882a593SmuzhiyunAdding support for it is easy: just define the macro in asm/ftrace.h and
229*4882a593Smuzhiyunpass the return address pointer as the 'retp' argument to
230*4882a593Smuzhiyunftrace_push_return_trace().
231*4882a593Smuzhiyun
232*4882a593SmuzhiyunHAVE_SYSCALL_TRACEPOINTS
233*4882a593Smuzhiyun------------------------
234*4882a593Smuzhiyun
235*4882a593SmuzhiyunYou need very few things to get the syscalls tracing in an arch.
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun  - Support HAVE_ARCH_TRACEHOOK (see arch/Kconfig).
238*4882a593Smuzhiyun  - Have a NR_syscalls variable in <asm/unistd.h> that provides the number
239*4882a593Smuzhiyun    of syscalls supported by the arch.
240*4882a593Smuzhiyun  - Support the TIF_SYSCALL_TRACEPOINT thread flags.
241*4882a593Smuzhiyun  - Put the trace_sys_enter() and trace_sys_exit() tracepoints calls from ptrace
242*4882a593Smuzhiyun    in the ptrace syscalls tracing path.
243*4882a593Smuzhiyun  - If the system call table on this arch is more complicated than a simple array
244*4882a593Smuzhiyun    of addresses of the system calls, implement an arch_syscall_addr to return
245*4882a593Smuzhiyun    the address of a given system call.
246*4882a593Smuzhiyun  - If the symbol names of the system calls do not match the function names on
247*4882a593Smuzhiyun    this arch, define ARCH_HAS_SYSCALL_MATCH_SYM_NAME in asm/ftrace.h and
248*4882a593Smuzhiyun    implement arch_syscall_match_sym_name with the appropriate logic to return
249*4882a593Smuzhiyun    true if the function name corresponds with the symbol name.
250*4882a593Smuzhiyun  - Tag this arch as HAVE_SYSCALL_TRACEPOINTS.
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun
253*4882a593SmuzhiyunHAVE_FTRACE_MCOUNT_RECORD
254*4882a593Smuzhiyun-------------------------
255*4882a593Smuzhiyun
256*4882a593SmuzhiyunSee scripts/recordmcount.pl for more info.  Just fill in the arch-specific
257*4882a593Smuzhiyundetails for how to locate the addresses of mcount call sites via objdump.
258*4882a593SmuzhiyunThis option doesn't make much sense without also implementing dynamic ftrace.
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun
261*4882a593SmuzhiyunHAVE_DYNAMIC_FTRACE
262*4882a593Smuzhiyun-------------------
263*4882a593Smuzhiyun
264*4882a593SmuzhiyunYou will first need HAVE_FTRACE_MCOUNT_RECORD and HAVE_FUNCTION_TRACER, so
265*4882a593Smuzhiyunscroll your reader back up if you got over eager.
266*4882a593Smuzhiyun
267*4882a593SmuzhiyunOnce those are out of the way, you will need to implement:
268*4882a593Smuzhiyun	- asm/ftrace.h:
269*4882a593Smuzhiyun		- MCOUNT_ADDR
270*4882a593Smuzhiyun		- ftrace_call_adjust()
271*4882a593Smuzhiyun		- struct dyn_arch_ftrace{}
272*4882a593Smuzhiyun	- asm code:
273*4882a593Smuzhiyun		- mcount() (new stub)
274*4882a593Smuzhiyun		- ftrace_caller()
275*4882a593Smuzhiyun		- ftrace_call()
276*4882a593Smuzhiyun		- ftrace_stub()
277*4882a593Smuzhiyun	- C code:
278*4882a593Smuzhiyun		- ftrace_dyn_arch_init()
279*4882a593Smuzhiyun		- ftrace_make_nop()
280*4882a593Smuzhiyun		- ftrace_make_call()
281*4882a593Smuzhiyun		- ftrace_update_ftrace_func()
282*4882a593Smuzhiyun
283*4882a593SmuzhiyunFirst you will need to fill out some arch details in your asm/ftrace.h.
284*4882a593Smuzhiyun
285*4882a593SmuzhiyunDefine MCOUNT_ADDR as the address of your mcount symbol similar to::
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun	#define MCOUNT_ADDR ((unsigned long)mcount)
288*4882a593Smuzhiyun
289*4882a593SmuzhiyunSince no one else will have a decl for that function, you will need to::
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun	extern void mcount(void);
292*4882a593Smuzhiyun
293*4882a593SmuzhiyunYou will also need the helper function ftrace_call_adjust().  Most people
294*4882a593Smuzhiyunwill be able to stub it out like so::
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun	static inline unsigned long ftrace_call_adjust(unsigned long addr)
297*4882a593Smuzhiyun	{
298*4882a593Smuzhiyun		return addr;
299*4882a593Smuzhiyun	}
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun<details to be filled>
302*4882a593Smuzhiyun
303*4882a593SmuzhiyunLastly you will need the custom dyn_arch_ftrace structure.  If you need
304*4882a593Smuzhiyunsome extra state when runtime patching arbitrary call sites, this is the
305*4882a593Smuzhiyunplace.  For now though, create an empty struct::
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun	struct dyn_arch_ftrace {
308*4882a593Smuzhiyun		/* No extra data needed */
309*4882a593Smuzhiyun	};
310*4882a593Smuzhiyun
311*4882a593SmuzhiyunWith the header out of the way, we can fill out the assembly code.  While we
312*4882a593Smuzhiyundid already create a mcount() function earlier, dynamic ftrace only wants a
313*4882a593Smuzhiyunstub function.  This is because the mcount() will only be used during boot
314*4882a593Smuzhiyunand then all references to it will be patched out never to return.  Instead,
315*4882a593Smuzhiyunthe guts of the old mcount() will be used to create a new ftrace_caller()
316*4882a593Smuzhiyunfunction.  Because the two are hard to merge, it will most likely be a lot
317*4882a593Smuzhiyuneasier to have two separate definitions split up by #ifdefs.  Same goes for
318*4882a593Smuzhiyunthe ftrace_stub() as that will now be inlined in ftrace_caller().
319*4882a593Smuzhiyun
320*4882a593SmuzhiyunBefore we get confused anymore, let's check out some pseudo code so you can
321*4882a593Smuzhiyunimplement your own stuff in assembly::
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun	void mcount(void)
324*4882a593Smuzhiyun	{
325*4882a593Smuzhiyun		return;
326*4882a593Smuzhiyun	}
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun	void ftrace_caller(void)
329*4882a593Smuzhiyun	{
330*4882a593Smuzhiyun		/* save all state needed by the ABI (see paragraph above) */
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun		unsigned long frompc = ...;
333*4882a593Smuzhiyun		unsigned long selfpc = <return address> - MCOUNT_INSN_SIZE;
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun	ftrace_call:
336*4882a593Smuzhiyun		ftrace_stub(frompc, selfpc);
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun		/* restore all state needed by the ABI */
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun	ftrace_stub:
341*4882a593Smuzhiyun		return;
342*4882a593Smuzhiyun	}
343*4882a593Smuzhiyun
344*4882a593SmuzhiyunThis might look a little odd at first, but keep in mind that we will be runtime
345*4882a593Smuzhiyunpatching multiple things.  First, only functions that we actually want to trace
346*4882a593Smuzhiyunwill be patched to call ftrace_caller().  Second, since we only have one tracer
347*4882a593Smuzhiyunactive at a time, we will patch the ftrace_caller() function itself to call the
348*4882a593Smuzhiyunspecific tracer in question.  That is the point of the ftrace_call label.
349*4882a593Smuzhiyun
350*4882a593SmuzhiyunWith that in mind, let's move on to the C code that will actually be doing the
351*4882a593Smuzhiyunruntime patching.  You'll need a little knowledge of your arch's opcodes in
352*4882a593Smuzhiyunorder to make it through the next section.
353*4882a593Smuzhiyun
354*4882a593SmuzhiyunEvery arch has an init callback function.  If you need to do something early on
355*4882a593Smuzhiyunto initialize some state, this is the time to do that.  Otherwise, this simple
356*4882a593Smuzhiyunfunction below should be sufficient for most people::
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun	int __init ftrace_dyn_arch_init(void)
359*4882a593Smuzhiyun	{
360*4882a593Smuzhiyun		return 0;
361*4882a593Smuzhiyun	}
362*4882a593Smuzhiyun
363*4882a593SmuzhiyunThere are two functions that are used to do runtime patching of arbitrary
364*4882a593Smuzhiyunfunctions.  The first is used to turn the mcount call site into a nop (which
365*4882a593Smuzhiyunis what helps us retain runtime performance when not tracing).  The second is
366*4882a593Smuzhiyunused to turn the mcount call site into a call to an arbitrary location (but
367*4882a593Smuzhiyuntypically that is ftracer_caller()).  See the general function definition in
368*4882a593Smuzhiyunlinux/ftrace.h for the functions::
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun	ftrace_make_nop()
371*4882a593Smuzhiyun	ftrace_make_call()
372*4882a593Smuzhiyun
373*4882a593SmuzhiyunThe rec->ip value is the address of the mcount call site that was collected
374*4882a593Smuzhiyunby the scripts/recordmcount.pl during build time.
375*4882a593Smuzhiyun
376*4882a593SmuzhiyunThe last function is used to do runtime patching of the active tracer.  This
377*4882a593Smuzhiyunwill be modifying the assembly code at the location of the ftrace_call symbol
378*4882a593Smuzhiyuninside of the ftrace_caller() function.  So you should have sufficient padding
379*4882a593Smuzhiyunat that location to support the new function calls you'll be inserting.  Some
380*4882a593Smuzhiyunpeople will be using a "call" type instruction while others will be using a
381*4882a593Smuzhiyun"branch" type instruction.  Specifically, the function is::
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun	ftrace_update_ftrace_func()
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun
386*4882a593SmuzhiyunHAVE_DYNAMIC_FTRACE + HAVE_FUNCTION_GRAPH_TRACER
387*4882a593Smuzhiyun------------------------------------------------
388*4882a593Smuzhiyun
389*4882a593SmuzhiyunThe function grapher needs a few tweaks in order to work with dynamic ftrace.
390*4882a593SmuzhiyunBasically, you will need to:
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun	- update:
393*4882a593Smuzhiyun		- ftrace_caller()
394*4882a593Smuzhiyun		- ftrace_graph_call()
395*4882a593Smuzhiyun		- ftrace_graph_caller()
396*4882a593Smuzhiyun	- implement:
397*4882a593Smuzhiyun		- ftrace_enable_ftrace_graph_caller()
398*4882a593Smuzhiyun		- ftrace_disable_ftrace_graph_caller()
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun<details to be filled>
401*4882a593Smuzhiyun
402*4882a593SmuzhiyunQuick notes:
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun	- add a nop stub after the ftrace_call location named ftrace_graph_call;
405*4882a593Smuzhiyun	  stub needs to be large enough to support a call to ftrace_graph_caller()
406*4882a593Smuzhiyun	- update ftrace_graph_caller() to work with being called by the new
407*4882a593Smuzhiyun	  ftrace_caller() since some semantics may have changed
408*4882a593Smuzhiyun	- ftrace_enable_ftrace_graph_caller() will runtime patch the
409*4882a593Smuzhiyun	  ftrace_graph_call location with a call to ftrace_graph_caller()
410*4882a593Smuzhiyun	- ftrace_disable_ftrace_graph_caller() will runtime patch the
411*4882a593Smuzhiyun	  ftrace_graph_call location with nops
412