From mboxrd@z Thu Jan 1 00:00:00 1970 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id AAC63C433F5 for ; Thu, 21 Apr 2022 16:28:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References: Message-ID:Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=5Dl6Vlh9TsyAUZnfJJWWeyCh/hIKQqlDNjEpp0sqZns=; b=n2gETWVYZO6QjA cXbEiCpFuV8y+ZazsfF/1EF0CCCl9nDpbrhklj9LnWr/DpsIbnElsRX3QzV3GJg8fGPdhdgmccCT0 8k9wE5u089v02MXV93iIyPnNzlnQwmGGidYqRqMYi2DMa3ygugIfkR5WaeRUoVCBGE6DdY3oTu9pa pw7CixmAsmbeXTPNGFEMBAGG6vSPYLNUIgYsTrNWsrGTHLIdOd0f4q/6jFBMc8Y1rAaplcfav7kiF 7UXgkX6N4FmkUyOw2cPgNm1r7SCZBd/3swOVkZXHxy5fEmCLXEj/yOByYMyYurz/Mg2uihPeOjFEJ nu30OFjM5tk+uz2j8/9w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nhZep-00EECA-1D; Thu, 21 Apr 2022 16:27:51 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nhZel-00EEB6-LY for linux-arm-kernel@lists.infradead.org; Thu, 21 Apr 2022 16:27:49 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 478C9153B; Thu, 21 Apr 2022 09:27:44 -0700 (PDT) Received: from lakrids (usa-sjc-imap-foss1.foss.arm.com [10.121.207.14]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id CC8E73F73B; Thu, 21 Apr 2022 09:27:42 -0700 (PDT) Date: Thu, 21 Apr 2022 17:27:40 +0100 From: Mark Rutland To: Steven Rostedt Cc: Wang ShaoBo , cj.chengjian@huawei.com, huawei.libin@huawei.com, xiexiuqi@huawei.com, liwei391@huawei.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, catalin.marinas@arm.com, will@kernel.org, zengshun.wu@outlook.com Subject: Re: [RFC PATCH -next v2 3/4] arm64/ftrace: support dynamically allocated trampolines Message-ID: References: <20220316100132.244849-1-bobo.shaobowang@huawei.com> <20220316100132.244849-4-bobo.shaobowang@huawei.com> <20220421100639.03c0d123@gandalf.local.home> <20220421114201.21228eeb@gandalf.local.home> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20220421114201.21228eeb@gandalf.local.home> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220421_092747_845331_68E18478 X-CRM114-Status: GOOD ( 39.42 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On Thu, Apr 21, 2022 at 11:42:01AM -0400, Steven Rostedt wrote: > On Thu, 21 Apr 2022 16:14:13 +0100 > Mark Rutland wrote: > > > > Let's say you have 10 ftrace_ops registered (with bpf and kprobes this can > > > be quite common). But each of these ftrace_ops traces a function (or > > > functions) that are not being traced by the other ftrace_ops. That is, each > > > ftrace_ops has its own unique function(s) that they are tracing. One could > > > be tracing schedule, the other could be tracing ksoftirqd_should_run > > > (whatever). > > > > Ok, so that's when messing around with bpf or kprobes, and not generally > > when using plain old ftrace functionality under /sys/kernel/tracing/ > > (unless that's concurrent with one of the former, as per your other > > reply) ? > > It's any user of the ftrace infrastructure, which includes kprobes, bpf, > perf, function tracing, function graph tracing, and also affects instances. > > > > > > Without this change, because the arch does not support dynamically > > > allocated trampolines, it means that all these ftrace_ops will be > > > registered to the same trampoline. That means, for every function that is > > > traced, it will loop through all 10 of theses ftrace_ops and check their > > > hashes to see if their callback should be called or not. > > > > Sure; I can see how that can be quite expensive. > > > > What I'm trying to figure out is who this matters to and when, since the > > implementation is going to come with a bunch of subtle/fractal > > complexities, and likely a substantial overhead too when enabling or > > disabling tracing of a patch-site. I'd like to understand the trade-offs > > better. > > > > > With dynamically allocated trampolines, each ftrace_ops will have their own > > > trampoline, and that trampoline will be called directly if the function > > > is only being traced by the one ftrace_ops. This is much more efficient. > > > > > > If a function is traced by more than one ftrace_ops, then it falls back to > > > the loop. > > > > I see -- so the dynamic trampoline is just to get the ops? Or is that > > doing additional things? > > It's to get both the ftrace_ops (as that's one of the parameters) as well > as to call the callback directly. Not sure if arm is affected by spectre, > but the "loop" function is filled with indirect function calls, where as > the dynamic trampolines call the callback directly. > > Instead of: > > bl ftrace_caller > > ftrace_caller: > [..] > bl ftrace_ops_list_func > [..] > > > void ftrace_ops_list_func(...) > { > __do_for_each_ftrace_ops(op, ftrace_ops_list) { > if (ftrace_ops_test(op, ip)) // test the hash to see if it > // should trace this > // function. > op->func(...); > } > } > > It does: > > bl dyanmic_tramp > > dynamic_tramp: > [..] > bl func // call the op->func directly! > > > Much more efficient! > > > > > > There might be a middle-ground here where we patch the ftrace_ops > > pointer into a literal pool at the patch-site, which would allow us to > > handle this atomically, and would avoid the issues with out-of-range > > trampolines. > > Have an example of what you are suggesting? We can make the compiler to place 2 NOPs before the function entry point, and 2 NOPs after it using `-fpatchable-function-entry=4,2` (the arguments are ,). On arm64 all instructions are 4 bytes, and we'll use the first two NOPs as an 8-byte literal pool. Ignoring BTI for now, the compiler generates (with some magic labels added here for demonstration): __before_func: NOP NOP func: NOP NOP __remainder_of_func: ... At ftrace_init_nop() time we patch that to: __before_func: // treat the 2 NOPs as an 8-byte literal-pool .quad // see below func: MOV X9, X30 NOP __remainder_of_func: ... When enabling tracing we do __before_func: // patch this with the relevant ops pointer .quad func: MOV X9, X30 BL // common trampoline __remainder_of_func: .. The `BL ` clobbers X30 with __remainder_of_func, so within the trampoline we can find the ops pointer at an offset from X30. On arm64 we can load that directly with something like: LDR , [X30, # -(__remainder_of_func - __before_func)] ... then load the ops->func from that and invoke it (or pass it to a helper which does): // Ignoring the function arguments for this demonstration LDR , [, #OPS_FUNC_OFFSET] BLR That avoids iterating over the list *without* requiring separate trampolines, and allows us to patch the sequence without requiring stop-the-world logic (since arm64 has strong requirements for patching most instructions other than branches and nops). We can initialize the ops pointer to a default ops that does the whole __do_for_each_ftrace_ops() dance. To handle BTI we can have two trampolines, or we can always reserve 3 NOPs before the function so that we can have a consistent offset regardless. Thanks, Mark. _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel