Message ID | 20230201163420.1579014-5-revest@chromium.org |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp379923wrn; Wed, 1 Feb 2023 08:36:31 -0800 (PST) X-Google-Smtp-Source: AK7set82cPVnoaKukaF7AmueCTfe3wn6rigzjFv9EyWKcNSkVn1L/ES+vVc0mjeBa4dJ2uA0TzSZ X-Received: by 2002:aa7:d49a:0:b0:49d:a87f:ba78 with SMTP id b26-20020aa7d49a000000b0049da87fba78mr2653053edr.35.1675269391705; Wed, 01 Feb 2023 08:36:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675269391; cv=none; d=google.com; s=arc-20160816; b=GFBU+66YIyPyNB7s1LyU+cOO8lp/TMivrkvsuYkGfN3pGDI70zcaPcFsna0LnDawKH L1soQqAuTRCG6LTjaTUGODTENTuTM2KP5v5oGvYxX8lWI6snrpKAoGL5cApzuCZ5Nc5P FMbahHFj9B4DNpp98tbl2YfBBbykTytFHyMbXcubmJU/xuvOPwvajPwaO+mtd/eWHSL1 lMMDnmfJOl/sVsIVe3SWddhjdK90eN362jC9JiOFqrup7ymigJKf31xY9sOZwEtOw9M3 9wTvlTRR2Yu5wrKhdBeWp82PGX9m1TRfgTgyGuwuY7F0o0E+KL1IzQXbyRgy6BNj+I0b 3PQQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=p0B1nR0feNzt6iYs1fcCSNwhqATraAQZbyN0DagmRgs=; b=qjOr2tigqxOkdXZHplPbmRxHFFAJHCpt6ZUwJc0nMLtxqB21LU7zC1qOZIqrm0tfm4 NGRmozpFVtvuDgFrBExCrmR/HATXHdfbSkjeh1OFKdk1bkGUcVHIY/FknTZDFP7jAc0P x2aLymRKViDyFaQeqH6FHHOzIpUjcjhRkoQhPpbZlmKcHtdQAyeFMuS8D84ybyrMFkgV mjrewj3zYhO0/YGXPaUicQv/6s80/eJy1BQn23f1oac1VsPR/lLd/KwNttGHCtKOd0gQ oOmE9/IiePT/GX0UFCkR8L1qP05GB28mnWsRzcVpIEYNT1EIGb4yrQ1UTkWXZKaFBQQi zWDA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=jcn6cTs4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e13-20020a056402190d00b004a24475fdd4si15516996edz.376.2023.02.01.08.36.07; Wed, 01 Feb 2023 08:36:31 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=jcn6cTs4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232591AbjBAQft (ORCPT <rfc822;duw91626@gmail.com> + 99 others); Wed, 1 Feb 2023 11:35:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40734 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232446AbjBAQfq (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 1 Feb 2023 11:35:46 -0500 Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [IPv6:2a00:1450:4864:20::32f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AF20F7A485 for <linux-kernel@vger.kernel.org>; Wed, 1 Feb 2023 08:35:29 -0800 (PST) Received: by mail-wm1-x32f.google.com with SMTP id m16-20020a05600c3b1000b003dc4050c94aso1921069wms.4 for <linux-kernel@vger.kernel.org>; Wed, 01 Feb 2023 08:35:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=p0B1nR0feNzt6iYs1fcCSNwhqATraAQZbyN0DagmRgs=; b=jcn6cTs4+XY1hUWmIDmmwPG44YIXWbCtGh35J88AOeps79NC6Aub1gKAPPv419PyFm HTPegDj2V+wQXQ7DcQvVkjHumtHWHz7verUSkgH7IJrJQQz1clTf1SwWQ3717K7f1cqs BiPYS75krdieSyLXCxa9QTp4cnoHXv5nKh5HI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=p0B1nR0feNzt6iYs1fcCSNwhqATraAQZbyN0DagmRgs=; b=ZnwDw0DXWtGbsGn8aMVkoZDmPM0ZDBO5KkSMjQNsZArLonbREyeUmLSxGSQ+SD1OFX MC4IygBWHWSLTDmHBkOnTXlczdbK+/YAbWfAx48wEOLu8qMidirIcBQ05r2x90WY7RTD 2gGSrqByopZXqm8FMMz5L7Lrs6231XSM7qnmWHEM0LVJCi53MS/tJdYmoGGueK/qIukc UoCzC0xFm01LA+REMmyhBXjTI00ywtZYuTlomXatRrdCHOz1xXJYC9cKKdyPEHZQp+VQ nDqVSFONkw0mGgTBYjWs7pWR0QpLaW11u6M+y193aYNcinh6zwN6X99TNip5yCEsFrPL bHLg== X-Gm-Message-State: AO0yUKXgLEdjJLxM0M+TB7CqPeRj2cxIQJWY4ZClmmFHmTn2ky+AuvDi C1NdrmeHlhFrNFBgS+TtYXhmig== X-Received: by 2002:a05:600c:491c:b0:3d9:ee01:60a4 with SMTP id f28-20020a05600c491c00b003d9ee0160a4mr2827768wmp.1.1675269328196; Wed, 01 Feb 2023 08:35:28 -0800 (PST) Received: from revest.zrh.corp.google.com ([2a00:79e0:9d:6:4399:89a1:4a86:9630]) by smtp.gmail.com with ESMTPSA id r38-20020a05600c322600b003dd7edcc960sm2058522wmp.45.2023.02.01.08.35.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 Feb 2023 08:35:27 -0800 (PST) From: Florent Revest <revest@chromium.org> To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, bpf@vger.kernel.org Cc: catalin.marinas@arm.com, will@kernel.org, rostedt@goodmis.org, mhiramat@kernel.org, mark.rutland@arm.com, ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, kpsingh@kernel.org, jolsa@kernel.org, xukuohai@huaweicloud.com, Florent Revest <revest@chromium.org> Subject: [PATCH 4/8] ftrace: Store direct called addresses in their ops Date: Wed, 1 Feb 2023 17:34:16 +0100 Message-Id: <20230201163420.1579014-5-revest@chromium.org> X-Mailer: git-send-email 2.39.1.519.gcb327c4b5f-goog In-Reply-To: <20230201163420.1579014-1-revest@chromium.org> References: <20230201163420.1579014-1-revest@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1756647277617931532?= X-GMAIL-MSGID: =?utf-8?q?1756647277617931532?= |
Series |
Add ftrace direct call for arm64
|
|
Commit Message
Florent Revest
Feb. 1, 2023, 4:34 p.m. UTC
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.
Signed-off-by: Florent Revest <revest@chromium.org>
---
include/linux/ftrace.h | 3 +++
kernel/trace/ftrace.c | 6 ++++--
2 files changed, 7 insertions(+), 2 deletions(-)
Comments
On Wed, Feb 01, 2023 at 05:34:16PM +0100, Florent Revest wrote: > 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. > > Signed-off-by: Florent Revest <revest@chromium.org> > --- > include/linux/ftrace.h | 3 +++ > kernel/trace/ftrace.c | 6 ++++-- > 2 files changed, 7 insertions(+), 2 deletions(-) > > diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h > index a7dbd307c3a4..84f717f8959e 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 > }; > > diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c > index cb77a0a208c7..b0426de11c45 100644 > --- a/kernel/trace/ftrace.c > +++ b/kernel/trace/ftrace.c > @@ -2577,9 +2577,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 = ops->direct_call; > > - addr = ftrace_find_rec_direct(ip); > if (!addr) > return; > > @@ -5375,6 +5374,7 @@ int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) > ops->func = call_direct_funcs; > ops->flags = MULTI_FLAGS; > ops->trampoline = FTRACE_REGS_ADDR; > + ops->direct_call = addr; > > err = register_ftrace_function_nolock(ops); > > @@ -5445,6 +5445,7 @@ __modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) > /* Enable the tmp_ops to have the same functions as the direct ops */ > ftrace_ops_init(&tmp_ops); > tmp_ops.func_hash = ops->func_hash; > + tmp_ops.direct_call = addr; > > err = register_ftrace_function_nolock(&tmp_ops); > if (err) > @@ -5466,6 +5467,7 @@ __modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) > entry->direct = addr; > } > } > + ops->direct_call = addr; AFAICT we don't synchronize threads when installing the tmp_ops, so IIUC on arches with call_ops, there could be a a thread in the middle of ftrace_caller which has loaded the ops pointer from the patch-site, but hasn't yet loaded the ops::direct_func pointer, and could race with this assignment. Given that, I think this needs to be: WRITE_ONCE(ops->direct_call, addr); ... in order to avoid the risk of the store being torn, and the ftrace_caller trampoline loading a corrupted pointer. Other than that, this looks good to me! Thanks, Mark. > > mutex_unlock(&ftrace_lock); > > -- > 2.39.1.519.gcb327c4b5f-goog >
On Thu, Feb 2, 2023 at 4:30 PM Mark Rutland <mark.rutland@arm.com> wrote: > > On Wed, Feb 01, 2023 at 05:34:16PM +0100, Florent Revest wrote: > > 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. > > > > Signed-off-by: Florent Revest <revest@chromium.org> > > --- > > include/linux/ftrace.h | 3 +++ > > kernel/trace/ftrace.c | 6 ++++-- > > 2 files changed, 7 insertions(+), 2 deletions(-) > > > > diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h > > index a7dbd307c3a4..84f717f8959e 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 > > }; > > > > diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c > > index cb77a0a208c7..b0426de11c45 100644 > > --- a/kernel/trace/ftrace.c > > +++ b/kernel/trace/ftrace.c > > @@ -2577,9 +2577,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 = ops->direct_call; > > > > - addr = ftrace_find_rec_direct(ip); > > if (!addr) > > return; > > > > @@ -5375,6 +5374,7 @@ int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) > > ops->func = call_direct_funcs; > > ops->flags = MULTI_FLAGS; > > ops->trampoline = FTRACE_REGS_ADDR; > > + ops->direct_call = addr; > > > > err = register_ftrace_function_nolock(ops); > > > > @@ -5445,6 +5445,7 @@ __modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) > > /* Enable the tmp_ops to have the same functions as the direct ops */ > > ftrace_ops_init(&tmp_ops); > > tmp_ops.func_hash = ops->func_hash; > > + tmp_ops.direct_call = addr; > > > > err = register_ftrace_function_nolock(&tmp_ops); > > if (err) > > @@ -5466,6 +5467,7 @@ __modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) > > entry->direct = addr; > > } > > } > > + ops->direct_call = addr; > > AFAICT we don't synchronize threads when installing the tmp_ops, so IIUC on > arches with call_ops, there could be a a thread in the middle of ftrace_caller > which has loaded the ops pointer from the patch-site, but hasn't yet loaded the > ops::direct_func pointer, and could race with this assignment. > > Given that, I think this needs to be: > > WRITE_ONCE(ops->direct_call, addr); > > ... in order to avoid the risk of the store being torn, and the ftrace_caller > trampoline loading a corrupted pointer. Good point, I'll do that in v2.
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index a7dbd307c3a4..84f717f8959e 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 }; diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index cb77a0a208c7..b0426de11c45 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -2577,9 +2577,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 = ops->direct_call; - addr = ftrace_find_rec_direct(ip); if (!addr) return; @@ -5375,6 +5374,7 @@ int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) ops->func = call_direct_funcs; ops->flags = MULTI_FLAGS; ops->trampoline = FTRACE_REGS_ADDR; + ops->direct_call = addr; err = register_ftrace_function_nolock(ops); @@ -5445,6 +5445,7 @@ __modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) /* Enable the tmp_ops to have the same functions as the direct ops */ ftrace_ops_init(&tmp_ops); tmp_ops.func_hash = ops->func_hash; + tmp_ops.direct_call = addr; err = register_ftrace_function_nolock(&tmp_ops); if (err) @@ -5466,6 +5467,7 @@ __modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) entry->direct = addr; } } + ops->direct_call = addr; mutex_unlock(&ftrace_lock);