diff options
author | Steven Rostedt <srostedt@redhat.com> | 2011-05-03 22:49:52 -0400 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2011-05-18 15:29:49 -0400 |
commit | 2b499381bc50ede01b3d8eab164ca2fad00655f0 (patch) | |
tree | 3140c277582b03b1645fffcb829763d62e2f01fa /kernel/trace/ftrace.c | |
parent | bd69c30b1d08032d97ab0dabd7a1eb7fb73ca2b2 (diff) |
ftrace: Have global_ops store the functions that are to be traced
This is a step towards each ops structure defining its own set
of functions to trace. As the current code with pid's and such
are specific to the global_ops, it is restructured to be used
with the global ops.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r-- | kernel/trace/ftrace.c | 69 |
1 files changed, 53 insertions, 16 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 8fef1d99bbbf..dcce0bf9c84d 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -91,6 +91,7 @@ static struct ftrace_ops *ftrace_list __read_mostly = &ftrace_list_end; | |||
91 | ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub; | 91 | ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub; |
92 | ftrace_func_t __ftrace_trace_function __read_mostly = ftrace_stub; | 92 | ftrace_func_t __ftrace_trace_function __read_mostly = ftrace_stub; |
93 | ftrace_func_t ftrace_pid_function __read_mostly = ftrace_stub; | 93 | ftrace_func_t ftrace_pid_function __read_mostly = ftrace_stub; |
94 | static struct ftrace_ops global_ops; | ||
94 | 95 | ||
95 | /* | 96 | /* |
96 | * Traverse the ftrace_list, invoking all entries. The reason that we | 97 | * Traverse the ftrace_list, invoking all entries. The reason that we |
@@ -153,7 +154,7 @@ static void ftrace_test_stop_func(unsigned long ip, unsigned long parent_ip) | |||
153 | } | 154 | } |
154 | #endif | 155 | #endif |
155 | 156 | ||
156 | static void update_ftrace_function(void) | 157 | static void update_global_ops(void) |
157 | { | 158 | { |
158 | ftrace_func_t func; | 159 | ftrace_func_t func; |
159 | 160 | ||
@@ -173,6 +174,18 @@ static void update_ftrace_function(void) | |||
173 | set_ftrace_pid_function(func); | 174 | set_ftrace_pid_function(func); |
174 | func = ftrace_pid_func; | 175 | func = ftrace_pid_func; |
175 | } | 176 | } |
177 | |||
178 | global_ops.func = func; | ||
179 | } | ||
180 | |||
181 | static void update_ftrace_function(void) | ||
182 | { | ||
183 | ftrace_func_t func; | ||
184 | |||
185 | update_global_ops(); | ||
186 | |||
187 | func = global_ops.func; | ||
188 | |||
176 | #ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST | 189 | #ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST |
177 | ftrace_trace_function = func; | 190 | ftrace_trace_function = func; |
178 | #else | 191 | #else |
@@ -181,24 +194,19 @@ static void update_ftrace_function(void) | |||
181 | #endif | 194 | #endif |
182 | } | 195 | } |
183 | 196 | ||
184 | static int __register_ftrace_function(struct ftrace_ops *ops) | 197 | static void add_ftrace_ops(struct ftrace_ops **list, struct ftrace_ops *ops) |
185 | { | 198 | { |
186 | ops->next = ftrace_list; | 199 | ops->next = *list; |
187 | /* | 200 | /* |
188 | * We are entering ops into the ftrace_list but another | 201 | * We are entering ops into the ftrace_list but another |
189 | * CPU might be walking that list. We need to make sure | 202 | * CPU might be walking that list. We need to make sure |
190 | * the ops->next pointer is valid before another CPU sees | 203 | * the ops->next pointer is valid before another CPU sees |
191 | * the ops pointer included into the ftrace_list. | 204 | * the ops pointer included into the ftrace_list. |
192 | */ | 205 | */ |
193 | rcu_assign_pointer(ftrace_list, ops); | 206 | rcu_assign_pointer(*list, ops); |
194 | |||
195 | if (ftrace_enabled) | ||
196 | update_ftrace_function(); | ||
197 | |||
198 | return 0; | ||
199 | } | 207 | } |
200 | 208 | ||
201 | static int __unregister_ftrace_function(struct ftrace_ops *ops) | 209 | static int remove_ftrace_ops(struct ftrace_ops **list, struct ftrace_ops *ops) |
202 | { | 210 | { |
203 | struct ftrace_ops **p; | 211 | struct ftrace_ops **p; |
204 | 212 | ||
@@ -206,13 +214,12 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops) | |||
206 | * If we are removing the last function, then simply point | 214 | * If we are removing the last function, then simply point |
207 | * to the ftrace_stub. | 215 | * to the ftrace_stub. |
208 | */ | 216 | */ |
209 | if (ftrace_list == ops && ops->next == &ftrace_list_end) { | 217 | if (*list == ops && ops->next == &ftrace_list_end) { |
210 | ftrace_trace_function = ftrace_stub; | 218 | *list = &ftrace_list_end; |
211 | ftrace_list = &ftrace_list_end; | ||
212 | return 0; | 219 | return 0; |
213 | } | 220 | } |
214 | 221 | ||
215 | for (p = &ftrace_list; *p != &ftrace_list_end; p = &(*p)->next) | 222 | for (p = list; *p != &ftrace_list_end; p = &(*p)->next) |
216 | if (*p == ops) | 223 | if (*p == ops) |
217 | break; | 224 | break; |
218 | 225 | ||
@@ -220,7 +227,37 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops) | |||
220 | return -1; | 227 | return -1; |
221 | 228 | ||
222 | *p = (*p)->next; | 229 | *p = (*p)->next; |
230 | return 0; | ||
231 | } | ||
232 | |||
233 | static int __register_ftrace_function(struct ftrace_ops *ops) | ||
234 | { | ||
235 | if (ftrace_disabled) | ||
236 | return -ENODEV; | ||
237 | |||
238 | if (FTRACE_WARN_ON(ops == &global_ops)) | ||
239 | return -EINVAL; | ||
240 | |||
241 | add_ftrace_ops(&ftrace_list, ops); | ||
242 | if (ftrace_enabled) | ||
243 | update_ftrace_function(); | ||
244 | |||
245 | return 0; | ||
246 | } | ||
223 | 247 | ||
248 | static int __unregister_ftrace_function(struct ftrace_ops *ops) | ||
249 | { | ||
250 | int ret; | ||
251 | |||
252 | if (ftrace_disabled) | ||
253 | return -ENODEV; | ||
254 | |||
255 | if (FTRACE_WARN_ON(ops == &global_ops)) | ||
256 | return -EINVAL; | ||
257 | |||
258 | ret = remove_ftrace_ops(&ftrace_list, ops); | ||
259 | if (ret < 0) | ||
260 | return ret; | ||
224 | if (ftrace_enabled) | 261 | if (ftrace_enabled) |
225 | update_ftrace_function(); | 262 | update_ftrace_function(); |
226 | 263 | ||
@@ -894,7 +931,7 @@ enum { | |||
894 | FTRACE_OPS_FL_ENABLED = 1, | 931 | FTRACE_OPS_FL_ENABLED = 1, |
895 | }; | 932 | }; |
896 | 933 | ||
897 | struct ftrace_ops global_ops = { | 934 | static struct ftrace_ops global_ops = { |
898 | .func = ftrace_stub, | 935 | .func = ftrace_stub, |
899 | .notrace_hash = EMPTY_HASH, | 936 | .notrace_hash = EMPTY_HASH, |
900 | .filter_hash = EMPTY_HASH, | 937 | .filter_hash = EMPTY_HASH, |
@@ -3263,7 +3300,7 @@ void __init ftrace_init(void) | |||
3263 | 3300 | ||
3264 | #else | 3301 | #else |
3265 | 3302 | ||
3266 | struct ftrace_ops global_ops = { | 3303 | static struct ftrace_ops global_ops = { |
3267 | .func = ftrace_stub, | 3304 | .func = ftrace_stub, |
3268 | }; | 3305 | }; |
3269 | 3306 | ||