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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B0271C77B73 for ; Tue, 2 May 2023 10:54:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233412AbjEBKyH (ORCPT ); Tue, 2 May 2023 06:54:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50454 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229703AbjEBKyF (ORCPT ); Tue, 2 May 2023 06:54:05 -0400 Received: from desiato.infradead.org (desiato.infradead.org [IPv6:2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 46F21E43 for ; Tue, 2 May 2023 03:54:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=In-Reply-To:Content-Type:MIME-Version: References:Message-ID:Subject:Cc:To:From:Date:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=YCX8z20JU20fx5eoX4StsSr5Qby3NVlCSlbBCrvRgAY=; b=MDjKPgCCF/fq+NpxTjcOkn0OMR b0vEzzP2eN0xAlHROhUmy/y+qurHomJghsCTYzKwq6D+6VrRDVnDJsnkw0dFVmzjwqiv2Kt9ME5vO uN20NMeRoWYL0GsY9bmExKDowh4n9TaXYPalcWE/iGhiVrepRP2hcgRHKrju1cM6MuP/rWol436F+ Nqzs/GHFQlH/vw3lOp6Hi6GlY/fwdQGRFZVrz+tRMMDCOorFH54CPZoHlVRhZXW9k45nzFF7JGMGN Kwfh3wm3ri5kRl0SPi2CxbX0xEohbWUPjmCtQY7lbs4tOJNYL+RUfCbA1qb85Ib+4Z/9fBxICq2qL piLratwQ==; Received: from j130084.upc-j.chello.nl ([24.132.130.84] helo=noisy.programming.kicks-ass.net) by desiato.infradead.org with esmtpsa (Exim 4.96 #2 (Red Hat Linux)) id 1ptndq-00GHrw-0P; Tue, 02 May 2023 10:53:54 +0000 Received: from hirez.programming.kicks-ass.net (hirez.programming.kicks-ass.net [192.168.1.225]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (Client did not present a certificate) by noisy.programming.kicks-ass.net (Postfix) with ESMTPS id 9C4833002BF; Tue, 2 May 2023 12:53:53 +0200 (CEST) Received: by hirez.programming.kicks-ass.net (Postfix, from userid 1000) id 4C80623C5C34E; Tue, 2 May 2023 12:53:53 +0200 (CEST) Date: Tue, 2 May 2023 12:53:53 +0200 From: Peter Zijlstra To: Indu Bhagat Cc: linux-toolchains@vger.kernel.org, daandemeyer@meta.com, andrii@kernel.org, rostedt@goodmis.org, kris.van.hees@oracle.com, elena.zannoni@oracle.com, nick.alcock@oracle.com Subject: Re: [POC 5/5] x86_64: invoke SFrame based stack tracer for user space Message-ID: <20230502105353.GO1597476@hirez.programming.kicks-ass.net> References: <20230501200410.3973453-1-indu.bhagat@oracle.com> <20230501200410.3973453-6-indu.bhagat@oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20230501200410.3973453-6-indu.bhagat@oracle.com> Precedence: bulk List-ID: X-Mailing-List: linux-toolchains@vger.kernel.org On Mon, May 01, 2023 at 01:04:10PM -0700, Indu Bhagat wrote: > The task's sframe_state is allocated and initialized if a phdr with type > PT_GNU_SFRAME is encountered for the binary. > > perf_callchain_user() will fall back on the frame pointer based stack > trace approach if: > - SFrame section for the main program is not found. > - SFrame state for the task is either not setup or stale and cannot > be refreshed. > > Finally, the sframe_state is cleaned up in release_task(). > > Signed-off-by: Indu Bhagat > --- > arch/x86/events/core.c | 51 ++++++++++++++++++++++++++++++++++++++++++ > fs/binfmt_elf.c | 39 ++++++++++++++++++++++++++++++++ > kernel/exit.c | 9 ++++++++ > 3 files changed, 99 insertions(+) > > diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c > index d096b04bf80e..4be9e826714a 100644 > --- a/arch/x86/events/core.c > +++ b/arch/x86/events/core.c > @@ -2860,11 +2860,54 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent > } > #endif > > +#ifdef CONFIG_USER_UNWINDER_SFRAME > + > +#include > + > +/* Check if the specified task has SFrame unwind state set up. */ > +static inline bool check_sframe_state_p(struct task_struct *task) > +{ > + bool sframe_ok = false; > + > + /* FIXME TODO - only current task can be unwinded at this time. > + * Even for current tasks, following unknowns remain and hence, not > + * handled: > + * - dlopen / dlclose detection and update of sframe_state, > + * - in general, any change in memory mappings. > + */ > + if (task != current) > + return false; > + > + if (!task->sframe_state) > + return false; > + > + sframe_ok = (unwind_sframe_state_valid_p(task->sframe_state) > + || unwind_sframe_state_ready_p(task->sframe_state)); Please; forget this style is even possible, it is horrific :/ > + > + return sframe_ok; > +} > + > +#else > +/* Check if the specified task has SFrame unwind state set up. */ > +static inline bool check_sframe_state_p(struct task_struct *task) > +{ > + return false; > +} > + > +static inline int sframe_callchain_user(struct task_struct *task, > + struct perf_callchain_entry_ctx *entry, > + struct pt_regs *regs) > +{ > + return 0; > +} > +#endif > + > void > perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) > { > struct stack_frame frame; > const struct stack_frame __user *fp; > + bool sframe_avail; > > if (perf_guest_state()) { > /* TODO: We don't support guest os callchain now */ > @@ -2887,7 +2930,15 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs > if (perf_callchain_user32(regs, entry)) > return; > > + sframe_avail = check_sframe_state_p (current); > + > pagefault_disable(); > + > + if (sframe_avail && !sframe_callchain_user (current, entry, regs)) { > + pagefault_enable(); > + return; > + } > + > while (entry->nr < entry->max_stack) { > if (!valid_user_frame(fp, sizeof(frame))) > break; This is broken, the sframe stuff is not NMI safe. First you need to change perf to emit a forward reference to a 'next' user trace and then emit the user trace on return-to-user. As is, perf does everything in-place from NMI context.