Skip to content

Commit e1effa0

Browse files
committed
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 <[email protected]>
1 parent 5fecaa0 commit e1effa0

File tree

2 files changed

+45
-6
lines changed

2 files changed

+45
-6
lines changed

include/linux/ftrace.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ ftrace_func_t ftrace_ops_get_func(struct ftrace_ops *ops);
9191
* INITIALIZED - The ftrace_ops has already been initialized (first use time
9292
* register_ftrace_function() is called, it will initialized the ops)
9393
* DELETED - The ops are being deleted, do not let them be registered again.
94+
* ADDING - The ops is in the process of being added.
95+
* REMOVING - The ops is in the process of being removed.
96+
* MODIFYING - The ops is in the process of changing its filter functions.
9497
*/
9598
enum {
9699
FTRACE_OPS_FL_ENABLED = 1 << 0,
@@ -102,6 +105,9 @@ enum {
102105
FTRACE_OPS_FL_STUB = 1 << 6,
103106
FTRACE_OPS_FL_INITIALIZED = 1 << 7,
104107
FTRACE_OPS_FL_DELETED = 1 << 8,
108+
FTRACE_OPS_FL_ADDING = 1 << 9,
109+
FTRACE_OPS_FL_REMOVING = 1 << 10,
110+
FTRACE_OPS_FL_MODIFYING = 1 << 11,
105111
};
106112

107113
#ifdef CONFIG_DYNAMIC_FTRACE

kernel/trace/ftrace.c

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,12 @@ static struct pid * const ftrace_swapper_pid = &init_struct_pid;
10571057

10581058
static struct ftrace_ops *removed_ops;
10591059

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+
*/
1064+
static bool update_all_ops;
1065+
10601066
#ifndef CONFIG_FTRACE_MCOUNT_RECORD
10611067
# error Dynamic ftrace depends on MCOUNT_RECORD
10621068
#endif
@@ -2366,6 +2372,13 @@ static void ftrace_run_update_code(int command)
23662372
FTRACE_WARN_ON(ret);
23672373
}
23682374

2375+
static 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+
23692382
static ftrace_func_t saved_ftrace_func;
23702383
static int ftrace_start_up;
23712384

@@ -2387,6 +2400,13 @@ static void ftrace_startup_enable(int command)
23872400
ftrace_run_update_code(command);
23882401
}
23892402

2403+
static void ftrace_startup_all(int command)
2404+
{
2405+
update_all_ops = true;
2406+
ftrace_startup_enable(command);
2407+
update_all_ops = false;
2408+
}
2409+
23902410
static int ftrace_startup(struct ftrace_ops *ops, int command)
23912411
{
23922412
int ret;
@@ -2401,12 +2421,22 @@ static int ftrace_startup(struct ftrace_ops *ops, int command)
24012421
ftrace_start_up++;
24022422
command |= FTRACE_UPDATE_CALLS;
24032423

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;
24052433

24062434
ftrace_hash_rec_enable(ops, 1);
24072435

24082436
ftrace_startup_enable(command);
24092437

2438+
ops->flags &= ~FTRACE_OPS_FL_ADDING;
2439+
24102440
return 0;
24112441
}
24122442

@@ -2456,11 +2486,12 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int command)
24562486
* If the ops uses a trampoline, then it needs to be
24572487
* tested first on update.
24582488
*/
2489+
ops->flags |= FTRACE_OPS_FL_REMOVING;
24592490
removed_ops = ops;
24602491

24612492
ftrace_run_update_code(command);
24622493

2463-
removed_ops = NULL;
2494+
ops->flags &= ~FTRACE_OPS_FL_REMOVING;
24642495

24652496
/*
24662497
* Dynamic ops may be freed, we must make sure that all
@@ -3373,7 +3404,7 @@ static void __enable_ftrace_function_probe(void)
33733404
if (ftrace_probe_registered) {
33743405
/* still need to update the function call sites */
33753406
if (ftrace_enabled)
3376-
ftrace_run_update_code(FTRACE_UPDATE_CALLS);
3407+
ftrace_run_modify_code(&trace_probe_ops, FTRACE_UPDATE_CALLS);
33773408
return;
33783409
}
33793410

@@ -3792,7 +3823,7 @@ ftrace_match_addr(struct ftrace_hash *hash, unsigned long ip, int remove)
37923823
static void ftrace_ops_update_code(struct ftrace_ops *ops)
37933824
{
37943825
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);
37963827
}
37973828

37983829
static int
@@ -4717,6 +4748,7 @@ core_initcall(ftrace_nodyn_init);
47174748

47184749
static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; }
47194750
static inline void ftrace_startup_enable(int command) { }
4751+
static inline void ftrace_startup_all(int command) { }
47204752
/* Keep as macros so we do not need to define the commands */
47214753
# define ftrace_startup(ops, command) \
47224754
({ \
@@ -5016,7 +5048,8 @@ static int ftrace_pid_add(int p)
50165048
set_ftrace_pid_task(pid);
50175049

50185050
ftrace_update_pid_func();
5019-
ftrace_startup_enable(0);
5051+
5052+
ftrace_startup_all(0);
50205053

50215054
mutex_unlock(&ftrace_lock);
50225055
return 0;
@@ -5045,7 +5078,7 @@ static void ftrace_pid_reset(void)
50455078
}
50465079

50475080
ftrace_update_pid_func();
5048-
ftrace_startup_enable(0);
5081+
ftrace_startup_all(0);
50495082

50505083
mutex_unlock(&ftrace_lock);
50515084
}

0 commit comments

Comments
 (0)