diff options
Diffstat (limited to 'Documentation/trace/ftrace-design.txt')
-rw-r--r-- | Documentation/trace/ftrace-design.txt | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/Documentation/trace/ftrace-design.txt b/Documentation/trace/ftrace-design.txt index 641a1ef2a7ff..6a5a579126b0 100644 --- a/Documentation/trace/ftrace-design.txt +++ b/Documentation/trace/ftrace-design.txt | |||
@@ -1,5 +1,6 @@ | |||
1 | function tracer guts | 1 | function tracer guts |
2 | ==================== | 2 | ==================== |
3 | By Mike Frysinger | ||
3 | 4 | ||
4 | Introduction | 5 | Introduction |
5 | ------------ | 6 | ------------ |
@@ -53,14 +54,14 @@ size of the mcount call that is embedded in the function). | |||
53 | For example, if the function foo() calls bar(), when the bar() function calls | 54 | For example, if the function foo() calls bar(), when the bar() function calls |
54 | mcount(), the arguments mcount() will pass to the tracer are: | 55 | mcount(), the arguments mcount() will pass to the tracer are: |
55 | "frompc" - the address bar() will use to return to foo() | 56 | "frompc" - the address bar() will use to return to foo() |
56 | "selfpc" - the address bar() (with _mcount() size adjustment) | 57 | "selfpc" - the address bar() (with mcount() size adjustment) |
57 | 58 | ||
58 | Also keep in mind that this mcount function will be called *a lot*, so | 59 | Also keep in mind that this mcount function will be called *a lot*, so |
59 | optimizing for the default case of no tracer will help the smooth running of | 60 | optimizing for the default case of no tracer will help the smooth running of |
60 | your system when tracing is disabled. So the start of the mcount function is | 61 | your system when tracing is disabled. So the start of the mcount function is |
61 | typically the bare min with checking things before returning. That also means | 62 | typically the bare minimum with checking things before returning. That also |
62 | the code flow should usually kept linear (i.e. no branching in the nop case). | 63 | means the code flow should usually be kept linear (i.e. no branching in the nop |
63 | This is of course an optimization and not a hard requirement. | 64 | case). This is of course an optimization and not a hard requirement. |
64 | 65 | ||
65 | Here is some pseudo code that should help (these functions should actually be | 66 | Here is some pseudo code that should help (these functions should actually be |
66 | implemented in assembly): | 67 | implemented in assembly): |
@@ -131,10 +132,10 @@ some functions to save (hijack) and restore the return address. | |||
131 | 132 | ||
132 | The mcount function should check the function pointers ftrace_graph_return | 133 | The mcount function should check the function pointers ftrace_graph_return |
133 | (compare to ftrace_stub) and ftrace_graph_entry (compare to | 134 | (compare to ftrace_stub) and ftrace_graph_entry (compare to |
134 | ftrace_graph_entry_stub). If either of those are not set to the relevant stub | 135 | ftrace_graph_entry_stub). If either of those is not set to the relevant stub |
135 | function, call the arch-specific function ftrace_graph_caller which in turn | 136 | function, call the arch-specific function ftrace_graph_caller which in turn |
136 | calls the arch-specific function prepare_ftrace_return. Neither of these | 137 | calls the arch-specific function prepare_ftrace_return. Neither of these |
137 | function names are strictly required, but you should use them anyways to stay | 138 | function names is strictly required, but you should use them anyway to stay |
138 | consistent across the architecture ports -- easier to compare & contrast | 139 | consistent across the architecture ports -- easier to compare & contrast |
139 | things. | 140 | things. |
140 | 141 | ||
@@ -144,7 +145,7 @@ but the first argument should be a pointer to the "frompc". Typically this is | |||
144 | located on the stack. This allows the function to hijack the return address | 145 | located on the stack. This allows the function to hijack the return address |
145 | temporarily to have it point to the arch-specific function return_to_handler. | 146 | temporarily to have it point to the arch-specific function return_to_handler. |
146 | That function will simply call the common ftrace_return_to_handler function and | 147 | That function will simply call the common ftrace_return_to_handler function and |
147 | that will return the original return address with which, you can return to the | 148 | that will return the original return address with which you can return to the |
148 | original call site. | 149 | original call site. |
149 | 150 | ||
150 | Here is the updated mcount pseudo code: | 151 | Here is the updated mcount pseudo code: |
@@ -173,14 +174,16 @@ void ftrace_graph_caller(void) | |||
173 | 174 | ||
174 | unsigned long *frompc = &...; | 175 | unsigned long *frompc = &...; |
175 | unsigned long selfpc = <return address> - MCOUNT_INSN_SIZE; | 176 | unsigned long selfpc = <return address> - MCOUNT_INSN_SIZE; |
176 | prepare_ftrace_return(frompc, selfpc); | 177 | /* passing frame pointer up is optional -- see below */ |
178 | prepare_ftrace_return(frompc, selfpc, frame_pointer); | ||
177 | 179 | ||
178 | /* restore all state needed by the ABI */ | 180 | /* restore all state needed by the ABI */ |
179 | } | 181 | } |
180 | #endif | 182 | #endif |
181 | 183 | ||
182 | For information on how to implement prepare_ftrace_return(), simply look at | 184 | For information on how to implement prepare_ftrace_return(), simply look at the |
183 | the x86 version. The only architecture-specific piece in it is the setup of | 185 | x86 version (the frame pointer passing is optional; see the next section for |
186 | more information). The only architecture-specific piece in it is the setup of | ||
184 | the fault recovery table (the asm(...) code). The rest should be the same | 187 | the fault recovery table (the asm(...) code). The rest should be the same |
185 | across architectures. | 188 | across architectures. |
186 | 189 | ||
@@ -205,6 +208,23 @@ void return_to_handler(void) | |||
205 | #endif | 208 | #endif |
206 | 209 | ||
207 | 210 | ||
211 | HAVE_FUNCTION_GRAPH_FP_TEST | ||
212 | --------------------------- | ||
213 | |||
214 | An arch may pass in a unique value (frame pointer) to both the entering and | ||
215 | exiting of a function. On exit, the value is compared and if it does not | ||
216 | match, then it will panic the kernel. This is largely a sanity check for bad | ||
217 | code generation with gcc. If gcc for your port sanely updates the frame | ||
218 | pointer under different opitmization levels, then ignore this option. | ||
219 | |||
220 | However, adding support for it isn't terribly difficult. In your assembly code | ||
221 | that calls prepare_ftrace_return(), pass the frame pointer as the 3rd argument. | ||
222 | Then in the C version of that function, do what the x86 port does and pass it | ||
223 | along to ftrace_push_return_trace() instead of a stub value of 0. | ||
224 | |||
225 | Similarly, when you call ftrace_return_to_handler(), pass it the frame pointer. | ||
226 | |||
227 | |||
208 | HAVE_FTRACE_NMI_ENTER | 228 | HAVE_FTRACE_NMI_ENTER |
209 | --------------------- | 229 | --------------------- |
210 | 230 | ||