From nobody Sun Feb 8 05:41:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 463CDC6FD1C for ; Wed, 22 Mar 2023 18:43:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230150AbjCVSnt (ORCPT ); Wed, 22 Mar 2023 14:43:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56096 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230052AbjCVSnj (ORCPT ); Wed, 22 Mar 2023 14:43:39 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7EC8C298FE for ; Wed, 22 Mar 2023 11:43:37 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 284EAB81DAF for ; Wed, 22 Mar 2023 18:43:36 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E529BC433EF; Wed, 22 Mar 2023 18:43:34 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.96) (envelope-from ) id 1pf3Qr-000pWL-2v; Wed, 22 Mar 2023 14:43:33 -0400 Message-ID: <20230322184333.718703835@goodmis.org> User-Agent: quilt/0.66 Date: Wed, 22 Mar 2023 14:42:40 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Andrew Morton , Florent Revest , Jiri Olsa Subject: [for-next][PATCH 01/11] ftrace: Let unregister_ftrace_direct_multi() call ftrace_free_filter() References: <20230322184239.594953818@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Florent Revest A common pattern when using the ftrace_direct_multi API is to unregister the ops and also immediately free its filter. We've noticed it's very easy for users to miss calling ftrace_free_filter(). This adds a "free_filters" argument to unregister_ftrace_direct_multi() to both remind the user they should free filters and also to make their life easier. Link: https://lkml.kernel.org/r/20230321140424.345218-2-revest@chromium.org Suggested-by: Steven Rostedt Signed-off-by: Florent Revest Acked-by: Mark Rutland Acked-by: Jiri Olsa Signed-off-by: Steven Rostedt (Google) --- include/linux/ftrace.h | 6 ++++-- kernel/bpf/trampoline.c | 2 +- kernel/trace/ftrace.c | 6 +++++- samples/ftrace/ftrace-direct-multi-modify.c | 3 +-- samples/ftrace/ftrace-direct-multi.c | 3 +-- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 366c730beaa3..5b68ee874bc1 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -407,7 +407,8 @@ int ftrace_modify_direct_caller(struct ftrace_func_entr= y *entry, unsigned long new_addr); unsigned long ftrace_find_rec_direct(unsigned long ip); int register_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long add= r); -int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long a= ddr); +int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long a= ddr, + bool free_filters); int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr); int modify_ftrace_direct_multi_nolock(struct ftrace_ops *ops, unsigned lon= g addr); =20 @@ -446,7 +447,8 @@ static inline int register_ftrace_direct_multi(struct f= trace_ops *ops, unsigned { return -ENODEV; } -static inline int unregister_ftrace_direct_multi(struct ftrace_ops *ops, u= nsigned long addr) +static inline int unregister_ftrace_direct_multi(struct ftrace_ops *ops, u= nsigned long addr, + bool free_filters) { return -ENODEV; } diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c index d0ed7d6f5eec..88bc23f1e10a 100644 --- a/kernel/bpf/trampoline.c +++ b/kernel/bpf/trampoline.c @@ -198,7 +198,7 @@ static int unregister_fentry(struct bpf_trampoline *tr,= void *old_addr) int ret; =20 if (tr->func.ftrace_managed) - ret =3D unregister_ftrace_direct_multi(tr->fops, (long)old_addr); + ret =3D unregister_ftrace_direct_multi(tr->fops, (long)old_addr, false); else ret =3D bpf_arch_text_poke(ip, BPF_MOD_CALL, old_addr, NULL); =20 diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 0feea145bb29..98434196c6a1 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -5805,7 +5805,8 @@ EXPORT_SYMBOL_GPL(register_ftrace_direct_multi); * 0 on success * -EINVAL - The @ops object was not properly registered. */ -int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long a= ddr) +int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long a= ddr, + bool free_filters) { struct ftrace_hash *hash =3D ops->func_hash->filter_hash; int err; @@ -5823,6 +5824,9 @@ int unregister_ftrace_direct_multi(struct ftrace_ops = *ops, unsigned long addr) /* cleanup for possible another register call */ ops->func =3D NULL; ops->trampoline =3D 0; + + if (free_filters) + ftrace_free_filter(ops); return err; } EXPORT_SYMBOL_GPL(unregister_ftrace_direct_multi); diff --git a/samples/ftrace/ftrace-direct-multi-modify.c b/samples/ftrace/f= trace-direct-multi-modify.c index b58c594efb51..196b43971cb5 100644 --- a/samples/ftrace/ftrace-direct-multi-modify.c +++ b/samples/ftrace/ftrace-direct-multi-modify.c @@ -151,8 +151,7 @@ static int __init ftrace_direct_multi_init(void) static void __exit ftrace_direct_multi_exit(void) { kthread_stop(simple_tsk); - unregister_ftrace_direct_multi(&direct, my_tramp); - ftrace_free_filter(&direct); + unregister_ftrace_direct_multi(&direct, my_tramp, true); } =20 module_init(ftrace_direct_multi_init); diff --git a/samples/ftrace/ftrace-direct-multi.c b/samples/ftrace/ftrace-d= irect-multi.c index c27cf130c319..ea0e88ee5e43 100644 --- a/samples/ftrace/ftrace-direct-multi.c +++ b/samples/ftrace/ftrace-direct-multi.c @@ -78,8 +78,7 @@ static int __init ftrace_direct_multi_init(void) =20 static void __exit ftrace_direct_multi_exit(void) { - unregister_ftrace_direct_multi(&direct, (unsigned long) my_tramp); - ftrace_free_filter(&direct); + unregister_ftrace_direct_multi(&direct, (unsigned long) my_tramp, true); } =20 module_init(ftrace_direct_multi_init); --=20 2.39.1 From nobody Sun Feb 8 05:41:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2FAA4C6FD1C for ; Wed, 22 Mar 2023 18:44:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230350AbjCVSoB (ORCPT ); Wed, 22 Mar 2023 14:44:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56152 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230124AbjCVSnj (ORCPT ); Wed, 22 Mar 2023 14:43:39 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9DCB929E07 for ; Wed, 22 Mar 2023 11:43:37 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 4C081B81DA9 for ; Wed, 22 Mar 2023 18:43:36 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 12B47C4339B; Wed, 22 Mar 2023 18:43:35 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.96) (envelope-from ) id 1pf3Qs-000pWt-0M; Wed, 22 Mar 2023 14:43:34 -0400 Message-ID: <20230322184333.927351019@goodmis.org> User-Agent: quilt/0.66 Date: Wed, 22 Mar 2023 14:42:41 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Andrew Morton , Florent Revest , Jiri Olsa Subject: [for-next][PATCH 02/11] ftrace: Replace uses of _ftrace_direct APIs with _ftrace_direct_multi References: <20230322184239.594953818@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Florent Revest The _multi API requires that users keep their own ops but can enforce that an op is only associated to one direct call. Link: https://lkml.kernel.org/r/20230321140424.345218-3-revest@chromium.org Signed-off-by: Florent Revest Acked-by: Mark Rutland Tested-by: Mark Rutland Acked-by: Jiri Olsa Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace_selftest.c | 10 ++++++---- samples/ftrace/ftrace-direct-modify.c | 12 ++++++++---- samples/ftrace/ftrace-direct-too.c | 12 +++++++----- samples/ftrace/ftrace-direct.c | 12 +++++++----- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index ff0536cea968..9ce80b3ad06d 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -785,6 +785,7 @@ static struct fgraph_ops fgraph_ops __initdata =3D { }; =20 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS +static struct ftrace_ops direct; #ifndef CALL_DEPTH_ACCOUNT #define CALL_DEPTH_ACCOUNT "" #endif @@ -870,8 +871,8 @@ trace_selftest_startup_function_graph(struct tracer *tr= ace, * Register direct function together with graph tracer * and make sure we get graph trace. */ - ret =3D register_ftrace_direct((unsigned long) DYN_FTRACE_TEST_NAME, - (unsigned long) trace_direct_tramp); + ftrace_set_filter_ip(&direct, (unsigned long)DYN_FTRACE_TEST_NAME, 0, 0); + ret =3D register_ftrace_direct_multi(&direct, (unsigned long)trace_direct= _tramp); if (ret) goto out; =20 @@ -891,8 +892,9 @@ trace_selftest_startup_function_graph(struct tracer *tr= ace, =20 unregister_ftrace_graph(&fgraph_ops); =20 - ret =3D unregister_ftrace_direct((unsigned long) DYN_FTRACE_TEST_NAME, - (unsigned long) trace_direct_tramp); + ret =3D unregister_ftrace_direct_multi(&direct, + (unsigned long) trace_direct_tramp, + true); if (ret) goto out; =20 diff --git a/samples/ftrace/ftrace-direct-modify.c b/samples/ftrace/ftrace-= direct-modify.c index d93abbcb1f4c..f01ac74bac10 100644 --- a/samples/ftrace/ftrace-direct-modify.c +++ b/samples/ftrace/ftrace-direct-modify.c @@ -96,6 +96,8 @@ asm ( =20 #endif /* CONFIG_S390 */ =20 +static struct ftrace_ops direct; + static unsigned long my_tramp =3D (unsigned long)my_tramp1; static unsigned long tramps[2] =3D { (unsigned long)my_tramp1, @@ -114,7 +116,7 @@ static int simple_thread(void *arg) if (ret) continue; t ^=3D 1; - ret =3D modify_ftrace_direct(my_ip, my_tramp, tramps[t]); + ret =3D modify_ftrace_direct_multi(&direct, tramps[t]); if (!ret) my_tramp =3D tramps[t]; WARN_ON_ONCE(ret); @@ -129,7 +131,9 @@ static int __init ftrace_direct_init(void) { int ret; =20 - ret =3D register_ftrace_direct(my_ip, my_tramp); + ftrace_set_filter_ip(&direct, (unsigned long) my_ip, 0, 0); + ret =3D register_ftrace_direct_multi(&direct, my_tramp); + if (!ret) simple_tsk =3D kthread_run(simple_thread, NULL, "event-sample-fn"); return ret; @@ -138,12 +142,12 @@ static int __init ftrace_direct_init(void) static void __exit ftrace_direct_exit(void) { kthread_stop(simple_tsk); - unregister_ftrace_direct(my_ip, my_tramp); + unregister_ftrace_direct_multi(&direct, my_tramp, true); } =20 module_init(ftrace_direct_init); module_exit(ftrace_direct_exit); =20 MODULE_AUTHOR("Steven Rostedt"); -MODULE_DESCRIPTION("Example use case of using modify_ftrace_direct()"); +MODULE_DESCRIPTION("Example use case of using modify_ftrace_direct_multi()= "); MODULE_LICENSE("GPL"); diff --git a/samples/ftrace/ftrace-direct-too.c b/samples/ftrace/ftrace-dir= ect-too.c index 8139dce2a31c..05c3585ac15e 100644 --- a/samples/ftrace/ftrace-direct-too.c +++ b/samples/ftrace/ftrace-direct-too.c @@ -70,21 +70,23 @@ asm ( =20 #endif /* CONFIG_S390 */ =20 +static struct ftrace_ops direct; + static int __init ftrace_direct_init(void) { - return register_ftrace_direct((unsigned long)handle_mm_fault, - (unsigned long)my_tramp); + ftrace_set_filter_ip(&direct, (unsigned long) handle_mm_fault, 0, 0); + + return register_ftrace_direct_multi(&direct, (unsigned long) my_tramp); } =20 static void __exit ftrace_direct_exit(void) { - unregister_ftrace_direct((unsigned long)handle_mm_fault, - (unsigned long)my_tramp); + unregister_ftrace_direct_multi(&direct, (unsigned long)my_tramp, true); } =20 module_init(ftrace_direct_init); module_exit(ftrace_direct_exit); =20 MODULE_AUTHOR("Steven Rostedt"); -MODULE_DESCRIPTION("Another example use case of using register_ftrace_dire= ct()"); +MODULE_DESCRIPTION("Another example use case of using register_ftrace_dire= ct_multi()"); MODULE_LICENSE("GPL"); diff --git a/samples/ftrace/ftrace-direct.c b/samples/ftrace/ftrace-direct.c index 1d3d307ca33d..42ec9e39453b 100644 --- a/samples/ftrace/ftrace-direct.c +++ b/samples/ftrace/ftrace-direct.c @@ -63,21 +63,23 @@ asm ( =20 #endif /* CONFIG_S390 */ =20 +static struct ftrace_ops direct; + static int __init ftrace_direct_init(void) { - return register_ftrace_direct((unsigned long)wake_up_process, - (unsigned long)my_tramp); + ftrace_set_filter_ip(&direct, (unsigned long) wake_up_process, 0, 0); + + return register_ftrace_direct_multi(&direct, (unsigned long) my_tramp); } =20 static void __exit ftrace_direct_exit(void) { - unregister_ftrace_direct((unsigned long)wake_up_process, - (unsigned long)my_tramp); + unregister_ftrace_direct_multi(&direct, (unsigned long)my_tramp, true); } =20 module_init(ftrace_direct_init); module_exit(ftrace_direct_exit); =20 MODULE_AUTHOR("Steven Rostedt"); -MODULE_DESCRIPTION("Example use case of using register_ftrace_direct()"); +MODULE_DESCRIPTION("Example use case of using register_ftrace_direct_multi= ()"); MODULE_LICENSE("GPL"); --=20 2.39.1 From nobody Sun Feb 8 05:41:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C6B6DC6FD1C for ; Wed, 22 Mar 2023 18:43:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230329AbjCVSnq (ORCPT ); Wed, 22 Mar 2023 14:43:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56034 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229973AbjCVSni (ORCPT ); Wed, 22 Mar 2023 14:43:38 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 854E72943F for ; Wed, 22 Mar 2023 11:43:36 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 14F7262279 for ; Wed, 22 Mar 2023 18:43:36 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 509E4C433A8; Wed, 22 Mar 2023 18:43:35 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.96) (envelope-from ) id 1pf3Qs-000pXR-11; Wed, 22 Mar 2023 14:43:34 -0400 Message-ID: <20230322184334.134626037@goodmis.org> User-Agent: quilt/0.66 Date: Wed, 22 Mar 2023 14:42:42 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Andrew Morton , Florent Revest , Jiri Olsa Subject: [for-next][PATCH 03/11] ftrace: Remove the legacy _ftrace_direct API References: <20230322184239.594953818@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Florent Revest This API relies on a single global ops, used for all direct calls registered with it. However, to implement arm64 direct calls, we need each ops to point to a single direct call trampoline. Link: https://lkml.kernel.org/r/20230321140424.345218-4-revest@chromium.org Signed-off-by: Florent Revest Acked-by: Mark Rutland Tested-by: Mark Rutland Acked-by: Jiri Olsa Signed-off-by: Steven Rostedt (Google) --- include/linux/ftrace.h | 32 ---- kernel/trace/ftrace.c | 393 ----------------------------------------- 2 files changed, 425 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 5b68ee874bc1..2f400c9f0787 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -397,14 +397,6 @@ struct ftrace_func_entry { =20 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS extern int ftrace_direct_func_count; -int register_ftrace_direct(unsigned long ip, unsigned long addr); -int unregister_ftrace_direct(unsigned long ip, unsigned long addr); -int modify_ftrace_direct(unsigned long ip, unsigned long old_addr, unsigne= d long new_addr); -struct ftrace_direct_func *ftrace_find_direct_func(unsigned long addr); -int ftrace_modify_direct_caller(struct ftrace_func_entry *entry, - struct dyn_ftrace *rec, - unsigned long old_addr, - unsigned long new_addr); unsigned long ftrace_find_rec_direct(unsigned long ip); int register_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long add= r); int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long a= ddr, @@ -415,30 +407,6 @@ int modify_ftrace_direct_multi_nolock(struct ftrace_op= s *ops, unsigned long addr #else struct ftrace_ops; # define ftrace_direct_func_count 0 -static inline int register_ftrace_direct(unsigned long ip, unsigned long a= ddr) -{ - return -ENOTSUPP; -} -static inline int unregister_ftrace_direct(unsigned long ip, unsigned long= addr) -{ - return -ENOTSUPP; -} -static inline int modify_ftrace_direct(unsigned long ip, - unsigned long old_addr, unsigned long new_addr) -{ - return -ENOTSUPP; -} -static inline struct ftrace_direct_func *ftrace_find_direct_func(unsigned = long addr) -{ - return NULL; -} -static inline int ftrace_modify_direct_caller(struct ftrace_func_entry *en= try, - struct dyn_ftrace *rec, - unsigned long old_addr, - unsigned long new_addr) -{ - return -ENODEV; -} static inline unsigned long ftrace_find_rec_direct(unsigned long ip) { return 0; diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 98434196c6a1..fbc9abfa1a3e 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -2591,20 +2591,6 @@ static void call_direct_funcs(unsigned long ip, unsi= gned long pip, =20 arch_ftrace_set_direct_caller(fregs, addr); } - -static struct ftrace_ops direct_ops =3D { - .func =3D call_direct_funcs, - .flags =3D FTRACE_OPS_FL_DIRECT | FTRACE_OPS_FL_SAVE_REGS - | FTRACE_OPS_FL_PERMANENT, - /* - * By declaring the main trampoline as this trampoline - * it will never have one allocated for it. Allocated - * trampolines should not call direct functions. - * The direct_ops should only be called by the builtin - * ftrace_regs_caller trampoline. - */ - .trampoline =3D FTRACE_REGS_ADDR, -}; #endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */ =20 /** @@ -5301,387 +5287,8 @@ struct ftrace_direct_func { =20 static LIST_HEAD(ftrace_direct_funcs); =20 -/** - * ftrace_find_direct_func - test an address if it is a registered direct = caller - * @addr: The address of a registered direct caller - * - * This searches to see if a ftrace direct caller has been registered - * at a specific address, and if so, it returns a descriptor for it. - * - * This can be used by architecture code to see if an address is - * a direct caller (trampoline) attached to a fentry/mcount location. - * This is useful for the function_graph tracer, as it may need to - * do adjustments if it traced a location that also has a direct - * trampoline attached to it. - */ -struct ftrace_direct_func *ftrace_find_direct_func(unsigned long addr) -{ - struct ftrace_direct_func *entry; - bool found =3D false; - - /* May be called by fgraph trampoline (protected by rcu tasks) */ - list_for_each_entry_rcu(entry, &ftrace_direct_funcs, next) { - if (entry->addr =3D=3D addr) { - found =3D true; - break; - } - } - if (found) - return entry; - - return NULL; -} - -static struct ftrace_direct_func *ftrace_alloc_direct_func(unsigned long a= ddr) -{ - struct ftrace_direct_func *direct; - - direct =3D kmalloc(sizeof(*direct), GFP_KERNEL); - if (!direct) - return NULL; - direct->addr =3D addr; - direct->count =3D 0; - list_add_rcu(&direct->next, &ftrace_direct_funcs); - ftrace_direct_func_count++; - return direct; -} - static int register_ftrace_function_nolock(struct ftrace_ops *ops); =20 -/** - * register_ftrace_direct - Call a custom trampoline directly - * @ip: The address of the nop at the beginning of a function - * @addr: The address of the trampoline to call at @ip - * - * This is used to connect a direct call from the nop location (@ip) - * at the start of ftrace traced functions. The location that it calls - * (@addr) must be able to handle a direct call, and save the parameters - * of the function being traced, and restore them (or inject new ones - * if needed), before returning. - * - * Returns: - * 0 on success - * -EBUSY - Another direct function is already attached (there can be onl= y one) - * -ENODEV - @ip does not point to a ftrace nop location (or not supporte= d) - * -ENOMEM - There was an allocation failure. - */ -int register_ftrace_direct(unsigned long ip, unsigned long addr) -{ - struct ftrace_direct_func *direct; - struct ftrace_func_entry *entry; - struct ftrace_hash *free_hash =3D NULL; - struct dyn_ftrace *rec; - int ret =3D -ENODEV; - - mutex_lock(&direct_mutex); - - ip =3D ftrace_location(ip); - if (!ip) - goto out_unlock; - - /* See if there's a direct function at @ip already */ - ret =3D -EBUSY; - if (ftrace_find_rec_direct(ip)) - goto out_unlock; - - ret =3D -ENODEV; - rec =3D lookup_rec(ip, ip); - if (!rec) - goto out_unlock; - - /* - * Check if the rec says it has a direct call but we didn't - * find one earlier? - */ - if (WARN_ON(rec->flags & FTRACE_FL_DIRECT)) - goto out_unlock; - - /* Make sure the ip points to the exact record */ - if (ip !=3D rec->ip) { - ip =3D rec->ip; - /* Need to check this ip for a direct. */ - if (ftrace_find_rec_direct(ip)) - goto out_unlock; - } - - ret =3D -ENOMEM; - direct =3D ftrace_find_direct_func(addr); - if (!direct) { - direct =3D ftrace_alloc_direct_func(addr); - if (!direct) - goto out_unlock; - } - - entry =3D ftrace_add_rec_direct(ip, addr, &free_hash); - if (!entry) - goto out_unlock; - - ret =3D ftrace_set_filter_ip(&direct_ops, ip, 0, 0); - - if (!ret && !(direct_ops.flags & FTRACE_OPS_FL_ENABLED)) { - ret =3D register_ftrace_function_nolock(&direct_ops); - if (ret) - ftrace_set_filter_ip(&direct_ops, ip, 1, 0); - } - - if (ret) { - remove_hash_entry(direct_functions, entry); - kfree(entry); - if (!direct->count) { - list_del_rcu(&direct->next); - synchronize_rcu_tasks(); - kfree(direct); - if (free_hash) - free_ftrace_hash(free_hash); - free_hash =3D NULL; - ftrace_direct_func_count--; - } - } else { - direct->count++; - } - out_unlock: - mutex_unlock(&direct_mutex); - - if (free_hash) { - synchronize_rcu_tasks(); - free_ftrace_hash(free_hash); - } - - return ret; -} -EXPORT_SYMBOL_GPL(register_ftrace_direct); - -static struct ftrace_func_entry *find_direct_entry(unsigned long *ip, - struct dyn_ftrace **recp) -{ - struct ftrace_func_entry *entry; - struct dyn_ftrace *rec; - - rec =3D lookup_rec(*ip, *ip); - if (!rec) - return NULL; - - entry =3D __ftrace_lookup_ip(direct_functions, rec->ip); - if (!entry) { - WARN_ON(rec->flags & FTRACE_FL_DIRECT); - return NULL; - } - - WARN_ON(!(rec->flags & FTRACE_FL_DIRECT)); - - /* Passed in ip just needs to be on the call site */ - *ip =3D rec->ip; - - if (recp) - *recp =3D rec; - - return entry; -} - -int unregister_ftrace_direct(unsigned long ip, unsigned long addr) -{ - struct ftrace_direct_func *direct; - struct ftrace_func_entry *entry; - struct ftrace_hash *hash; - int ret =3D -ENODEV; - - mutex_lock(&direct_mutex); - - ip =3D ftrace_location(ip); - if (!ip) - goto out_unlock; - - entry =3D find_direct_entry(&ip, NULL); - if (!entry) - goto out_unlock; - - hash =3D direct_ops.func_hash->filter_hash; - if (hash->count =3D=3D 1) - unregister_ftrace_function(&direct_ops); - - ret =3D ftrace_set_filter_ip(&direct_ops, ip, 1, 0); - - WARN_ON(ret); - - remove_hash_entry(direct_functions, entry); - - direct =3D ftrace_find_direct_func(addr); - if (!WARN_ON(!direct)) { - /* This is the good path (see the ! before WARN) */ - direct->count--; - WARN_ON(direct->count < 0); - if (!direct->count) { - list_del_rcu(&direct->next); - synchronize_rcu_tasks(); - kfree(direct); - kfree(entry); - ftrace_direct_func_count--; - } - } - out_unlock: - mutex_unlock(&direct_mutex); - - return ret; -} -EXPORT_SYMBOL_GPL(unregister_ftrace_direct); - -static struct ftrace_ops stub_ops =3D { - .func =3D ftrace_stub, -}; - -/** - * ftrace_modify_direct_caller - modify ftrace nop directly - * @entry: The ftrace hash entry of the direct helper for @rec - * @rec: The record representing the function site to patch - * @old_addr: The location that the site at @rec->ip currently calls - * @new_addr: The location that the site at @rec->ip should call - * - * An architecture may overwrite this function to optimize the - * changing of the direct callback on an ftrace nop location. - * This is called with the ftrace_lock mutex held, and no other - * ftrace callbacks are on the associated record (@rec). Thus, - * it is safe to modify the ftrace record, where it should be - * currently calling @old_addr directly, to call @new_addr. - * - * This is called with direct_mutex locked. - * - * Safety checks should be made to make sure that the code at - * @rec->ip is currently calling @old_addr. And this must - * also update entry->direct to @new_addr. - */ -int __weak ftrace_modify_direct_caller(struct ftrace_func_entry *entry, - struct dyn_ftrace *rec, - unsigned long old_addr, - unsigned long new_addr) -{ - unsigned long ip =3D rec->ip; - int ret; - - lockdep_assert_held(&direct_mutex); - - /* - * The ftrace_lock was used to determine if the record - * had more than one registered user to it. If it did, - * we needed to prevent that from changing to do the quick - * switch. But if it did not (only a direct caller was attached) - * then this function is called. But this function can deal - * with attached callers to the rec that we care about, and - * since this function uses standard ftrace calls that take - * the ftrace_lock mutex, we need to release it. - */ - mutex_unlock(&ftrace_lock); - - /* - * By setting a stub function at the same address, we force - * the code to call the iterator and the direct_ops helper. - * This means that @ip does not call the direct call, and - * we can simply modify it. - */ - ret =3D ftrace_set_filter_ip(&stub_ops, ip, 0, 0); - if (ret) - goto out_lock; - - ret =3D register_ftrace_function_nolock(&stub_ops); - if (ret) { - ftrace_set_filter_ip(&stub_ops, ip, 1, 0); - goto out_lock; - } - - entry->direct =3D new_addr; - - /* - * By removing the stub, we put back the direct call, calling - * the @new_addr. - */ - unregister_ftrace_function(&stub_ops); - ftrace_set_filter_ip(&stub_ops, ip, 1, 0); - - out_lock: - mutex_lock(&ftrace_lock); - - return ret; -} - -/** - * modify_ftrace_direct - Modify an existing direct call to call something= else - * @ip: The instruction pointer to modify - * @old_addr: The address that the current @ip calls directly - * @new_addr: The address that the @ip should call - * - * This modifies a ftrace direct caller at an instruction pointer without - * having to disable it first. The direct call will switch over to the - * @new_addr without missing anything. - * - * Returns: zero on success. Non zero on error, which includes: - * -ENODEV : the @ip given has no direct caller attached - * -EINVAL : the @old_addr does not match the current direct caller - */ -int modify_ftrace_direct(unsigned long ip, - unsigned long old_addr, unsigned long new_addr) -{ - struct ftrace_direct_func *direct, *new_direct =3D NULL; - struct ftrace_func_entry *entry; - struct dyn_ftrace *rec; - int ret =3D -ENODEV; - - mutex_lock(&direct_mutex); - - mutex_lock(&ftrace_lock); - - ip =3D ftrace_location(ip); - if (!ip) - goto out_unlock; - - entry =3D find_direct_entry(&ip, &rec); - if (!entry) - goto out_unlock; - - ret =3D -EINVAL; - if (entry->direct !=3D old_addr) - goto out_unlock; - - direct =3D ftrace_find_direct_func(old_addr); - if (WARN_ON(!direct)) - goto out_unlock; - if (direct->count > 1) { - ret =3D -ENOMEM; - new_direct =3D ftrace_alloc_direct_func(new_addr); - if (!new_direct) - goto out_unlock; - direct->count--; - new_direct->count++; - } else { - direct->addr =3D new_addr; - } - - /* - * If there's no other ftrace callback on the rec->ip location, - * then it can be changed directly by the architecture. - * If there is another caller, then we just need to change the - * direct caller helper to point to @new_addr. - */ - if (ftrace_rec_count(rec) =3D=3D 1) { - ret =3D ftrace_modify_direct_caller(entry, rec, old_addr, new_addr); - } else { - entry->direct =3D new_addr; - ret =3D 0; - } - - if (unlikely(ret && new_direct)) { - direct->count++; - list_del_rcu(&new_direct->next); - synchronize_rcu_tasks(); - kfree(new_direct); - ftrace_direct_func_count--; - } - - out_unlock: - mutex_unlock(&ftrace_lock); - mutex_unlock(&direct_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(modify_ftrace_direct); - #define MULTI_FLAGS (FTRACE_OPS_FL_DIRECT | FTRACE_OPS_FL_SAVE_REGS) =20 static int check_direct_multi(struct ftrace_ops *ops) --=20 2.39.1 From nobody Sun Feb 8 05:41:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A8A49C6FD1F for ; Wed, 22 Mar 2023 18:43:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230236AbjCVSnl (ORCPT ); Wed, 22 Mar 2023 14:43:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56032 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229928AbjCVSni (ORCPT ); Wed, 22 Mar 2023 14:43:38 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9525E298C9 for ; Wed, 22 Mar 2023 11:43:36 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 25FE362276 for ; Wed, 22 Mar 2023 18:43:36 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 696FCC433AA; Wed, 22 Mar 2023 18:43:35 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.96) (envelope-from ) id 1pf3Qs-000pXz-1f; Wed, 22 Mar 2023 14:43:34 -0400 Message-ID: <20230322184334.334868243@goodmis.org> User-Agent: quilt/0.66 Date: Wed, 22 Mar 2023 14:42:43 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Andrew Morton , Florent Revest , Jiri Olsa Subject: [for-next][PATCH 04/11] ftrace: Rename _ftrace_direct_multi APIs to _ftrace_direct APIs References: <20230322184239.594953818@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Florent Revest Now that the original _ftrace_direct APIs are gone, the "_multi" suffixes only add confusion. Link: https://lkml.kernel.org/r/20230321140424.345218-5-revest@chromium.org Signed-off-by: Florent Revest Acked-by: Mark Rutland Tested-by: Mark Rutland Acked-by: Jiri Olsa Signed-off-by: Steven Rostedt (Google) --- include/linux/ftrace.h | 20 ++++++------ kernel/bpf/trampoline.c | 12 ++++---- kernel/trace/ftrace.c | 34 ++++++++++----------- kernel/trace/trace_selftest.c | 9 +++--- samples/Kconfig | 2 +- samples/ftrace/ftrace-direct-modify.c | 8 ++--- samples/ftrace/ftrace-direct-multi-modify.c | 8 ++--- samples/ftrace/ftrace-direct-multi.c | 4 +-- samples/ftrace/ftrace-direct-too.c | 6 ++-- samples/ftrace/ftrace-direct.c | 6 ++-- 10 files changed, 55 insertions(+), 54 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 2f400c9f0787..abee60865fc7 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -398,11 +398,11 @@ struct ftrace_func_entry { #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS extern int ftrace_direct_func_count; unsigned long ftrace_find_rec_direct(unsigned long ip); -int register_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long add= r); -int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long a= ddr, - bool free_filters); -int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr); -int modify_ftrace_direct_multi_nolock(struct ftrace_ops *ops, unsigned lon= g addr); +int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr); +int unregister_ftrace_direct(struct ftrace_ops *ops, unsigned long addr, + bool free_filters); +int modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr); +int modify_ftrace_direct_nolock(struct ftrace_ops *ops, unsigned long addr= ); =20 #else struct ftrace_ops; @@ -411,20 +411,20 @@ static inline unsigned long ftrace_find_rec_direct(un= signed long ip) { return 0; } -static inline int register_ftrace_direct_multi(struct ftrace_ops *ops, uns= igned long addr) +static inline int register_ftrace_direct(struct ftrace_ops *ops, unsigned = long addr) { return -ENODEV; } -static inline int unregister_ftrace_direct_multi(struct ftrace_ops *ops, u= nsigned long addr, - bool free_filters) +static inline int unregister_ftrace_direct(struct ftrace_ops *ops, unsigne= d long addr, + bool free_filters) { return -ENODEV; } -static inline int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsig= ned long addr) +static inline int modify_ftrace_direct(struct ftrace_ops *ops, unsigned lo= ng addr) { return -ENODEV; } -static inline int modify_ftrace_direct_multi_nolock(struct ftrace_ops *ops= , unsigned long addr) +static inline int modify_ftrace_direct_nolock(struct ftrace_ops *ops, unsi= gned long addr) { return -ENODEV; } diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c index 88bc23f1e10a..a14d0af534b3 100644 --- a/kernel/bpf/trampoline.c +++ b/kernel/bpf/trampoline.c @@ -45,8 +45,8 @@ static int bpf_tramp_ftrace_ops_func(struct ftrace_ops *o= ps, enum ftrace_ops_cmd lockdep_assert_held_once(&tr->mutex); =20 /* Instead of updating the trampoline here, we propagate - * -EAGAIN to register_ftrace_direct_multi(). Then we can - * retry register_ftrace_direct_multi() after updating the + * -EAGAIN to register_ftrace_direct(). Then we can + * retry register_ftrace_direct() after updating the * trampoline. */ if ((tr->flags & BPF_TRAMP_F_CALL_ORIG) && @@ -198,7 +198,7 @@ static int unregister_fentry(struct bpf_trampoline *tr,= void *old_addr) int ret; =20 if (tr->func.ftrace_managed) - ret =3D unregister_ftrace_direct_multi(tr->fops, (long)old_addr, false); + ret =3D unregister_ftrace_direct(tr->fops, (long)old_addr, false); else ret =3D bpf_arch_text_poke(ip, BPF_MOD_CALL, old_addr, NULL); =20 @@ -215,9 +215,9 @@ static int modify_fentry(struct bpf_trampoline *tr, voi= d *old_addr, void *new_ad =20 if (tr->func.ftrace_managed) { if (lock_direct_mutex) - ret =3D modify_ftrace_direct_multi(tr->fops, (long)new_addr); + ret =3D modify_ftrace_direct(tr->fops, (long)new_addr); else - ret =3D modify_ftrace_direct_multi_nolock(tr->fops, (long)new_addr); + ret =3D modify_ftrace_direct_nolock(tr->fops, (long)new_addr); } else { ret =3D bpf_arch_text_poke(ip, BPF_MOD_CALL, old_addr, new_addr); } @@ -243,7 +243,7 @@ static int register_fentry(struct bpf_trampoline *tr, v= oid *new_addr) =20 if (tr->func.ftrace_managed) { ftrace_set_filter_ip(tr->fops, (unsigned long)ip, 0, 1); - ret =3D register_ftrace_direct_multi(tr->fops, (long)new_addr); + ret =3D register_ftrace_direct(tr->fops, (long)new_addr); } else { ret =3D bpf_arch_text_poke(ip, BPF_MOD_CALL, NULL, new_addr); } diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index fbc9abfa1a3e..845c4012630f 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -5318,7 +5318,7 @@ static void remove_direct_functions_hash(struct ftrac= e_hash *hash, unsigned long } =20 /** - * register_ftrace_direct_multi - Call a custom trampoline directly + * register_ftrace_direct - Call a custom trampoline directly * for multiple functions registered in @ops * @ops: The address of the struct ftrace_ops object * @addr: The address of the trampoline to call at @ops functions @@ -5339,7 +5339,7 @@ static void remove_direct_functions_hash(struct ftrac= e_hash *hash, unsigned long * -ENODEV - @ip does not point to a ftrace nop location (or not support= ed) * -ENOMEM - There was an allocation failure. */ -int register_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long add= r) +int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) { struct ftrace_hash *hash, *free_hash =3D NULL; struct ftrace_func_entry *entry, *new; @@ -5397,11 +5397,11 @@ int register_ftrace_direct_multi(struct ftrace_ops = *ops, unsigned long addr) } return err; } -EXPORT_SYMBOL_GPL(register_ftrace_direct_multi); +EXPORT_SYMBOL_GPL(register_ftrace_direct); =20 /** - * unregister_ftrace_direct_multi - Remove calls to custom trampoline - * previously registered by register_ftrace_direct_multi for @ops object. + * unregister_ftrace_direct - Remove calls to custom trampoline + * previously registered by register_ftrace_direct for @ops object. * @ops: The address of the struct ftrace_ops object * * This is used to remove a direct calls to @addr from the nop locations @@ -5412,8 +5412,8 @@ EXPORT_SYMBOL_GPL(register_ftrace_direct_multi); * 0 on success * -EINVAL - The @ops object was not properly registered. */ -int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long a= ddr, - bool free_filters) +int unregister_ftrace_direct(struct ftrace_ops *ops, unsigned long addr, + bool free_filters) { struct ftrace_hash *hash =3D ops->func_hash->filter_hash; int err; @@ -5436,10 +5436,10 @@ int unregister_ftrace_direct_multi(struct ftrace_op= s *ops, unsigned long addr, ftrace_free_filter(ops); return err; } -EXPORT_SYMBOL_GPL(unregister_ftrace_direct_multi); +EXPORT_SYMBOL_GPL(unregister_ftrace_direct); =20 static int -__modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr) +__modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) { struct ftrace_hash *hash; struct ftrace_func_entry *entry, *iter; @@ -5486,7 +5486,7 @@ __modify_ftrace_direct_multi(struct ftrace_ops *ops, = unsigned long addr) } =20 /** - * modify_ftrace_direct_multi_nolock - Modify an existing direct 'multi' c= all + * modify_ftrace_direct_nolock - Modify an existing direct 'multi' call * to call something else * @ops: The address of the struct ftrace_ops object * @addr: The address of the new trampoline to call at @ops functions @@ -5503,19 +5503,19 @@ __modify_ftrace_direct_multi(struct ftrace_ops *ops= , unsigned long addr) * Returns: zero on success. Non zero on error, which includes: * -EINVAL - The @ops object was not properly registered. */ -int modify_ftrace_direct_multi_nolock(struct ftrace_ops *ops, unsigned lon= g addr) +int modify_ftrace_direct_nolock(struct ftrace_ops *ops, unsigned long addr) { if (check_direct_multi(ops)) return -EINVAL; if (!(ops->flags & FTRACE_OPS_FL_ENABLED)) return -EINVAL; =20 - return __modify_ftrace_direct_multi(ops, addr); + return __modify_ftrace_direct(ops, addr); } -EXPORT_SYMBOL_GPL(modify_ftrace_direct_multi_nolock); +EXPORT_SYMBOL_GPL(modify_ftrace_direct_nolock); =20 /** - * modify_ftrace_direct_multi - Modify an existing direct 'multi' call + * modify_ftrace_direct - Modify an existing direct 'multi' call * to call something else * @ops: The address of the struct ftrace_ops object * @addr: The address of the new trampoline to call at @ops functions @@ -5529,7 +5529,7 @@ EXPORT_SYMBOL_GPL(modify_ftrace_direct_multi_nolock); * Returns: zero on success. Non zero on error, which includes: * -EINVAL - The @ops object was not properly registered. */ -int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr) +int modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) { int err; =20 @@ -5539,11 +5539,11 @@ int modify_ftrace_direct_multi(struct ftrace_ops *o= ps, unsigned long addr) return -EINVAL; =20 mutex_lock(&direct_mutex); - err =3D __modify_ftrace_direct_multi(ops, addr); + err =3D __modify_ftrace_direct(ops, addr); mutex_unlock(&direct_mutex); return err; } -EXPORT_SYMBOL_GPL(modify_ftrace_direct_multi); +EXPORT_SYMBOL_GPL(modify_ftrace_direct); #endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */ =20 /** diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 9ce80b3ad06d..84cd7ba31d27 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -872,7 +872,8 @@ trace_selftest_startup_function_graph(struct tracer *tr= ace, * and make sure we get graph trace. */ ftrace_set_filter_ip(&direct, (unsigned long)DYN_FTRACE_TEST_NAME, 0, 0); - ret =3D register_ftrace_direct_multi(&direct, (unsigned long)trace_direct= _tramp); + ret =3D register_ftrace_direct(&direct, + (unsigned long)trace_direct_tramp); if (ret) goto out; =20 @@ -892,9 +893,9 @@ trace_selftest_startup_function_graph(struct tracer *tr= ace, =20 unregister_ftrace_graph(&fgraph_ops); =20 - ret =3D unregister_ftrace_direct_multi(&direct, - (unsigned long) trace_direct_tramp, - true); + ret =3D unregister_ftrace_direct(&direct, + (unsigned long) trace_direct_tramp, + true); if (ret) goto out; =20 diff --git a/samples/Kconfig b/samples/Kconfig index 30ef8bd48ba3..fd24daa99f34 100644 --- a/samples/Kconfig +++ b/samples/Kconfig @@ -38,7 +38,7 @@ config SAMPLE_FTRACE_DIRECT that hooks to wake_up_process and prints the parameters. =20 config SAMPLE_FTRACE_DIRECT_MULTI - tristate "Build register_ftrace_direct_multi() example" + tristate "Build register_ftrace_direct() on multiple ips example" depends on DYNAMIC_FTRACE_WITH_DIRECT_CALLS && m depends on HAVE_SAMPLE_FTRACE_DIRECT_MULTI help diff --git a/samples/ftrace/ftrace-direct-modify.c b/samples/ftrace/ftrace-= direct-modify.c index f01ac74bac10..25fba66f61c0 100644 --- a/samples/ftrace/ftrace-direct-modify.c +++ b/samples/ftrace/ftrace-direct-modify.c @@ -116,7 +116,7 @@ static int simple_thread(void *arg) if (ret) continue; t ^=3D 1; - ret =3D modify_ftrace_direct_multi(&direct, tramps[t]); + ret =3D modify_ftrace_direct(&direct, tramps[t]); if (!ret) my_tramp =3D tramps[t]; WARN_ON_ONCE(ret); @@ -132,7 +132,7 @@ static int __init ftrace_direct_init(void) int ret; =20 ftrace_set_filter_ip(&direct, (unsigned long) my_ip, 0, 0); - ret =3D register_ftrace_direct_multi(&direct, my_tramp); + ret =3D register_ftrace_direct(&direct, my_tramp); =20 if (!ret) simple_tsk =3D kthread_run(simple_thread, NULL, "event-sample-fn"); @@ -142,12 +142,12 @@ static int __init ftrace_direct_init(void) static void __exit ftrace_direct_exit(void) { kthread_stop(simple_tsk); - unregister_ftrace_direct_multi(&direct, my_tramp, true); + unregister_ftrace_direct(&direct, my_tramp, true); } =20 module_init(ftrace_direct_init); module_exit(ftrace_direct_exit); =20 MODULE_AUTHOR("Steven Rostedt"); -MODULE_DESCRIPTION("Example use case of using modify_ftrace_direct_multi()= "); +MODULE_DESCRIPTION("Example use case of using modify_ftrace_direct()"); MODULE_LICENSE("GPL"); diff --git a/samples/ftrace/ftrace-direct-multi-modify.c b/samples/ftrace/f= trace-direct-multi-modify.c index 196b43971cb5..f72623899602 100644 --- a/samples/ftrace/ftrace-direct-multi-modify.c +++ b/samples/ftrace/ftrace-direct-multi-modify.c @@ -123,7 +123,7 @@ static int simple_thread(void *arg) if (ret) continue; t ^=3D 1; - ret =3D modify_ftrace_direct_multi(&direct, tramps[t]); + ret =3D modify_ftrace_direct(&direct, tramps[t]); if (!ret) my_tramp =3D tramps[t]; WARN_ON_ONCE(ret); @@ -141,7 +141,7 @@ static int __init ftrace_direct_multi_init(void) ftrace_set_filter_ip(&direct, (unsigned long) wake_up_process, 0, 0); ftrace_set_filter_ip(&direct, (unsigned long) schedule, 0, 0); =20 - ret =3D register_ftrace_direct_multi(&direct, my_tramp); + ret =3D register_ftrace_direct(&direct, my_tramp); =20 if (!ret) simple_tsk =3D kthread_run(simple_thread, NULL, "event-sample-fn"); @@ -151,12 +151,12 @@ static int __init ftrace_direct_multi_init(void) static void __exit ftrace_direct_multi_exit(void) { kthread_stop(simple_tsk); - unregister_ftrace_direct_multi(&direct, my_tramp, true); + unregister_ftrace_direct(&direct, my_tramp, true); } =20 module_init(ftrace_direct_multi_init); module_exit(ftrace_direct_multi_exit); =20 MODULE_AUTHOR("Jiri Olsa"); -MODULE_DESCRIPTION("Example use case of using modify_ftrace_direct_multi()= "); +MODULE_DESCRIPTION("Example use case of using modify_ftrace_direct()"); MODULE_LICENSE("GPL"); diff --git a/samples/ftrace/ftrace-direct-multi.c b/samples/ftrace/ftrace-d= irect-multi.c index ea0e88ee5e43..1547c2c6be02 100644 --- a/samples/ftrace/ftrace-direct-multi.c +++ b/samples/ftrace/ftrace-direct-multi.c @@ -73,12 +73,12 @@ static int __init ftrace_direct_multi_init(void) ftrace_set_filter_ip(&direct, (unsigned long) wake_up_process, 0, 0); ftrace_set_filter_ip(&direct, (unsigned long) schedule, 0, 0); =20 - return register_ftrace_direct_multi(&direct, (unsigned long) my_tramp); + return register_ftrace_direct(&direct, (unsigned long) my_tramp); } =20 static void __exit ftrace_direct_multi_exit(void) { - unregister_ftrace_direct_multi(&direct, (unsigned long) my_tramp, true); + unregister_ftrace_direct(&direct, (unsigned long) my_tramp, true); } =20 module_init(ftrace_direct_multi_init); diff --git a/samples/ftrace/ftrace-direct-too.c b/samples/ftrace/ftrace-dir= ect-too.c index 05c3585ac15e..f28e7b99840f 100644 --- a/samples/ftrace/ftrace-direct-too.c +++ b/samples/ftrace/ftrace-direct-too.c @@ -76,17 +76,17 @@ static int __init ftrace_direct_init(void) { ftrace_set_filter_ip(&direct, (unsigned long) handle_mm_fault, 0, 0); =20 - return register_ftrace_direct_multi(&direct, (unsigned long) my_tramp); + return register_ftrace_direct(&direct, (unsigned long) my_tramp); } =20 static void __exit ftrace_direct_exit(void) { - unregister_ftrace_direct_multi(&direct, (unsigned long)my_tramp, true); + unregister_ftrace_direct(&direct, (unsigned long)my_tramp, true); } =20 module_init(ftrace_direct_init); module_exit(ftrace_direct_exit); =20 MODULE_AUTHOR("Steven Rostedt"); -MODULE_DESCRIPTION("Another example use case of using register_ftrace_dire= ct_multi()"); +MODULE_DESCRIPTION("Another example use case of using register_ftrace_dire= ct()"); MODULE_LICENSE("GPL"); diff --git a/samples/ftrace/ftrace-direct.c b/samples/ftrace/ftrace-direct.c index 42ec9e39453b..d81a9473b585 100644 --- a/samples/ftrace/ftrace-direct.c +++ b/samples/ftrace/ftrace-direct.c @@ -69,17 +69,17 @@ static int __init ftrace_direct_init(void) { ftrace_set_filter_ip(&direct, (unsigned long) wake_up_process, 0, 0); =20 - return register_ftrace_direct_multi(&direct, (unsigned long) my_tramp); + return register_ftrace_direct(&direct, (unsigned long) my_tramp); } =20 static void __exit ftrace_direct_exit(void) { - unregister_ftrace_direct_multi(&direct, (unsigned long)my_tramp, true); + unregister_ftrace_direct(&direct, (unsigned long)my_tramp, true); } =20 module_init(ftrace_direct_init); module_exit(ftrace_direct_exit); =20 MODULE_AUTHOR("Steven Rostedt"); -MODULE_DESCRIPTION("Example use case of using register_ftrace_direct_multi= ()"); +MODULE_DESCRIPTION("Example use case of using register_ftrace_direct()"); MODULE_LICENSE("GPL"); --=20 2.39.1 From nobody Sun Feb 8 05:41:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 110CCC6FD1C for ; Wed, 22 Mar 2023 18:44:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230491AbjCVSn6 (ORCPT ); Wed, 22 Mar 2023 14:43:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56150 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230120AbjCVSnj (ORCPT ); Wed, 22 Mar 2023 14:43:39 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3CFB22A162 for ; Wed, 22 Mar 2023 11:43:38 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id D5D50B81DAE for ; Wed, 22 Mar 2023 18:43:36 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A02E2C433AC; Wed, 22 Mar 2023 18:43:35 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.96) (envelope-from ) id 1pf3Qs-000pYX-2K; Wed, 22 Mar 2023 14:43:34 -0400 Message-ID: <20230322184334.537784095@goodmis.org> User-Agent: quilt/0.66 Date: Wed, 22 Mar 2023 14:42:44 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Andrew Morton , Florent Revest , Jiri Olsa Subject: [for-next][PATCH 05/11] ftrace: Store direct called addresses in their ops References: <20230322184239.594953818@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Florent Revest 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/20230321140424.345218-6-revest@chromium.org Signed-off-by: Florent Revest Acked-by: Jiri Olsa Signed-off-by: Steven Rostedt (Google) --- include/linux/ftrace.h | 3 +++ kernel/trace/ftrace.c | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index abee60865fc7..6a532dd6789e 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -321,6 +321,9 @@ struct ftrace_ops { unsigned long trampoline_size; struct list_head list; ftrace_ops_func_t ops_func; +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS + unsigned long direct_call; +#endif #endif }; =20 diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 845c4012630f..3bef2abc037a 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -2583,9 +2583,8 @@ ftrace_add_rec_direct(unsigned long ip, unsigned long= addr, static void call_direct_funcs(unsigned long ip, unsigned long pip, struct ftrace_ops *ops, struct ftrace_regs *fregs) { - unsigned long addr; + unsigned long addr =3D READ_ONCE(ops->direct_call); =20 - addr =3D ftrace_find_rec_direct(ip); if (!addr) return; =20 @@ -5381,6 +5380,7 @@ int register_ftrace_direct(struct ftrace_ops *ops, un= signed long addr) ops->func =3D call_direct_funcs; ops->flags =3D MULTI_FLAGS; ops->trampoline =3D FTRACE_REGS_ADDR; + ops->direct_call =3D addr; =20 err =3D register_ftrace_function_nolock(ops); =20 @@ -5455,6 +5455,7 @@ __modify_ftrace_direct(struct ftrace_ops *ops, unsign= ed long addr) /* Enable the tmp_ops to have the same functions as the direct ops */ ftrace_ops_init(&tmp_ops); tmp_ops.func_hash =3D ops->func_hash; + tmp_ops.direct_call =3D addr; =20 err =3D register_ftrace_function_nolock(&tmp_ops); if (err) @@ -5476,6 +5477,8 @@ __modify_ftrace_direct(struct ftrace_ops *ops, unsign= ed long addr) entry->direct =3D addr; } } + /* Prevent store tearing if a trampoline concurrently accesses the value = */ + WRITE_ONCE(ops->direct_call, addr); =20 mutex_unlock(&ftrace_lock); =20 --=20 2.39.1 From nobody Sun Feb 8 05:41:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0B2ABC6FD1C for ; Wed, 22 Mar 2023 18:44:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231181AbjCVSoM (ORCPT ); Wed, 22 Mar 2023 14:44:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56166 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230127AbjCVSnj (ORCPT ); Wed, 22 Mar 2023 14:43:39 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 845702DE50 for ; Wed, 22 Mar 2023 11:43:38 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 2A9E6B81DAA for ; Wed, 22 Mar 2023 18:43:37 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id CA993C4339E; Wed, 22 Mar 2023 18:43:35 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.96) (envelope-from ) id 1pf3Qs-000pZ5-2z; Wed, 22 Mar 2023 14:43:34 -0400 Message-ID: <20230322184334.744106182@goodmis.org> User-Agent: quilt/0.66 Date: Wed, 22 Mar 2023 14:42:45 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Andrew Morton , Florent Revest , Jiri Olsa Subject: [for-next][PATCH 06/11] ftrace: Make DIRECT_CALLS work WITH_ARGS and !WITH_REGS References: <20230322184239.594953818@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Florent Revest Direct called trampolines can be called in two ways: - either from the ftrace callsite. In this case, they do not access any struct ftrace_regs nor pt_regs - Or, if a ftrace ops is also attached, from the end of a ftrace trampoline. In this case, the call_direct_funcs ops is in charge of setting the direct call trampoline's address in a struct ftrace_regs Since: commit 9705bc709604 ("ftrace: pass fregs to arch_ftrace_set_direct_caller()= ") The later case no longer requires a full pt_regs. It only needs a struct ftrace_regs so DIRECT_CALLS can work with both WITH_ARGS or WITH_REGS. With architectures like arm64 already abandoning WITH_REGS in favor of WITH_ARGS, it's important to have DIRECT_CALLS work WITH_ARGS only. Link: https://lkml.kernel.org/r/20230321140424.345218-7-revest@chromium.org Signed-off-by: Florent Revest Co-developed-by: Mark Rutland Signed-off-by: Mark Rutland Acked-by: Jiri Olsa Signed-off-by: Steven Rostedt (Google) --- include/linux/ftrace.h | 6 ++++++ kernel/trace/Kconfig | 2 +- kernel/trace/ftrace.c | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 6a532dd6789e..31f1e1df2af3 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -241,6 +241,12 @@ enum { FTRACE_OPS_FL_DIRECT =3D BIT(17), }; =20 +#ifndef CONFIG_DYNAMIC_FTRACE_WITH_ARGS +#define FTRACE_OPS_FL_SAVE_ARGS FTRACE_OPS_FL_SAVE_= REGS +#else +#define FTRACE_OPS_FL_SAVE_ARGS 0 +#endif + /* * FTRACE_OPS_CMD_* commands allow the ftrace core logic to request changes * to a ftrace_ops. Note, the requests may fail. diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index a856d4a34c67..5b1e7fa41ca8 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -257,7 +257,7 @@ config DYNAMIC_FTRACE_WITH_REGS =20 config DYNAMIC_FTRACE_WITH_DIRECT_CALLS def_bool y - depends on DYNAMIC_FTRACE_WITH_REGS + depends on DYNAMIC_FTRACE_WITH_REGS || DYNAMIC_FTRACE_WITH_ARGS depends on HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS =20 config DYNAMIC_FTRACE_WITH_CALL_OPS diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 3bef2abc037a..3b46dba3f69b 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -5288,7 +5288,7 @@ static LIST_HEAD(ftrace_direct_funcs); =20 static int register_ftrace_function_nolock(struct ftrace_ops *ops); =20 -#define MULTI_FLAGS (FTRACE_OPS_FL_DIRECT | FTRACE_OPS_FL_SAVE_REGS) +#define MULTI_FLAGS (FTRACE_OPS_FL_DIRECT | FTRACE_OPS_FL_SAVE_ARGS) =20 static int check_direct_multi(struct ftrace_ops *ops) { --=20 2.39.1 From nobody Sun Feb 8 05:41:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7FC44C6FD1C for ; Wed, 22 Mar 2023 18:44:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230500AbjCVSoH (ORCPT ); Wed, 22 Mar 2023 14:44:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56146 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230059AbjCVSnj (ORCPT ); Wed, 22 Mar 2023 14:43:39 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BF19F298D2 for ; Wed, 22 Mar 2023 11:43:36 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 5658F6227B for ; Wed, 22 Mar 2023 18:43:36 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0B2CAC43445; Wed, 22 Mar 2023 18:43:36 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.96) (envelope-from ) id 1pf3Qt-000pZf-0P; Wed, 22 Mar 2023 14:43:35 -0400 Message-ID: <20230322184334.946813393@goodmis.org> User-Agent: quilt/0.66 Date: Wed, 22 Mar 2023 14:42:46 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Andrew Morton , Li Huafei , Xu Kuohai , Florent Revest , Jiri Olsa Subject: [for-next][PATCH 07/11] ftrace: selftest: remove broken trace_direct_tramp References: <20230322184239.594953818@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mark Rutland The ftrace selftest code has a trace_direct_tramp() function which it uses as a direct call trampoline. This happens to work on x86, since the direct call's return address is in the usual place, and can be returned to via a RET, but in general the calling convention for direct calls is different from regular function calls, and requires a trampoline written in assembly. On s390, regular function calls place the return address in %r14, and an ftrace patch-site in an instrumented function places the trampoline's return address (which is within the instrumented function) in %r0, preserving the original %r14 value in-place. As a regular C function will return to the address in %r14, using a C function as the trampoline results in the trampoline returning to the caller of the instrumented function, skipping the body of the instrumented function. Note that the s390 issue is not detcted by the ftrace selftest code, as the instrumented function is trivial, and returning back into the caller happens to be equivalent. On arm64, regular function calls place the return address in x30, and an ftrace patch-site in an instrumented function saves this into r9 and places the trampoline's return address (within the instrumented function) in x30. A regular C function will return to the address in x30, but will not restore x9 into x30. Consequently, using a C function as the trampoline results in returning to the trampoline's return address having corrupted x30, such that when the instrumented function returns, it will return back into itself. To avoid future issues in this area, remove the trace_direct_tramp() function, and require that each architecture with direct calls provides a stub trampoline, named ftrace_stub_direct_tramp. This can be written to handle the architecture's trampoline calling convention, and in future could be used elsewhere (e.g. in the ftrace ops sample, to measure the overhead of direct calls), so we may as well always build it in. Link: https://lkml.kernel.org/r/20230321140424.345218-8-revest@chromium.org Signed-off-by: Mark Rutland Cc: Li Huafei Cc: Xu Kuohai Signed-off-by: Florent Revest Acked-by: Jiri Olsa Signed-off-by: Steven Rostedt (Google) --- arch/s390/kernel/mcount.S | 5 +++++ arch/x86/kernel/ftrace_32.S | 5 +++++ arch/x86/kernel/ftrace_64.S | 4 ++++ include/linux/ftrace.h | 2 ++ kernel/trace/trace_selftest.c | 12 ++---------- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S index 43ff91073d2a..6c10da43b538 100644 --- a/arch/s390/kernel/mcount.S +++ b/arch/s390/kernel/mcount.S @@ -32,6 +32,11 @@ ENTRY(ftrace_stub) BR_EX %r14 ENDPROC(ftrace_stub) =20 +SYM_CODE_START(ftrace_stub_direct_tramp) + lgr %r1, %r0 + BR_EX %r1 +SYM_CODE_END(ftrace_stub_direct_tramp) + .macro ftrace_regs_entry, allregs=3D0 stg %r14,(__SF_GPRS+8*8)(%r15) # save traced function caller =20 diff --git a/arch/x86/kernel/ftrace_32.S b/arch/x86/kernel/ftrace_32.S index a0ed0e4a2c0c..0d9a14528176 100644 --- a/arch/x86/kernel/ftrace_32.S +++ b/arch/x86/kernel/ftrace_32.S @@ -163,6 +163,11 @@ SYM_INNER_LABEL(ftrace_regs_call, SYM_L_GLOBAL) jmp .Lftrace_ret SYM_CODE_END(ftrace_regs_caller) =20 +SYM_FUNC_START(ftrace_stub_direct_tramp) + CALL_DEPTH_ACCOUNT + RET +SYM_FUNC_END(ftrace_stub_direct_tramp) + #ifdef CONFIG_FUNCTION_GRAPH_TRACER SYM_CODE_START(ftrace_graph_caller) pushl %eax diff --git a/arch/x86/kernel/ftrace_64.S b/arch/x86/kernel/ftrace_64.S index fb4f1e01b64a..970d8445fdc4 100644 --- a/arch/x86/kernel/ftrace_64.S +++ b/arch/x86/kernel/ftrace_64.S @@ -309,6 +309,10 @@ SYM_INNER_LABEL(ftrace_regs_caller_end, SYM_L_GLOBAL) SYM_FUNC_END(ftrace_regs_caller) STACK_FRAME_NON_STANDARD_FP(ftrace_regs_caller) =20 +SYM_FUNC_START(ftrace_stub_direct_tramp) + CALL_DEPTH_ACCOUNT + RET +SYM_FUNC_END(ftrace_stub_direct_tramp) =20 #else /* ! CONFIG_DYNAMIC_FTRACE */ =20 diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 31f1e1df2af3..931f3d904529 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -413,6 +413,8 @@ int unregister_ftrace_direct(struct ftrace_ops *ops, un= signed long addr, int modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr); int modify_ftrace_direct_nolock(struct ftrace_ops *ops, unsigned long addr= ); =20 +void ftrace_stub_direct_tramp(void); + #else struct ftrace_ops; # define ftrace_direct_func_count 0 diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 84cd7ba31d27..a931d9aaea26 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -786,14 +786,6 @@ static struct fgraph_ops fgraph_ops __initdata =3D { =20 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS static struct ftrace_ops direct; -#ifndef CALL_DEPTH_ACCOUNT -#define CALL_DEPTH_ACCOUNT "" -#endif - -noinline __noclone static void trace_direct_tramp(void) -{ - asm(CALL_DEPTH_ACCOUNT); -} #endif =20 /* @@ -873,7 +865,7 @@ trace_selftest_startup_function_graph(struct tracer *tr= ace, */ ftrace_set_filter_ip(&direct, (unsigned long)DYN_FTRACE_TEST_NAME, 0, 0); ret =3D register_ftrace_direct(&direct, - (unsigned long)trace_direct_tramp); + (unsigned long)ftrace_stub_direct_tramp); if (ret) goto out; =20 @@ -894,7 +886,7 @@ trace_selftest_startup_function_graph(struct tracer *tr= ace, unregister_ftrace_graph(&fgraph_ops); =20 ret =3D unregister_ftrace_direct(&direct, - (unsigned long) trace_direct_tramp, + (unsigned long)ftrace_stub_direct_tramp, true); if (ret) goto out; --=20 2.39.1 From nobody Sun Feb 8 05:41:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 46BA0C6FD1C for ; Wed, 22 Mar 2023 18:43:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230433AbjCVSnx (ORCPT ); Wed, 22 Mar 2023 14:43:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56082 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230022AbjCVSnj (ORCPT ); Wed, 22 Mar 2023 14:43:39 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C6FA9298D6 for ; Wed, 22 Mar 2023 11:43:36 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 64C8B6227E for ; Wed, 22 Mar 2023 18:43:36 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3CF96C433A1; Wed, 22 Mar 2023 18:43:36 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.96) (envelope-from ) id 1pf3Qt-000paE-14; Wed, 22 Mar 2023 14:43:35 -0400 Message-ID: <20230322184335.149101791@goodmis.org> User-Agent: quilt/0.66 Date: Wed, 22 Mar 2023 14:42:47 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Andrew Morton , Uros Bizjak , Mukesh Ojha Subject: [for-next][PATCH 08/11] ring_buffer: Change some static functions to void References: <20230322184239.594953818@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Uros Bizjak The results of some static functions are not used. Change the type of these function to void and remove unnecessary returns. No functional change intended. Link: https://lkml.kernel.org/r/20230305155532.5549-2-ubizjak@gmail.com Signed-off-by: Uros Bizjak Reviewed-by: Masami Hiramatsu Reviewed-by: Mukesh Ojha Signed-off-by: Steven Rostedt (Google) --- kernel/trace/ring_buffer.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index c6f47b6cfd5f..b45915dd67b9 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -1565,15 +1565,12 @@ static void rb_tail_page_update(struct ring_buffer_= per_cpu *cpu_buffer, } } =20 -static int rb_check_bpage(struct ring_buffer_per_cpu *cpu_buffer, +static void rb_check_bpage(struct ring_buffer_per_cpu *cpu_buffer, struct buffer_page *bpage) { unsigned long val =3D (unsigned long)bpage; =20 - if (RB_WARN_ON(cpu_buffer, val & RB_FLAG_MASK)) - return 1; - - return 0; + RB_WARN_ON(cpu_buffer, val & RB_FLAG_MASK); } =20 /** @@ -1583,30 +1580,28 @@ static int rb_check_bpage(struct ring_buffer_per_cp= u *cpu_buffer, * As a safety measure we check to make sure the data pages have not * been corrupted. */ -static int rb_check_pages(struct ring_buffer_per_cpu *cpu_buffer) +static void rb_check_pages(struct ring_buffer_per_cpu *cpu_buffer) { struct list_head *head =3D rb_list_head(cpu_buffer->pages); struct list_head *tmp; =20 if (RB_WARN_ON(cpu_buffer, rb_list_head(rb_list_head(head->next)->prev) !=3D head)) - return -1; + return; =20 if (RB_WARN_ON(cpu_buffer, rb_list_head(rb_list_head(head->prev)->next) !=3D head)) - return -1; + return; =20 for (tmp =3D rb_list_head(head->next); tmp !=3D head; tmp =3D rb_list_hea= d(tmp->next)) { if (RB_WARN_ON(cpu_buffer, rb_list_head(rb_list_head(tmp->next)->prev) !=3D tmp)) - return -1; + return; =20 if (RB_WARN_ON(cpu_buffer, rb_list_head(rb_list_head(tmp->prev)->next) !=3D tmp)) - return -1; + return; } - - return 0; } =20 static int __rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer, @@ -4496,7 +4491,6 @@ rb_update_read_stamp(struct ring_buffer_per_cpu *cpu_= buffer, default: RB_WARN_ON(cpu_buffer, 1); } - return; } =20 static void @@ -4527,7 +4521,6 @@ rb_update_iter_read_stamp(struct ring_buffer_iter *it= er, default: RB_WARN_ON(iter->cpu_buffer, 1); } - return; } =20 static struct buffer_page * @@ -4942,7 +4935,6 @@ rb_reader_unlock(struct ring_buffer_per_cpu *cpu_buff= er, bool locked) { if (likely(locked)) raw_spin_unlock(&cpu_buffer->reader_lock); - return; } =20 /** --=20 2.39.1 From nobody Sun Feb 8 05:41:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D80F1C6FD1F for ; Wed, 22 Mar 2023 18:44:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230401AbjCVSoF (ORCPT ); Wed, 22 Mar 2023 14:44:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56148 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230090AbjCVSnj (ORCPT ); Wed, 22 Mar 2023 14:43:39 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 422D6298DD for ; Wed, 22 Mar 2023 11:43:37 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id A3DAA62281 for ; Wed, 22 Mar 2023 18:43:36 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7C8E7C433D2; Wed, 22 Mar 2023 18:43:36 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.96) (envelope-from ) id 1pf3Qt-000pam-1j; Wed, 22 Mar 2023 14:43:35 -0400 Message-ID: <20230322184335.352033343@goodmis.org> User-Agent: quilt/0.66 Date: Wed, 22 Mar 2023 14:42:48 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Andrew Morton , Uros Bizjak , Mukesh Ojha Subject: [for-next][PATCH 09/11] ring_buffer: Change some static functions to bool References: <20230322184239.594953818@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Uros Bizjak The return values of some functions are of boolean type. Change the type of these function to bool and adjust their return values. Also change type of some internal varibles to bool. No functional change intended. Link: https://lkml.kernel.org/r/20230305155532.5549-3-ubizjak@gmail.com Cc: Masami Hiramatsu Signed-off-by: Uros Bizjak Reviewed-by: Mukesh Ojha Signed-off-by: Steven Rostedt (Google) --- kernel/trace/ring_buffer.c | 47 +++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index b45915dd67b9..93f854433d89 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -163,7 +163,7 @@ enum { #define extended_time(event) \ (event->type_len >=3D RINGBUF_TYPE_TIME_EXTEND) =20 -static inline int rb_null_event(struct ring_buffer_event *event) +static inline bool rb_null_event(struct ring_buffer_event *event) { return event->type_len =3D=3D RINGBUF_TYPE_PADDING && !event->time_delta; } @@ -363,11 +363,9 @@ static void free_buffer_page(struct buffer_page *bpage) /* * We need to fit the time_stamp delta into 27 bits. */ -static inline int test_time_stamp(u64 delta) +static inline bool test_time_stamp(u64 delta) { - if (delta & TS_DELTA_TEST) - return 1; - return 0; + return !!(delta & TS_DELTA_TEST); } =20 #define BUF_PAGE_SIZE (PAGE_SIZE - BUF_PAGE_HDR_SIZE) @@ -696,7 +694,7 @@ rb_time_read_cmpxchg(local_t *l, unsigned long expect, = unsigned long set) return ret =3D=3D expect; } =20 -static int rb_time_cmpxchg(rb_time_t *t, u64 expect, u64 set) +static bool rb_time_cmpxchg(rb_time_t *t, u64 expect, u64 set) { unsigned long cnt, top, bottom, msb; unsigned long cnt2, top2, bottom2, msb2; @@ -1486,7 +1484,7 @@ rb_set_head_page(struct ring_buffer_per_cpu *cpu_buff= er) return NULL; } =20 -static int rb_head_page_replace(struct buffer_page *old, +static bool rb_head_page_replace(struct buffer_page *old, struct buffer_page *new) { unsigned long *ptr =3D (unsigned long *)&old->list.prev->next; @@ -1913,7 +1911,7 @@ static inline unsigned long rb_page_write(struct buff= er_page *bpage) return local_read(&bpage->write) & RB_WRITE_MASK; } =20 -static int +static bool rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_p= ages) { struct list_head *tail_page, *to_remove, *next_page; @@ -2026,12 +2024,13 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buf= fer, unsigned long nr_pages) return nr_removed =3D=3D 0; } =20 -static int +static bool rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer) { struct list_head *pages =3D &cpu_buffer->new_pages; - int retries, success; unsigned long flags; + bool success; + int retries; =20 /* Can be called at early boot up, where interrupts must not been enabled= */ raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); @@ -2050,7 +2049,7 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffe= r) * spinning. */ retries =3D 10; - success =3D 0; + success =3D false; while (retries--) { struct list_head *head_page, *prev_page, *r; struct list_head *last_page, *first_page; @@ -2079,7 +2078,7 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffe= r) * pointer to point to end of list */ head_page->prev =3D last_page; - success =3D 1; + success =3D true; break; } } @@ -2107,7 +2106,7 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffe= r) =20 static void rb_update_pages(struct ring_buffer_per_cpu *cpu_buffer) { - int success; + bool success; =20 if (cpu_buffer->nr_pages_to_update > 0) success =3D rb_insert_pages(cpu_buffer); @@ -2990,7 +2989,7 @@ static u64 rb_time_delta(struct ring_buffer_event *ev= ent) } } =20 -static inline int +static inline bool rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buffer, struct ring_buffer_event *event) { @@ -3011,7 +3010,7 @@ rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buf= fer, delta =3D rb_time_delta(event); =20 if (!rb_time_read(&cpu_buffer->write_stamp, &write_stamp)) - return 0; + return false; =20 /* Make sure the write stamp is read before testing the location */ barrier(); @@ -3024,7 +3023,7 @@ rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buf= fer, /* Something came in, can't discard */ if (!rb_time_cmpxchg(&cpu_buffer->write_stamp, write_stamp, write_stamp - delta)) - return 0; + return false; =20 /* * It's possible that the event time delta is zero @@ -3057,12 +3056,12 @@ rb_try_to_discard(struct ring_buffer_per_cpu *cpu_b= uffer, if (index =3D=3D old_index) { /* update counters */ local_sub(event_length, &cpu_buffer->entries_bytes); - return 1; + return true; } } =20 /* could not discard */ - return 0; + return false; } =20 static void rb_start_commit(struct ring_buffer_per_cpu *cpu_buffer) @@ -3277,7 +3276,7 @@ rb_wakeups(struct trace_buffer *buffer, struct ring_b= uffer_per_cpu *cpu_buffer) * Note: The TRANSITION bit only handles a single transition between conte= xt. */ =20 -static __always_inline int +static __always_inline bool trace_recursive_lock(struct ring_buffer_per_cpu *cpu_buffer) { unsigned int val =3D cpu_buffer->current_context; @@ -3294,14 +3293,14 @@ trace_recursive_lock(struct ring_buffer_per_cpu *cp= u_buffer) bit =3D RB_CTX_TRANSITION; if (val & (1 << (bit + cpu_buffer->nest))) { do_ring_buffer_record_recursion(); - return 1; + return true; } } =20 val |=3D (1 << (bit + cpu_buffer->nest)); cpu_buffer->current_context =3D val; =20 - return 0; + return false; } =20 static __always_inline void @@ -4530,7 +4529,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_bu= ffer) unsigned long overwrite; unsigned long flags; int nr_loops =3D 0; - int ret; + bool ret; =20 local_irq_save(flags); arch_spin_lock(&cpu_buffer->lock); @@ -5405,8 +5404,8 @@ bool ring_buffer_empty(struct trace_buffer *buffer) struct ring_buffer_per_cpu *cpu_buffer; unsigned long flags; bool dolock; + bool ret; int cpu; - int ret; =20 /* yes this is racy, but if you don't like the race, lock the buffer */ for_each_buffer_cpu(buffer, cpu) { @@ -5435,7 +5434,7 @@ bool ring_buffer_empty_cpu(struct trace_buffer *buffe= r, int cpu) struct ring_buffer_per_cpu *cpu_buffer; unsigned long flags; bool dolock; - int ret; + bool ret; =20 if (!cpumask_test_cpu(cpu, buffer->cpumask)) return true; --=20 2.39.1 From nobody Sun Feb 8 05:41:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3DD9BC6FD1F for ; Wed, 22 Mar 2023 18:43:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230443AbjCVSnz (ORCPT ); Wed, 22 Mar 2023 14:43:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56094 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230026AbjCVSnj (ORCPT ); Wed, 22 Mar 2023 14:43:39 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4185C23A75 for ; Wed, 22 Mar 2023 11:43:37 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id BEA3962284 for ; Wed, 22 Mar 2023 18:43:36 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 99F1CC433EF; Wed, 22 Mar 2023 18:43:36 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.96) (envelope-from ) id 1pf3Qt-000pbL-2O; Wed, 22 Mar 2023 14:43:35 -0400 Message-ID: <20230322184335.558195206@goodmis.org> User-Agent: quilt/0.66 Date: Wed, 22 Mar 2023 14:42:49 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Andrew Morton , Uros Bizjak , Mukesh Ojha Subject: [for-next][PATCH 10/11] ring_buffer: Use try_cmpxchg instead of cmpxchg References: <20230322184239.594953818@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Uros Bizjak Use try_cmpxchg instead of cmpxchg (*ptr, old, new) =3D=3D old. x86 CMPXCHG instruction returns success in ZF flag, so this change saves a compare after cmpxchg (and related move instruction in front of cmpxchg). Also, try_cmpxchg implicitly assigns old *ptr value to "old" when cmpxchg fails. There is no need to re-read the value in the loop. No functional change intended. Link: https://lkml.kernel.org/r/20230305155532.5549-4-ubizjak@gmail.com Cc: Masami Hiramatsu Signed-off-by: Uros Bizjak Acked-by: Mukesh Ojha Signed-off-by: Steven Rostedt (Google) --- kernel/trace/ring_buffer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 93f854433d89..2d5c3caff32d 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -4057,10 +4057,10 @@ void ring_buffer_record_off(struct trace_buffer *bu= ffer) unsigned int rd; unsigned int new_rd; =20 + rd =3D atomic_read(&buffer->record_disabled); do { - rd =3D atomic_read(&buffer->record_disabled); new_rd =3D rd | RB_BUFFER_OFF; - } while (atomic_cmpxchg(&buffer->record_disabled, rd, new_rd) !=3D rd); + } while (!atomic_try_cmpxchg(&buffer->record_disabled, &rd, new_rd)); } EXPORT_SYMBOL_GPL(ring_buffer_record_off); =20 @@ -4080,10 +4080,10 @@ void ring_buffer_record_on(struct trace_buffer *buf= fer) unsigned int rd; unsigned int new_rd; =20 + rd =3D atomic_read(&buffer->record_disabled); do { - rd =3D atomic_read(&buffer->record_disabled); new_rd =3D rd & ~RB_BUFFER_OFF; - } while (atomic_cmpxchg(&buffer->record_disabled, rd, new_rd) !=3D rd); + } while (!atomic_try_cmpxchg(&buffer->record_disabled, &rd, new_rd)); } EXPORT_SYMBOL_GPL(ring_buffer_record_on); =20 --=20 2.39.1 From nobody Sun Feb 8 05:41:49 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4627DC6FD1F for ; Wed, 22 Mar 2023 18:44:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231189AbjCVSoP (ORCPT ); Wed, 22 Mar 2023 14:44:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56244 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230214AbjCVSnk (ORCPT ); Wed, 22 Mar 2023 14:43:40 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DE39B2943F for ; Wed, 22 Mar 2023 11:43:38 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 7552962279 for ; Wed, 22 Mar 2023 18:43:38 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E8220C433D2; Wed, 22 Mar 2023 18:43:37 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.96) (envelope-from ) id 1pf3Qt-000pbv-32; Wed, 22 Mar 2023 14:43:35 -0400 Message-ID: <20230322184335.762751069@goodmis.org> User-Agent: quilt/0.66 Date: Wed, 22 Mar 2023 14:42:50 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Andrew Morton , Catalin Marinas , Chris Li Subject: [for-next][PATCH 11/11] ftrace: Show a list of all functions that have ever been enabled References: <20230322184239.594953818@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: "Steven Rostedt (Google)" When debugging a crash that appears to be related to ftrace, but not for sure, it is useful to know if a function was ever enabled by ftrace or not. It could be that a BPF program was attached to it, or possibly a live patch. We are having crashes in the field where this information is not always known. But having ftrace set a flag if a function has ever been attached since boot up helps tremendously in trying to know if a crash had to do with something using ftrace. For analyzing crashes, the use of a kdump image can have access to the flags. When looking at issues where the kernel did not panic, the touched_functions file can simply be used. Link: https://lore.kernel.org/linux-trace-kernel/20230124095653.6fd1640e@ga= ndalf.local.home Cc: Masami Hiramatsu Cc: Catalin Marinas Tested-by: Mark Rutland Tested-by: Chris Li Signed-off-by: Steven Rostedt (Google) --- include/linux/ftrace.h | 5 ++++- kernel/trace/ftrace.c | 51 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 931f3d904529..327046f1278d 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -548,6 +548,7 @@ bool is_ftrace_trampoline(unsigned long addr); * DIRECT - there is a direct function to call * CALL_OPS - the record can use callsite-specific ops * CALL_OPS_EN - the function is set up to use callsite-specific ops + * TOUCHED - A callback was added since boot up * * When a new ftrace_ops is registered and wants a function to save * pt_regs, the rec->flags REGS is set. When the function has been @@ -567,9 +568,10 @@ enum { FTRACE_FL_DIRECT_EN =3D (1UL << 23), FTRACE_FL_CALL_OPS =3D (1UL << 22), FTRACE_FL_CALL_OPS_EN =3D (1UL << 21), + FTRACE_FL_TOUCHED =3D (1UL << 20), }; =20 -#define FTRACE_REF_MAX_SHIFT 21 +#define FTRACE_REF_MAX_SHIFT 20 #define FTRACE_REF_MAX ((1UL << FTRACE_REF_MAX_SHIFT) - 1) =20 #define ftrace_rec_count(rec) ((rec)->flags & FTRACE_REF_MAX) @@ -628,6 +630,7 @@ enum { FTRACE_ITER_PROBE =3D (1 << 4), FTRACE_ITER_MOD =3D (1 << 5), FTRACE_ITER_ENABLED =3D (1 << 6), + FTRACE_ITER_TOUCHED =3D (1 << 7), }; =20 void arch_ftrace_update_code(int command); diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 3b46dba3f69b..db8532a4d5c8 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -45,6 +45,9 @@ #include "trace_output.h" #include "trace_stat.h" =20 +/* Flags that do not get reset */ +#define FTRACE_NOCLEAR_FLAGS (FTRACE_FL_DISABLED | FTRACE_FL_TOUCHED) + #define FTRACE_INVALID_FUNCTION "__ftrace_invalid_address__" =20 #define FTRACE_WARN_ON(cond) \ @@ -2256,7 +2259,7 @@ static int ftrace_check_record(struct dyn_ftrace *rec= , bool enable, bool update) flag ^=3D rec->flags & FTRACE_FL_ENABLED; =20 if (update) { - rec->flags |=3D FTRACE_FL_ENABLED; + rec->flags |=3D FTRACE_FL_ENABLED | FTRACE_FL_TOUCHED; if (flag & FTRACE_FL_REGS) { if (rec->flags & FTRACE_FL_REGS) rec->flags |=3D FTRACE_FL_REGS_EN; @@ -2326,7 +2329,7 @@ static int ftrace_check_record(struct dyn_ftrace *rec= , bool enable, bool update) if (update) { /* If there's no more users, clear all flags */ if (!ftrace_rec_count(rec)) - rec->flags &=3D FTRACE_FL_DISABLED; + rec->flags &=3D FTRACE_NOCLEAR_FLAGS; else /* * Just disable the record, but keep the ops TRAMP @@ -3147,7 +3150,7 @@ int ftrace_shutdown(struct ftrace_ops *ops, int comma= nd) struct dyn_ftrace *rec; =20 do_for_each_ftrace_rec(pg, rec) { - if (FTRACE_WARN_ON_ONCE(rec->flags & ~FTRACE_FL_DISABLED)) + if (FTRACE_WARN_ON_ONCE(rec->flags & ~FTRACE_NOCLEAR_FLAGS)) pr_warn(" %pS flags:%lx\n", (void *)rec->ip, rec->flags); } while_for_each_ftrace_rec(); @@ -3598,7 +3601,10 @@ t_func_next(struct seq_file *m, loff_t *pos) !ftrace_lookup_ip(iter->hash, rec->ip)) || =20 ((iter->flags & FTRACE_ITER_ENABLED) && - !(rec->flags & FTRACE_FL_ENABLED))) { + !(rec->flags & FTRACE_FL_ENABLED)) || + + ((iter->flags & FTRACE_ITER_TOUCHED) && + !(rec->flags & FTRACE_FL_TOUCHED))) { =20 rec =3D NULL; goto retry; @@ -3857,7 +3863,7 @@ static int t_show(struct seq_file *m, void *v) return 0; } =20 - if (iter->flags & FTRACE_ITER_ENABLED) { + if (iter->flags & (FTRACE_ITER_ENABLED | FTRACE_ITER_TOUCHED)) { struct ftrace_ops *ops; =20 seq_printf(m, " (%ld)%s%s%s%s", @@ -3959,6 +3965,31 @@ ftrace_enabled_open(struct inode *inode, struct file= *file) return 0; } =20 +static int +ftrace_touched_open(struct inode *inode, struct file *file) +{ + struct ftrace_iterator *iter; + + /* + * This shows us what functions have ever been enabled + * (traced, direct, patched, etc). Not sure if we want lockdown + * to hide such critical information for an admin. + * Although, perhaps it can show information we don't + * want people to see, but if something had traced + * something, we probably want to know about it. + */ + + iter =3D __seq_open_private(file, &show_ftrace_seq_ops, sizeof(*iter)); + if (!iter) + return -ENOMEM; + + iter->pg =3D ftrace_pages_start; + iter->flags =3D FTRACE_ITER_TOUCHED; + iter->ops =3D &global_ops; + + return 0; +} + /** * ftrace_regex_open - initialize function tracer filter files * @ops: The ftrace_ops that hold the hash filters @@ -5872,6 +5903,13 @@ static const struct file_operations ftrace_enabled_f= ops =3D { .release =3D seq_release_private, }; =20 +static const struct file_operations ftrace_touched_fops =3D { + .open =3D ftrace_touched_open, + .read =3D seq_read, + .llseek =3D seq_lseek, + .release =3D seq_release_private, +}; + static const struct file_operations ftrace_filter_fops =3D { .open =3D ftrace_filter_open, .read =3D seq_read, @@ -6336,6 +6374,9 @@ static __init int ftrace_init_dyn_tracefs(struct dent= ry *d_tracer) trace_create_file("enabled_functions", TRACE_MODE_READ, d_tracer, NULL, &ftrace_enabled_fops); =20 + trace_create_file("touched_functions", TRACE_MODE_READ, + d_tracer, NULL, &ftrace_touched_fops); + ftrace_create_filter_files(&global_ops, d_tracer); =20 #ifdef CONFIG_FUNCTION_GRAPH_TRACER --=20 2.39.1