aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/ftrace.c
diff options
context:
space:
mode:
authorSteven Rostedt (Red Hat) <rostedt@goodmis.org>2014-08-05 17:19:38 -0400
committerSteven Rostedt <rostedt@goodmis.org>2014-09-10 10:48:44 -0400
commite1effa0144a1ddf5b456c388ffaf784f3c5163fd (patch)
treec169e93553bf595d5c1f3bbd7f25d56ed0f27b2d /kernel/trace/ftrace.c
parent5fecaa044af3dc52e4bc138842bdf1c6676105b1 (diff)
ftrace: Annotate the ops operation on update
Add three new flags for ftrace_ops: FTRACE_OPS_FL_ADDING FTRACE_OPS_FL_REMOVING FTRACE_OPS_FL_MODIFYING These will be set for the ftrace_ops when they are first added to the function tracing, being removed from function tracing or just having their functions changed from function tracing, respectively. This will be needed to remove the tramp_hash, which can grow quite big. The tramp_hash is used to note what functions a ftrace_ops is using a trampoline for. Denoting which ftrace_ops is being modified, will allow us to use the ftrace_ops hashes themselves, which are much smaller as they have a global flag to denote if a ftrace_ops is tracing all functions, as well as a notrace hash if the ftrace_ops is tracing all but a few. The tramp_hash just creates a hash item for every function, which can go into the 10s of thousands if all functions are using the ftrace_ops trampoline. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r--kernel/trace/ftrace.c45
1 files changed, 39 insertions, 6 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 858ac16f8492..e43c793093e5 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1057,6 +1057,12 @@ static struct pid * const ftrace_swapper_pid = &init_struct_pid;
1057 1057
1058static struct ftrace_ops *removed_ops; 1058static struct ftrace_ops *removed_ops;
1059 1059
1060/*
1061 * Set when doing a global update, like enabling all recs or disabling them.
1062 * It is not set when just updating a single ftrace_ops.
1063 */
1064static bool update_all_ops;
1065
1060#ifndef CONFIG_FTRACE_MCOUNT_RECORD 1066#ifndef CONFIG_FTRACE_MCOUNT_RECORD
1061# error Dynamic ftrace depends on MCOUNT_RECORD 1067# error Dynamic ftrace depends on MCOUNT_RECORD
1062#endif 1068#endif
@@ -2366,6 +2372,13 @@ static void ftrace_run_update_code(int command)
2366 FTRACE_WARN_ON(ret); 2372 FTRACE_WARN_ON(ret);
2367} 2373}
2368 2374
2375static void ftrace_run_modify_code(struct ftrace_ops *ops, int command)
2376{
2377 ops->flags |= FTRACE_OPS_FL_MODIFYING;
2378 ftrace_run_update_code(command);
2379 ops->flags &= ~FTRACE_OPS_FL_MODIFYING;
2380}
2381
2369static ftrace_func_t saved_ftrace_func; 2382static ftrace_func_t saved_ftrace_func;
2370static int ftrace_start_up; 2383static int ftrace_start_up;
2371 2384
@@ -2387,6 +2400,13 @@ static void ftrace_startup_enable(int command)
2387 ftrace_run_update_code(command); 2400 ftrace_run_update_code(command);
2388} 2401}
2389 2402
2403static void ftrace_startup_all(int command)
2404{
2405 update_all_ops = true;
2406 ftrace_startup_enable(command);
2407 update_all_ops = false;
2408}
2409
2390static int ftrace_startup(struct ftrace_ops *ops, int command) 2410static int ftrace_startup(struct ftrace_ops *ops, int command)
2391{ 2411{
2392 int ret; 2412 int ret;
@@ -2401,12 +2421,22 @@ static int ftrace_startup(struct ftrace_ops *ops, int command)
2401 ftrace_start_up++; 2421 ftrace_start_up++;
2402 command |= FTRACE_UPDATE_CALLS; 2422 command |= FTRACE_UPDATE_CALLS;
2403 2423
2404 ops->flags |= FTRACE_OPS_FL_ENABLED; 2424 /*
2425 * Note that ftrace probes uses this to start up
2426 * and modify functions it will probe. But we still
2427 * set the ADDING flag for modification, as probes
2428 * do not have trampolines. If they add them in the
2429 * future, then the probes will need to distinguish
2430 * between adding and updating probes.
2431 */
2432 ops->flags |= FTRACE_OPS_FL_ENABLED | FTRACE_OPS_FL_ADDING;
2405 2433
2406 ftrace_hash_rec_enable(ops, 1); 2434 ftrace_hash_rec_enable(ops, 1);
2407 2435
2408 ftrace_startup_enable(command); 2436 ftrace_startup_enable(command);
2409 2437
2438 ops->flags &= ~FTRACE_OPS_FL_ADDING;
2439
2410 return 0; 2440 return 0;
2411} 2441}
2412 2442
@@ -2456,11 +2486,12 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int command)
2456 * If the ops uses a trampoline, then it needs to be 2486 * If the ops uses a trampoline, then it needs to be
2457 * tested first on update. 2487 * tested first on update.
2458 */ 2488 */
2489 ops->flags |= FTRACE_OPS_FL_REMOVING;
2459 removed_ops = ops; 2490 removed_ops = ops;
2460 2491
2461 ftrace_run_update_code(command); 2492 ftrace_run_update_code(command);
2462 2493
2463 removed_ops = NULL; 2494 ops->flags &= ~FTRACE_OPS_FL_REMOVING;
2464 2495
2465 /* 2496 /*
2466 * Dynamic ops may be freed, we must make sure that all 2497 * Dynamic ops may be freed, we must make sure that all
@@ -3373,7 +3404,7 @@ static void __enable_ftrace_function_probe(void)
3373 if (ftrace_probe_registered) { 3404 if (ftrace_probe_registered) {
3374 /* still need to update the function call sites */ 3405 /* still need to update the function call sites */
3375 if (ftrace_enabled) 3406 if (ftrace_enabled)
3376 ftrace_run_update_code(FTRACE_UPDATE_CALLS); 3407 ftrace_run_modify_code(&trace_probe_ops, FTRACE_UPDATE_CALLS);
3377 return; 3408 return;
3378 } 3409 }
3379 3410
@@ -3792,7 +3823,7 @@ ftrace_match_addr(struct ftrace_hash *hash, unsigned long ip, int remove)
3792static void ftrace_ops_update_code(struct ftrace_ops *ops) 3823static void ftrace_ops_update_code(struct ftrace_ops *ops)
3793{ 3824{
3794 if (ops->flags & FTRACE_OPS_FL_ENABLED && ftrace_enabled) 3825 if (ops->flags & FTRACE_OPS_FL_ENABLED && ftrace_enabled)
3795 ftrace_run_update_code(FTRACE_UPDATE_CALLS); 3826 ftrace_run_modify_code(ops, FTRACE_UPDATE_CALLS);
3796} 3827}
3797 3828
3798static int 3829static int
@@ -4717,6 +4748,7 @@ core_initcall(ftrace_nodyn_init);
4717 4748
4718static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; } 4749static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; }
4719static inline void ftrace_startup_enable(int command) { } 4750static inline void ftrace_startup_enable(int command) { }
4751static inline void ftrace_startup_all(int command) { }
4720/* Keep as macros so we do not need to define the commands */ 4752/* Keep as macros so we do not need to define the commands */
4721# define ftrace_startup(ops, command) \ 4753# define ftrace_startup(ops, command) \
4722 ({ \ 4754 ({ \
@@ -5016,7 +5048,8 @@ static int ftrace_pid_add(int p)
5016 set_ftrace_pid_task(pid); 5048 set_ftrace_pid_task(pid);
5017 5049
5018 ftrace_update_pid_func(); 5050 ftrace_update_pid_func();
5019 ftrace_startup_enable(0); 5051
5052 ftrace_startup_all(0);
5020 5053
5021 mutex_unlock(&ftrace_lock); 5054 mutex_unlock(&ftrace_lock);
5022 return 0; 5055 return 0;
@@ -5045,7 +5078,7 @@ static void ftrace_pid_reset(void)
5045 } 5078 }
5046 5079
5047 ftrace_update_pid_func(); 5080 ftrace_update_pid_func();
5048 ftrace_startup_enable(0); 5081 ftrace_startup_all(0);
5049 5082
5050 mutex_unlock(&ftrace_lock); 5083 mutex_unlock(&ftrace_lock);
5051} 5084}