Skip to content

Commit d182985

Browse files
ftrace: Store direct called addresses in their ops
JIRA: https://issues.redhat.com/browse/RHEL-101598 commit dbaccb6 Author: Florent Revest <[email protected]> Date: Tue Mar 21 15:04:22 2023 +0100 ftrace: Store direct called addresses in their ops All direct calls are now registered using the register_ftrace_direct API so each ops can jump to only one direct-called trampoline. By storing the direct called trampoline address directly in the ops we can save one hashmap lookup in the direct call ops and implement arm64 direct calls on top of call ops. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Florent Revest <[email protected]> Acked-by: Jiri Olsa <[email protected]> Signed-off-by: Steven Rostedt (Google) <[email protected]> Signed-off-by: Jerome Marchand <[email protected]>
1 parent 8108cf1 commit d182985

File tree

2 files changed

+8
-2
lines changed

2 files changed

+8
-2
lines changed

include/linux/ftrace.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,9 @@ struct ftrace_ops {
314314
unsigned long trampoline_size;
315315
struct list_head list;
316316
ftrace_ops_func_t ops_func;
317+
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
318+
unsigned long direct_call;
319+
#endif
317320
#endif
318321
};
319322

kernel/trace/ftrace.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2586,9 +2586,8 @@ ftrace_add_rec_direct(unsigned long ip, unsigned long addr,
25862586
static void call_direct_funcs(unsigned long ip, unsigned long pip,
25872587
struct ftrace_ops *ops, struct ftrace_regs *fregs)
25882588
{
2589-
unsigned long addr;
2589+
unsigned long addr = READ_ONCE(ops->direct_call);
25902590

2591-
addr = ftrace_find_rec_direct(ip);
25922591
if (!addr)
25932592
return;
25942593

@@ -5368,6 +5367,7 @@ int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
53685367
ops->func = call_direct_funcs;
53695368
ops->flags = MULTI_FLAGS;
53705369
ops->trampoline = FTRACE_REGS_ADDR;
5370+
ops->direct_call = addr;
53715371

53725372
err = register_ftrace_function_nolock(ops);
53735373

@@ -5442,6 +5442,7 @@ __modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
54425442
/* Enable the tmp_ops to have the same functions as the direct ops */
54435443
ftrace_ops_init(&tmp_ops);
54445444
tmp_ops.func_hash = ops->func_hash;
5445+
tmp_ops.direct_call = addr;
54455446

54465447
err = register_ftrace_function_nolock(&tmp_ops);
54475448
if (err)
@@ -5463,6 +5464,8 @@ __modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
54635464
entry->direct = addr;
54645465
}
54655466
}
5467+
/* Prevent store tearing if a trampoline concurrently accesses the value */
5468+
WRITE_ONCE(ops->direct_call, addr);
54665469

54675470
mutex_unlock(&ftrace_lock);
54685471

0 commit comments

Comments
 (0)