From nobody Fri Oct 3 15:36:00 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1300E30CD84; Thu, 28 Aug 2025 18:03:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756404216; cv=none; b=VpehZEoAUeTd3eIn9+FXY1P5WXi2EJ4f5Su1V68v0JWHqojLaNWD255nruQEQ4F8G0OUW3kSSYZjKxoac2oP8hzJ1NHzuc9LpdeKpExQxr9GCPaKis/Hrpa8KIrgc1Cs3PUy7qL0HE/ajx92+DuN/pqf+iSvTYuPonwU3lppq0s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756404216; c=relaxed/simple; bh=len1TqcKGRiWgn4i9K88WT0rfFP/JPV1Xx3J5okLYhI=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=AgyD//GIv66u8nAkt2swyCkfST86XoXGkhVyRUGDV6KnpEJSvepXLm8h5DLliHpnyVjyhlW2TEaB36pdjGyp3RA+YAieNmLaNfVdKVQnWNm97Cb1sJyPM1nTjPjiaE7eAhdx9aNrExSnnoEQ588tmtXplDuLpV5eFv3/iAhYn/s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Uk0Lw9gy; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Uk0Lw9gy" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DADF6C4CEED; Thu, 28 Aug 2025 18:03:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756404215; bh=len1TqcKGRiWgn4i9K88WT0rfFP/JPV1Xx3J5okLYhI=; h=Date:From:To:Cc:Subject:References:From; b=Uk0Lw9gylnba4ypnY+JeVoxsq3OIvYUi/IDBRUuPwiRaVicREVR478oxPIZweAr4H VF431oNQc36kJHvP9+H2B18r2JaCyT0cedHccHVNwSwpvA8/gO8aE6GJbisBjvgDpt tj3leRlUeXhwLFhR8Fh3YxjEAo5mwMCBiAnFTGAY94e+l1A2fSxAI4EkU4chDZTr0j 6xSdONqNDCnleQKBya9365kh/uO9TMLpFMx6cc6EUefrVoq1xH6Abq4fel1FmXn67k U122bFoZ/5EGufmcdwiyUjDG4he7HL60oK7uciqSooGqvnVU8bMrRifkNfiBYBBDiw aV3bEvbRSIypg== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1urgya-00000004GBK-2uqk; Thu, 28 Aug 2025 14:03:56 -0400 Message-ID: <20250828180356.546256287@kernel.org> User-Agent: quilt/0.68 Date: Thu, 28 Aug 2025 14:03:01 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, bpf@vger.kernel.org, x86@kernel.org Cc: Masami Hiramatsu , Mathieu Desnoyers , Josh Poimboeuf , Peter Zijlstra , Ingo Molnar , Jiri Olsa , Arnaldo Carvalho de Melo , Namhyung Kim , Thomas Gleixner , Andrii Nakryiko , Indu Bhagat , "Jose E. Marchesi" , Beau Belgrave , Jens Remus , Linus Torvalds , Andrew Morton , Florian Weimer , Sam James , Kees Cook , "Carlos O'Donell" Subject: [PATCH v6 1/6] tracing: Do not bother getting user space stacktraces for kernel threads References: <20250828180300.591225320@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Steven Rostedt If a user space stacktrace is requested when running a kernel thread, just return, as there's no point trying to get the user space stacktrace as there is no user space. Signed-off-by: Steven Rostedt (Google) --- Changes since v5: https://lore.kernel.org/20250424192613.014380756@goodmis.= org - Also add check for PF_USER_WORKER to test for kernel thread kernel/trace/trace.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 1b7db732c0b1..2cca29c9863d 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -3138,6 +3138,10 @@ ftrace_trace_userstack(struct trace_array *tr, if (!(tr->trace_flags & TRACE_ITER_USERSTACKTRACE)) return; =20 + /* No point doing user space stacktraces on kernel threads */ + if (current->flags & (PF_KTHREAD | PF_USER_WORKER)) + return; + /* * NMIs can not handle page faults, even with fix ups. * The save user stack can (and often does) fault. --=20 2.50.1 From nobody Fri Oct 3 15:36:00 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 727D5262FD7; Thu, 28 Aug 2025 18:03:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756404216; cv=none; b=eIL40wVcAx5CK8JmeJqoAs3rv/qRMbEQL63ECYSgM9XcZjXynZTaieKn8jPzAK96iUQKz1O+lXK67eZYI1HCGYTDqQVjfLyVb4FbniyoWQs5iH4kAUkQMe51LX6nMGvZLKgv3nosT0X5An1oCTedyjyRs/EvRP2dS5QNMyT8oFo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756404216; c=relaxed/simple; bh=ndrE4gvdhVRpRUi6pNX6gi19dw4jMHbZ54Q/ID3v70c=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=hUlPapkna8fA0O0tLuvZpqYtOSIiT7VhGboqYnZb6Y9OHno+0SWrO7GUY8OMR03lkW+lwrduZ3OWQD7MdOjzEJSQiaaqecsMTfhULbcxTnwI66T7S78uaPAIoEzHf86XsrKNauiLD0MZ+b/qi3q7UeheYaeRZUZX16rwY4JJY/I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mgDp6LSh; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="mgDp6LSh" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E2252C4CEF4; Thu, 28 Aug 2025 18:03:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756404216; bh=ndrE4gvdhVRpRUi6pNX6gi19dw4jMHbZ54Q/ID3v70c=; h=Date:From:To:Cc:Subject:References:From; b=mgDp6LSh2Bs/3yqNuAqNaq6W4stRWT66hiYWS+SGJ0h0e/bSrELTcF6SgFDyTDVbf nc8wVQ82dzKPHg2ZbbdXK58VCulitnJlnoQk1DQ2yPx0BFAEPeEmE2/o3mzLO5Ii9M gUI75wFfNqrcm9VEMoxb3TZYXmazuCpJYsPj+xadm5fB1CQ+X3zmbIvOMjmYf/ssY3 N2mCPd5X9Ia9GlSGWwW1xWuNOZNr0RQjLgKtdUg7o0Q75nQE/br5jVB35ZtCVY+e3H FJRWqqXVng8WzK07B9+jyYx5ROaWjjHnlsmPM547shHd4s4wKFo88Dvrh1hquOgvG3 HZgAuf048a7Ew== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1urgya-00000004GBo-3bon; Thu, 28 Aug 2025 14:03:56 -0400 Message-ID: <20250828180356.716157474@kernel.org> User-Agent: quilt/0.68 Date: Thu, 28 Aug 2025 14:03:02 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, bpf@vger.kernel.org, x86@kernel.org Cc: Masami Hiramatsu , Mathieu Desnoyers , Josh Poimboeuf , Peter Zijlstra , Ingo Molnar , Jiri Olsa , Arnaldo Carvalho de Melo , Namhyung Kim , Thomas Gleixner , Andrii Nakryiko , Indu Bhagat , "Jose E. Marchesi" , Beau Belgrave , Jens Remus , Linus Torvalds , Andrew Morton , Florian Weimer , Sam James , Kees Cook , "Carlos O'Donell" Subject: [PATCH v6 2/6] tracing: Rename __dynamic_array() to __dynamic_field() for ftrace events References: <20250828180300.591225320@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Steven Rostedt The ftrace events (like function, trace_print, etc) are created somewhat manually and not via the TRACE_EVENT() or tracepoint magic macros. It has its own macros. The dynamic fields used __dynamic_array() to be created, but the output is different than the __dynamic_array() used by TRACE_EVENT(). The TRACE_EVENT() __dynamic_array() creates the field like: field:__data_loc u8[] v_data; offset:120; size:4; signed:0; Whereas the ftrace event is created as: field:char buf[]; offset:12; size:0; signed:0; The difference is that the ftrace field is defined as the rest of the size of the event saved in the ring buffer. TRACE_EVENT() doesn't have such a dynamic field, and its version saves a word that holds the offset into the event that the field is stored, as well as the size. For consistency rename the ftrace event macro to __dynamic_field(). This way the ftrace event can also include a __dynamic_array() later that works the same as the TRACE_EVENT() dynamic array. Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace.h | 4 ++-- kernel/trace/trace_entries.h | 10 +++++----- kernel/trace/trace_export.c | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 5f4bed5842f9..0fd2559ff119 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -92,8 +92,8 @@ enum trace_type { #undef __array_desc #define __array_desc(type, container, item, size) =20 -#undef __dynamic_array -#define __dynamic_array(type, item) type item[]; +#undef __dynamic_field +#define __dynamic_field(type, item) type item[]; =20 #undef __rel_dynamic_array #define __rel_dynamic_array(type, item) type item[]; diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h index de294ae2c5c5..5cf80f6c704a 100644 --- a/kernel/trace/trace_entries.h +++ b/kernel/trace/trace_entries.h @@ -63,7 +63,7 @@ FTRACE_ENTRY_REG(function, ftrace_entry, F_STRUCT( __field_fn( unsigned long, ip ) __field_fn( unsigned long, parent_ip ) - __dynamic_array( unsigned long, args ) + __dynamic_field( unsigned long, args ) ), =20 F_printk(" %ps <-- %ps", @@ -81,7 +81,7 @@ FTRACE_ENTRY(funcgraph_entry, ftrace_graph_ent_entry, __field_struct( struct ftrace_graph_ent, graph_ent ) __field_packed( unsigned long, graph_ent, func ) __field_packed( unsigned int, graph_ent, depth ) - __dynamic_array(unsigned long, args ) + __dynamic_field(unsigned long, args ) ), =20 F_printk("--> %ps (%u)", (void *)__entry->func, __entry->depth) @@ -259,7 +259,7 @@ FTRACE_ENTRY(bprint, bprint_entry, F_STRUCT( __field( unsigned long, ip ) __field( const char *, fmt ) - __dynamic_array( u32, buf ) + __dynamic_field( u32, buf ) ), =20 F_printk("%ps: %s", @@ -272,7 +272,7 @@ FTRACE_ENTRY_REG(print, print_entry, =20 F_STRUCT( __field( unsigned long, ip ) - __dynamic_array( char, buf ) + __dynamic_field( char, buf ) ), =20 F_printk("%ps: %s", @@ -287,7 +287,7 @@ FTRACE_ENTRY(raw_data, raw_data_entry, =20 F_STRUCT( __field( unsigned int, id ) - __dynamic_array( char, buf ) + __dynamic_field( char, buf ) ), =20 F_printk("id:%04x %08x", diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c index 1698fc22afa0..d9d41e3ba379 100644 --- a/kernel/trace/trace_export.c +++ b/kernel/trace/trace_export.c @@ -57,8 +57,8 @@ static int ftrace_event_register(struct trace_event_call = *call, #undef __array_desc #define __array_desc(type, container, item, size) type item[size]; =20 -#undef __dynamic_array -#define __dynamic_array(type, item) type item[]; +#undef __dynamic_field +#define __dynamic_field(type, item) type item[]; =20 #undef F_STRUCT #define F_STRUCT(args...) args @@ -123,8 +123,8 @@ static void __always_unused ____ftrace_check_##name(voi= d) \ #undef __array_desc #define __array_desc(_type, _container, _item, _len) __array(_type, _item,= _len) =20 -#undef __dynamic_array -#define __dynamic_array(_type, _item) { \ +#undef __dynamic_field +#define __dynamic_field(_type, _item) { \ .type =3D #_type "[]", .name =3D #_item, \ .size =3D 0, .align =3D __alignof__(_type), \ is_signed_type(_type), .filter_type =3D FILTER_OTHER }, @@ -161,8 +161,8 @@ static struct trace_event_fields ftrace_event_fields_##= name[] =3D { \ #undef __array_desc #define __array_desc(type, container, item, len) =20 -#undef __dynamic_array -#define __dynamic_array(type, item) +#undef __dynamic_field +#define __dynamic_field(type, item) =20 #undef F_printk #define F_printk(fmt, args...) __stringify(fmt) ", " __stringify(args) --=20 2.50.1 From nobody Fri Oct 3 15:36:00 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 99221265281; Thu, 28 Aug 2025 18:03:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756404216; cv=none; b=GasdygCQrQwD4j1y8S4IqcOfNGXr5axsq8pxIhRBJCnjukl5PUKmaVojo7b6eacbld6YPFMhng5NFc17dZ8U27flFVbiEW4ZIj4DOqHRnn5RtPmx5F7KLpkJsuQ5I6splfosko0PZcnTvRNYEi25uKSyiQEkfmvicftstpVwbXc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756404216; c=relaxed/simple; bh=sla6hrT5B1o2zSr6cxHddWYwxQpQ0gR9p6xSsoo1ILs=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=OphbGUm3E6vm+PA13XXwEB3F+yWsBUoeFcfrFxH7EBlxxj0G9/RVOd0f8FaES8dGF1bRCc6AxDl1qCYtkFAfqDBBZX34q187ROEnJWT11b+IDjw7StyLKy7EmS6RyOLUWf3QoPNgXk/YuR2xKZftHBX0xLsLGzKRpOyrLHMrlcY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gvQg9Z8D; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gvQg9Z8D" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2ED03C4CEFC; Thu, 28 Aug 2025 18:03:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756404216; bh=sla6hrT5B1o2zSr6cxHddWYwxQpQ0gR9p6xSsoo1ILs=; h=Date:From:To:Cc:Subject:References:From; b=gvQg9Z8DET3z9HDTcIblVdaupGDvMaULGsKaGfdv3bsCKE7JkpwHDooylvvMtL6mP 1l7uEheIzMQAe9oN3E09+Y7Dj65Yg0z+aS3I+AWBsbLYHajUpzQVxzi9mJwsCBGGle fO1n6UxcR4HG7gm2Y1LXqsj1e9h/lXWNo+jeJGgrpbruaFiIv/6Ikg8IepiJRguoNO udASwa34ablTdILzOigw4KujWRU3QBX38ZdE3S8cerX4ULeVDXi0LXvJYZH5i0KijO 1xU5AuzfkblcYmeF+tU0Q2pfuiWE2vM3l+bOpozvUFbVdS8U/KLAd7matII++/GCvE +sY0+7e2qgdOg== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1urgyb-00000004GCI-08QY; Thu, 28 Aug 2025 14:03:57 -0400 Message-ID: <20250828180356.882470556@kernel.org> User-Agent: quilt/0.68 Date: Thu, 28 Aug 2025 14:03:03 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, bpf@vger.kernel.org, x86@kernel.org Cc: Masami Hiramatsu , Mathieu Desnoyers , Josh Poimboeuf , Peter Zijlstra , Ingo Molnar , Jiri Olsa , Arnaldo Carvalho de Melo , Namhyung Kim , Thomas Gleixner , Andrii Nakryiko , Indu Bhagat , "Jose E. Marchesi" , Beau Belgrave , Jens Remus , Linus Torvalds , Andrew Morton , Florian Weimer , Sam James , Kees Cook , "Carlos O'Donell" Subject: [PATCH v6 3/6] tracing: Implement deferred user space stacktracing References: <20250828180300.591225320@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Steven Rostedt Use the unwind_deferred_*() interface to be able to trace deferred user space stacks. This creates two new ftrace events: user_unwind_cookie user_unwind_stack The user_unwind_cookie will record into the ring buffer the cookie given from unwind_deferred_request(), and the user_unwind_stack will record into the ring buffer the user space stack as well as the cookie associated with it. Signed-off-by: Steven Rostedt (Google) --- Changes since v5: https://lore.kernel.org/20250424192613.356969984@goodmis.= org - Have the userstacktrace_delay option not depend on the userstacktrace option. - Do not expose the userstacktrace_delay option if it's not supported. kernel/trace/trace.c | 91 ++++++++++++++++++++++++++++++++++-- kernel/trace/trace.h | 20 ++++++++ kernel/trace/trace_entries.h | 24 ++++++++++ kernel/trace/trace_export.c | 23 +++++++++ kernel/trace/trace_output.c | 72 ++++++++++++++++++++++++++++ 5 files changed, 227 insertions(+), 3 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 2cca29c9863d..e5b7db19aa53 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -3128,6 +3128,66 @@ EXPORT_SYMBOL_GPL(trace_dump_stack); #ifdef CONFIG_USER_STACKTRACE_SUPPORT static DEFINE_PER_CPU(int, user_stack_count); =20 +static void trace_user_unwind_callback(struct unwind_work *unwind, + struct unwind_stacktrace *trace, + u64 ctx_cookie) +{ + struct trace_array *tr =3D container_of(unwind, struct trace_array, unwin= der); + struct trace_buffer *buffer =3D tr->array_buffer.buffer; + struct userunwind_stack_entry *entry; + struct ring_buffer_event *event; + unsigned int trace_ctx; + unsigned long *caller; + unsigned int offset; + int len; + int i; + + if (!(tr->trace_flags & TRACE_ITER_USERSTACKTRACE_DELAY)) + return; + + len =3D trace->nr * sizeof(unsigned long) + sizeof(*entry); + + trace_ctx =3D tracing_gen_ctx(); + event =3D __trace_buffer_lock_reserve(buffer, TRACE_USER_UNWIND_STACK, + len, trace_ctx); + if (!event) + return; + + entry =3D ring_buffer_event_data(event); + + entry->cookie =3D ctx_cookie; + + offset =3D sizeof(*entry); + len =3D sizeof(unsigned long) * trace->nr; + + entry->__data_loc_stack =3D offset | (len << 16); + caller =3D (void *)entry + offset; + + for (i =3D 0; i < trace->nr; i++) { + caller[i] =3D trace->entries[i]; + } + + __buffer_unlock_commit(buffer, event); +} + +static void +ftrace_trace_userstack_delay(struct trace_array *tr, + struct trace_buffer *buffer, unsigned int trace_ctx) +{ + struct userunwind_cookie_entry *entry; + struct ring_buffer_event *event; + + event =3D __trace_buffer_lock_reserve(buffer, TRACE_USER_UNWIND_COOKIE, + sizeof(*entry), trace_ctx); + if (!event) + return; + entry =3D ring_buffer_event_data(event); + + unwind_deferred_request(&tr->unwinder, &entry->cookie); + + __buffer_unlock_commit(buffer, event); +} + static void ftrace_trace_userstack(struct trace_array *tr, struct trace_buffer *buffer, unsigned int trace_ctx) @@ -3135,13 +3195,18 @@ ftrace_trace_userstack(struct trace_array *tr, struct ring_buffer_event *event; struct userstack_entry *entry; =20 - if (!(tr->trace_flags & TRACE_ITER_USERSTACKTRACE)) - return; - /* No point doing user space stacktraces on kernel threads */ if (current->flags & (PF_KTHREAD | PF_USER_WORKER)) return; =20 + if (tr->trace_flags & TRACE_ITER_USERSTACKTRACE_DELAY) { + ftrace_trace_userstack_delay(tr, buffer, trace_ctx); + return; + } + + if (!(tr->trace_flags & TRACE_ITER_USERSTACKTRACE)) + return; + /* * NMIs can not handle page faults, even with fix ups. * The save user stack can (and often does) fault. @@ -5215,6 +5280,17 @@ int trace_keep_overwrite(struct tracer *tracer, u32 = mask, int set) return 0; } =20 +static int update_unwind_deferred(struct trace_array *tr, int enabled) +{ + if (enabled) { + return unwind_deferred_init(&tr->unwinder, + trace_user_unwind_callback); + } else { + unwind_deferred_cancel(&tr->unwinder); + return 0; + } +} + int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled) { if ((mask =3D=3D TRACE_ITER_RECORD_TGID) || @@ -5251,6 +5327,12 @@ int set_tracer_flag(struct trace_array *tr, unsigned= int mask, int enabled) } } =20 + if (mask =3D=3D TRACE_ITER_USERSTACKTRACE_DELAY) { + int ret =3D update_unwind_deferred(tr, enabled); + if (ret < 0) + return ret; + } + if (mask =3D=3D TRACE_ITER_COPY_MARKER) update_marker_trace(tr, enabled); =20 @@ -10002,6 +10084,9 @@ static int __remove_instance(struct trace_array *tr) if (tr->ref > 1 || (tr->current_trace && tr->trace_ref)) return -EBUSY; =20 + if ((tr->flags & TRACE_ITER_USERSTACKTRACE_DELAY)) + unwind_deferred_cancel(&tr->unwinder); + list_del(&tr->list); =20 /* Disable all the flags that were enabled coming in */ diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 0fd2559ff119..940107ba618a 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -49,7 +50,10 @@ enum trace_type { TRACE_GRAPH_ENT, TRACE_GRAPH_RETADDR_ENT, TRACE_USER_STACK, + /* trace-cmd manually adds blktrace after USER_STACK */ TRACE_BLK, + TRACE_USER_UNWIND_STACK, + TRACE_USER_UNWIND_COOKIE, TRACE_BPUTS, TRACE_HWLAT, TRACE_OSNOISE, @@ -92,6 +96,9 @@ enum trace_type { #undef __array_desc #define __array_desc(type, container, item, size) =20 +#undef __dynamic_array +#define __dynamic_array(type, item) u32 __data_loc_##item; + #undef __dynamic_field #define __dynamic_field(type, item) type item[]; =20 @@ -435,6 +442,7 @@ struct trace_array { struct cond_snapshot *cond_snapshot; #endif struct trace_func_repeats __percpu *last_func_repeats; + struct unwind_work unwinder; /* * On boot up, the ring buffer is set to the minimum size, so that * we do not waste memory on systems that are not using tracing. @@ -526,6 +534,9 @@ extern void __ftrace_bad_type(void); IF_ASSIGN(var, ent, struct ctx_switch_entry, 0); \ IF_ASSIGN(var, ent, struct stack_entry, TRACE_STACK); \ IF_ASSIGN(var, ent, struct userstack_entry, TRACE_USER_STACK);\ + IF_ASSIGN(var, ent, struct userunwind_stack_entry, TRACE_USER_UNWIND_STA= CK);\ + IF_ASSIGN(var, ent, struct userunwind_cookie_entry, TRACE_USER_UNWIND_CO= OKIE);\ + IF_ASSIGN(var, ent, struct userstack_entry, TRACE_USER_STACK);\ IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT); \ IF_ASSIGN(var, ent, struct bprint_entry, TRACE_BPRINT); \ IF_ASSIGN(var, ent, struct bputs_entry, TRACE_BPUTS); \ @@ -1359,6 +1370,14 @@ extern int trace_get_user(struct trace_parser *parse= r, const char __user *ubuf, # define STACK_FLAGS #endif =20 +#ifdef CONFIG_UNWIND_USER +# define USERSTACK_DELAY \ + C(USERSTACKTRACE_DELAY, "userstacktrace_delay"), +#else +# define USERSTACK_DELAY +# define TRACE_ITER_USERSTACKTRACE_DELAY 0 +#endif + /* * trace_iterator_flags is an enumeration that defines bit * positions into trace_flags that controls the output. @@ -1379,6 +1398,7 @@ extern int trace_get_user(struct trace_parser *parser= , const char __user *ubuf, C(PRINTK, "trace_printk"), \ C(ANNOTATE, "annotate"), \ C(USERSTACKTRACE, "userstacktrace"), \ + USERSTACK_DELAY \ C(SYM_USEROBJ, "sym-userobj"), \ C(PRINTK_MSGONLY, "printk-msg-only"), \ C(CONTEXT_INFO, "context-info"), /* Print pid/cpu/time */ \ diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h index 5cf80f6c704a..40dc53ead0a8 100644 --- a/kernel/trace/trace_entries.h +++ b/kernel/trace/trace_entries.h @@ -249,6 +249,30 @@ FTRACE_ENTRY(user_stack, userstack_entry, (void *)__entry->caller[6], (void *)__entry->caller[7]) ); =20 +FTRACE_ENTRY(user_unwind_stack, userunwind_stack_entry, + + TRACE_USER_UNWIND_STACK, + + F_STRUCT( + __field( u64, cookie ) + __dynamic_array( unsigned long, stack ) + ), + + F_printk("cookie=3D%lld\n%s", __entry->cookie, + __print_dynamic_array(stack, sizeof(unsigned long))) +); + +FTRACE_ENTRY(user_unwind_cookie, userunwind_cookie_entry, + + TRACE_USER_UNWIND_COOKIE, + + F_STRUCT( + __field( u64, cookie ) + ), + + F_printk("cookie=3D%lld", __entry->cookie) +); + /* * trace_printk entry: */ diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c index d9d41e3ba379..831999f84e2c 100644 --- a/kernel/trace/trace_export.c +++ b/kernel/trace/trace_export.c @@ -57,6 +57,9 @@ static int ftrace_event_register(struct trace_event_call = *call, #undef __array_desc #define __array_desc(type, container, item, size) type item[size]; =20 +#undef __dynamic_array +#define __dynamic_array(type, item) u32 __data_loc_##item; + #undef __dynamic_field #define __dynamic_field(type, item) type item[]; =20 @@ -66,6 +69,16 @@ static int ftrace_event_register(struct trace_event_call= *call, #undef F_printk #define F_printk(fmt, args...) fmt, args =20 +/* Only used for ftrace event format output */ +static inline char * __print_dynamic_array(int array, size_t size) +{ + return NULL; +} + +#undef __print_dynamic_array +#define __print_dynamic_array(array, el_size) \ + __print_dynamic_array(__entry->__data_loc_##array, el_size) + #undef FTRACE_ENTRY #define FTRACE_ENTRY(name, struct_name, id, tstruct, print) \ struct ____ftrace_##name { \ @@ -74,6 +87,7 @@ struct ____ftrace_##name { \ static void __always_unused ____ftrace_check_##name(void) \ { \ struct ____ftrace_##name *__entry =3D NULL; \ + struct trace_seq __maybe_unused *p =3D NULL; \ \ /* force compile-time check on F_printk() */ \ printk(print); \ @@ -123,6 +137,12 @@ static void __always_unused ____ftrace_check_##name(vo= id) \ #undef __array_desc #define __array_desc(_type, _container, _item, _len) __array(_type, _item,= _len) =20 +#undef __dynamic_array +#define __dynamic_array(_type, _item) { \ + .type =3D "__data_loc " #_type "[]", .name =3D #_item, \ + .size =3D 4, .align =3D __alignof__(4), \ + is_signed_type(_type), .filter_type =3D FILTER_OTHER }, + #undef __dynamic_field #define __dynamic_field(_type, _item) { \ .type =3D #_type "[]", .name =3D #_item, \ @@ -161,6 +181,9 @@ static struct trace_event_fields ftrace_event_fields_##= name[] =3D { \ #undef __array_desc #define __array_desc(type, container, item, len) =20 +#undef __dynamic_array +#define __dynamic_array(type, item) + #undef __dynamic_field #define __dynamic_field(type, item) =20 diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 97db0b0ccf3e..9489537533f7 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -1404,6 +1404,58 @@ static struct trace_event trace_stack_event =3D { }; =20 /* TRACE_USER_STACK */ +static enum print_line_t trace_user_unwind_stack_print(struct trace_iterat= or *iter, + int flags, struct trace_event *event) +{ + struct userunwind_stack_entry *field; + struct trace_seq *s =3D &iter->seq; + unsigned long *caller; + unsigned int offset; + unsigned int len; + unsigned int caller_cnt; + unsigned int i; + + trace_assign_type(field, iter->ent); + + trace_seq_puts(s, "\n"); + + trace_seq_printf(s, "cookie=3D%llx\n", field->cookie); + + /* The stack field is a dynamic pointer */ + offset =3D field->__data_loc_stack; + len =3D offset >> 16; + offset =3D offset & 0xffff; + caller_cnt =3D len / sizeof(*caller); + + caller =3D (void *)iter->ent + offset; + + for (i =3D 0; i < caller_cnt; i++) { + unsigned long ip =3D caller[i]; + + if (!ip || trace_seq_has_overflowed(s)) + break; + + trace_seq_puts(s, " =3D> "); + seq_print_user_ip(s, NULL, ip, flags); + trace_seq_putc(s, '\n'); + } + + return trace_handle_return(s); +} + +static enum print_line_t trace_user_unwind_cookie_print(struct trace_itera= tor *iter, + int flags, struct trace_event *event) +{ + struct userunwind_cookie_entry *field; + struct trace_seq *s =3D &iter->seq; + + trace_assign_type(field, iter->ent); + + trace_seq_printf(s, "cookie=3D%llx\n", field->cookie); + + return trace_handle_return(s); +} + static enum print_line_t trace_user_stack_print(struct trace_iterator *ite= r, int flags, struct trace_event *event) { @@ -1447,6 +1499,24 @@ static enum print_line_t trace_user_stack_print(stru= ct trace_iterator *iter, return trace_handle_return(s); } =20 +static struct trace_event_functions trace_userunwind_stack_funcs =3D { + .trace =3D trace_user_unwind_stack_print, +}; + +static struct trace_event trace_userunwind_stack_event =3D { + .type =3D TRACE_USER_UNWIND_STACK, + .funcs =3D &trace_userunwind_stack_funcs, +}; + +static struct trace_event_functions trace_userunwind_cookie_funcs =3D { + .trace =3D trace_user_unwind_cookie_print, +}; + +static struct trace_event trace_userunwind_cookie_event =3D { + .type =3D TRACE_USER_UNWIND_COOKIE, + .funcs =3D &trace_userunwind_cookie_funcs, +}; + static struct trace_event_functions trace_user_stack_funcs =3D { .trace =3D trace_user_stack_print, }; @@ -1846,6 +1916,8 @@ static struct trace_event *events[] __initdata =3D { &trace_ctx_event, &trace_wake_event, &trace_stack_event, + &trace_userunwind_cookie_event, + &trace_userunwind_stack_event, &trace_user_stack_event, &trace_bputs_event, &trace_bprint_event, --=20 2.50.1 From nobody Fri Oct 3 15:36:00 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 992BE2652A2; Thu, 28 Aug 2025 18:03:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756404216; cv=none; b=LLBtJVz/nI2gDnXI46pJTkg07mRumHjsFtV5+WeY2s/fRyJJdVW+xhbyhnypLMMzIRIrbVk9LwrggCIqCao4ZtqQ/2JxPepqzkvr6p9LEudiqDu0+tGwE5KscSWVhlOW7vOlP3GVo1WrB/F0IngU8LaJIk35qg78FG2XjAe8HnQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756404216; c=relaxed/simple; bh=vfbt2SZ6nqgsEUTnkrxBr9gEI1neBhMBF0zlWhgN6BI=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=GExt4WCoR1rYH5sWM6+bf2UEvoqFzPh82shRoPJjlHP4t+aepQXpewsnPsJ5n6Pp+wn8ycsb8FN+kirKC0QdqL++m9qrycRPbNiEoz9aS7S1qxaHHRp7nLeiOtBVtYilQG8oqERQR5gCf3/DawFQNCssmVSyqD+9OnkYGMWq6MU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=X916Y52k; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="X916Y52k" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 503A5C4CEF5; Thu, 28 Aug 2025 18:03:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756404216; bh=vfbt2SZ6nqgsEUTnkrxBr9gEI1neBhMBF0zlWhgN6BI=; h=Date:From:To:Cc:Subject:References:From; b=X916Y52kDkzOAB+YN2ufHn8u7Sn7d/kgdzqIqwhxrpiZmjGJ2Akl05HnGzpeyTLG5 peaABt7rQ81tMFaoNnU11XZKT2t1/vJ6x8QSHcdVl1LuY9KGrXp5uMAp+Dtz8Np65I Wn4X/DGw8e1Nil2NRhX/S2mj7iliGlEZ4ToYTtUPqovvmhsIHQ2q8Zi5KV3UtYP8Xr LlOnCmg24Q/UMGCg4ULhuwc2oMjdXn5GjGJwTfpZ+t7Hs2lwgIvGEHYrAw4WIMt/z4 AQIqBmbGYJoadAoQMVY/8B2dh0r2L4okhzEaJvPqI/jGBUcBZN92eDhvTK6Rgn1hcU 0vGMUV8vY1skg== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1urgyb-00000004GCm-0qNe; Thu, 28 Aug 2025 14:03:57 -0400 Message-ID: <20250828180357.052318722@kernel.org> User-Agent: quilt/0.68 Date: Thu, 28 Aug 2025 14:03:04 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, bpf@vger.kernel.org, x86@kernel.org Cc: Masami Hiramatsu , Mathieu Desnoyers , Josh Poimboeuf , Peter Zijlstra , Ingo Molnar , Jiri Olsa , Arnaldo Carvalho de Melo , Namhyung Kim , Thomas Gleixner , Andrii Nakryiko , Indu Bhagat , "Jose E. Marchesi" , Beau Belgrave , Jens Remus , Linus Torvalds , Andrew Morton , Florian Weimer , Sam James , Kees Cook , "Carlos O'Donell" Subject: [PATCH v6 4/6] tracing: Have deferred user space stacktrace show file offsets References: <20250828180300.591225320@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Steven Rostedt Instead of showing the IP address of the user space stack trace, which is where ever it was mapped by the kernel, show the offsets of where it would be in the file. Instead of: trace-cmd-1066 [007] ..... 67.770256: cookie=3D7000000000009 =3D> <00007fdbd0d421ca> =3D> <00007fdbd0f3be27> =3D> <00005635ece557e7> =3D> <00005635ece559d3> =3D> <00005635ece56523> =3D> <00005635ece6479d> =3D> <00005635ece64b01> =3D> <00005635ece64bc0> =3D> <00005635ece53b7e> =3D> <00007fdbd0c6bca8> Which is the addresses of the functions in the virtual address space of the process. Have it record: trace-cmd-1090 [003] ..... 180.779876: cookie=3D3000000000009 =3D> <00000000001001ca> =3D> <000000000000ae27> =3D> <00000000000107e7> =3D> <00000000000109d3> =3D> <0000000000011523> =3D> <000000000001f79d> =3D> <000000000001fb01> =3D> <000000000001fbc0> =3D> <000000000000eb7e> =3D> <0000000000029ca8> Which is the offset from code where it was mapped at. To find this address, the mmap_read_lock is taken and the vma is searched for the addresses. Then what is recorded is simply: (addr - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index e5b7db19aa53..3e9ef644dd64 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -3136,18 +3136,27 @@ static void trace_user_unwind_callback(struct unwin= d_work *unwind, struct trace_buffer *buffer =3D tr->array_buffer.buffer; struct userunwind_stack_entry *entry; struct ring_buffer_event *event; + struct mm_struct *mm =3D current->mm; unsigned int trace_ctx; + struct vm_area_struct *vma =3D NULL; unsigned long *caller; unsigned int offset; int len; int i; =20 + /* This should never happen */ + if (!mm) + return; + if (!(tr->trace_flags & TRACE_ITER_USERSTACKTRACE_DELAY)) return; =20 len =3D trace->nr * sizeof(unsigned long) + sizeof(*entry); =20 trace_ctx =3D tracing_gen_ctx(); + + guard(mmap_read_lock)(mm); + event =3D __trace_buffer_lock_reserve(buffer, TRACE_USER_UNWIND_STACK, len, trace_ctx); if (!event) @@ -3164,7 +3173,16 @@ static void trace_user_unwind_callback(struct unwind= _work *unwind, caller =3D (void *)entry + offset; =20 for (i =3D 0; i < trace->nr; i++) { - caller[i] =3D trace->entries[i]; + unsigned long addr =3D trace->entries[i]; + + if (!vma || addr < vma->vm_start || addr >=3D vma->vm_end) + vma =3D vma_lookup(mm, addr); + + if (!vma) { + caller[i] =3D addr; + continue; + } + caller[i] =3D (addr - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); } =20 __buffer_unlock_commit(buffer, event); --=20 2.50.1 From nobody Fri Oct 3 15:36:00 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C6B9326CE0C; Thu, 28 Aug 2025 18:03:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756404216; cv=none; b=an4QVZn5ell0iUQbGp0yMh2wGyXvGz4ghCjYda26Aml+LgkKSpSRDOrSNZYoFbS8RpocjENUNjWUxR8BLuAkiw+Sc333w4B++wyC2uRZyaQ3AvguGYwrvIi/Z01yCuKNIYlh93WQT8uxSUc9K2Wl0DWumfnumIahZBus0RMeAAo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756404216; c=relaxed/simple; bh=Shk9XwWHjXHvmNsPUjC9THhLxy0GsQvAparhr+M+gFk=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=BNgY6Hq3ftp/SM/Ra+2PpqeVwZnuWnAlnIYD54FBBipS1P71TsQs6Fs+YHXISDAKBXgWbHS1dIOJOT8Ns47u41bKy0cZB6J0QIl8TPuCC3ZWXCBDjadVMiWVG/kl/X+5LMTlIAFTeJYRrmxwP8kWpAhHjk0dewKpRellHNQXz3U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ip+Lh5Fv; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Ip+Lh5Fv" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6C3FEC4CEEB; Thu, 28 Aug 2025 18:03:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756404216; bh=Shk9XwWHjXHvmNsPUjC9THhLxy0GsQvAparhr+M+gFk=; h=Date:From:To:Cc:Subject:References:From; b=Ip+Lh5FvyhTXpM9D7VoHtdPxSo8Rp6nN6FmLNPDqkzUx7b8pZKJJN/TnoROmxfsp0 lxzNRMzeGrLxHg1b8mH2YSMiiNT2lUsXrtEmttQmKYx9hf4M2snFtg5lfiV/lWa4wh RXgeEs+xFTjtZZ1qel3FwbyIvYlCK7ZZx5YMmm3XU8Bg8NNGuDpu9mQ5N98GZbsFZg eXH2xMTS0OCeCy0sa/kX0lHdNoT/AitDnu3OYxcwGDWAoxnGrS09vGLuZsfY2ybKla 3EYZzu8co46vbMq/uToHpBZEOPiTL3Xx67ppJHcQXAbe/vfPeGMWbCvKBcgV8TrR9A MpUDG97WiRZUA== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1urgyb-00000004GDG-1Z3v; Thu, 28 Aug 2025 14:03:57 -0400 Message-ID: <20250828180357.223298134@kernel.org> User-Agent: quilt/0.68 Date: Thu, 28 Aug 2025 14:03:05 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, bpf@vger.kernel.org, x86@kernel.org Cc: Masami Hiramatsu , Mathieu Desnoyers , Josh Poimboeuf , Peter Zijlstra , Ingo Molnar , Jiri Olsa , Arnaldo Carvalho de Melo , Namhyung Kim , Thomas Gleixner , Andrii Nakryiko , Indu Bhagat , "Jose E. Marchesi" , Beau Belgrave , Jens Remus , Linus Torvalds , Andrew Morton , Florian Weimer , Sam James , Kees Cook , "Carlos O'Donell" Subject: [PATCH v6 5/6] tracing: Show inode and device major:minor in deferred user space stacktrace References: <20250828180300.591225320@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Steven Rostedt The deferred user space stacktrace event already does a lookup of the vma for each address in the trace to get the file offset for those addresses, it can also report the file itself. Add two more arrays to the user space stacktrace event. One for the inode number, and the other to store the device major:minor number. Now the output looks like this: trace-cmd-1108 [007] ..... 240.253487: cookie=3D7000000000009 =3D> <00000000001001ca> : 1340007 : 254:3 =3D> <000000000000ae27> : 1308548 : 254:3 =3D> <00000000000107e7> : 1440347 : 254:3 =3D> <00000000000109d3> : 1440347 : 254:3 =3D> <0000000000011523> : 1440347 : 254:3 =3D> <000000000001f79d> : 1440347 : 254:3 =3D> <000000000001fb01> : 1440347 : 254:3 =3D> <000000000001fbc0> : 1440347 : 254:3 =3D> <000000000000eb7e> : 1440347 : 254:3 =3D> <0000000000029ca8> : 1340007 : 254:3 Use space tooling can use this information to get the actual functions from the files. Signed-off-by: Steven Rostedt (Google) --- Changes since v5: https://lore.kernel.org/20250424192613.869730948@goodmis.= org - Set inode to -1L if vma is not found for that address to let user space know that, and differentiate from a vdso section. kernel/trace/trace.c | 26 +++++++++++++++++++++++++- kernel/trace/trace_entries.h | 8 ++++++-- kernel/trace/trace_output.c | 27 +++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3e9ef644dd64..c6e1471e4615 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -3140,6 +3140,8 @@ static void trace_user_unwind_callback(struct unwind_= work *unwind, unsigned int trace_ctx; struct vm_area_struct *vma =3D NULL; unsigned long *caller; + unsigned long *inodes; + unsigned int *devs; unsigned int offset; int len; int i; @@ -3151,7 +3153,8 @@ static void trace_user_unwind_callback(struct unwind_= work *unwind, if (!(tr->trace_flags & TRACE_ITER_USERSTACKTRACE_DELAY)) return; =20 - len =3D trace->nr * sizeof(unsigned long) + sizeof(*entry); + len =3D trace->nr * (sizeof(unsigned long) * 2 + sizeof(unsigned int)) + + sizeof(*entry); =20 trace_ctx =3D tracing_gen_ctx(); =20 @@ -3172,6 +3175,15 @@ static void trace_user_unwind_callback(struct unwind= _work *unwind, entry->__data_loc_stack =3D offset | (len << 16); caller =3D (void *)entry + offset; =20 + offset +=3D len; + entry->__data_loc_inodes =3D offset | (len << 16); + inodes =3D (void *)entry + offset; + + offset +=3D len; + len =3D sizeof(unsigned int) * trace->nr; + entry->__data_loc_dev =3D offset | (len << 16); + devs =3D (void *)entry + offset; + for (i =3D 0; i < trace->nr; i++) { unsigned long addr =3D trace->entries[i]; =20 @@ -3180,9 +3192,21 @@ static void trace_user_unwind_callback(struct unwind= _work *unwind, =20 if (!vma) { caller[i] =3D addr; + /* Use -1 to denote no vma found */ + inodes[i] =3D -1L; + devs[i] =3D 0; continue; } + caller[i] =3D (addr - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); + + if (vma->vm_file && vma->vm_file->f_inode) { + inodes[i] =3D vma->vm_file->f_inode->i_ino; + devs[i] =3D vma->vm_file->f_inode->i_sb->s_dev; + } else { + inodes[i] =3D 0; + devs[i] =3D 0; + } } =20 __buffer_unlock_commit(buffer, event); diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h index 40dc53ead0a8..5f7b72359901 100644 --- a/kernel/trace/trace_entries.h +++ b/kernel/trace/trace_entries.h @@ -256,10 +256,14 @@ FTRACE_ENTRY(user_unwind_stack, userunwind_stack_entr= y, F_STRUCT( __field( u64, cookie ) __dynamic_array( unsigned long, stack ) + __dynamic_array( unsigned long, inodes ) + __dynamic_array( unsigned int, dev ) ), =20 - F_printk("cookie=3D%lld\n%s", __entry->cookie, - __print_dynamic_array(stack, sizeof(unsigned long))) + F_printk("cookie=3D%lld\n%s%s%s", __entry->cookie, + __print_dynamic_array(stack, sizeof(unsigned long)), + __print_dynamic_array(inodes, sizeof(unsigned long)), + __print_dynamic_array(dev, sizeof(unsigned long))) ); =20 FTRACE_ENTRY(user_unwind_cookie, userunwind_cookie_entry, diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 9489537533f7..437e5f23b73d 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -1410,9 +1410,13 @@ static enum print_line_t trace_user_unwind_stack_pri= nt(struct trace_iterator *it struct userunwind_stack_entry *field; struct trace_seq *s =3D &iter->seq; unsigned long *caller; + unsigned long *inodes; + unsigned int *devs; unsigned int offset; unsigned int len; unsigned int caller_cnt; + unsigned int inode_cnt; + unsigned int dev_cnt; unsigned int i; =20 trace_assign_type(field, iter->ent); @@ -1429,6 +1433,21 @@ static enum print_line_t trace_user_unwind_stack_pri= nt(struct trace_iterator *it =20 caller =3D (void *)iter->ent + offset; =20 + /* The inodes and devices are also dynamic pointers */ + offset =3D field->__data_loc_inodes; + len =3D offset >> 16; + offset =3D offset & 0xffff; + inode_cnt =3D len / sizeof(*inodes); + + inodes =3D (void *)iter->ent + offset; + + offset =3D field->__data_loc_dev; + len =3D offset >> 16; + offset =3D offset & 0xffff; + dev_cnt =3D len / sizeof(*devs); + + devs =3D (void *)iter->ent + offset; + for (i =3D 0; i < caller_cnt; i++) { unsigned long ip =3D caller[i]; =20 @@ -1437,6 +1456,14 @@ static enum print_line_t trace_user_unwind_stack_pri= nt(struct trace_iterator *it =20 trace_seq_puts(s, " =3D> "); seq_print_user_ip(s, NULL, ip, flags); + + if (i < inode_cnt) { + trace_seq_printf(s, " : %ld", inodes[i]); + if (i < dev_cnt) { + trace_seq_printf(s, " : %d:%d", + MAJOR(devs[i]), MINOR(devs[i])); + } + } trace_seq_putc(s, '\n'); } =20 --=20 2.50.1 From nobody Fri Oct 3 15:36:00 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DD0AF26E143; Thu, 28 Aug 2025 18:03:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756404217; cv=none; b=TkOJPQiIAb11m18h3Itg4V96rUlM1NHZVe9MKgGdoQnCp/8mwutm4tDQMGO2uJLO6HJjQ9/2uKyokKlbQGXMWnvIxZ13ig0PmYOqsuZ8YBlNCtgRDWc0d+Y9DZmWtGjcqLbQaDFNYLOZk47/L8+v0UzMm2DBRcVFAYsT5asVBVk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756404217; c=relaxed/simple; bh=TcYMw4TZuj8n6gPvf25Za15ZY5i9wM2Tt/cm2PhH12g=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=SztjPftQM5Q8wd1/zx9VcXTer4PeQTdHQknPx0kGPFlIoLf7Jpov9V/QiLeK3x5Ndk60rfArRuswuONO2ov8NOBOw2khc2J4YMsIG/II654Gux0oAxT7/vE0FIrNCTspIwbZnybCHOif6brcZP2+n/5tnp5/njTJ+t7ZrYlKmMQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YpaTHhyO; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="YpaTHhyO" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A445DC4CEF4; Thu, 28 Aug 2025 18:03:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756404216; bh=TcYMw4TZuj8n6gPvf25Za15ZY5i9wM2Tt/cm2PhH12g=; h=Date:From:To:Cc:Subject:References:From; b=YpaTHhyOZ1cenbrU2SF3pXIr3ko+8DibORAn8ukh8yG0ybAFyXbhdA/t4ZZ8I2gRo 9O2BGtIepXroU2uBR7VsCFjN3PJNYCCUH9WSqfGe4Z/ElYkYEZE7WeM5t9dr0HJSs6 +EQkaSefl9BXX0ghuhth7Bh9CFiHVpcKpObv9HlDbGn7sIe2ll4uFUOTu/vMKHaDO2 +mLJsouGjqQZjvtEAjWpiwdxc8Fzmb3wHy6uWC3Ovw4aQcGNp5meuyqDn/tmt08wTy HwXqsT3mhYSM2o9E55QHqpKJNMhMM95ILbqu6ZtEzxd0YYNPkt4jIACZrMW98YIK2z tWlilMQs/XAjQ== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1urgyb-00000004GDk-2Hxh; Thu, 28 Aug 2025 14:03:57 -0400 Message-ID: <20250828180357.394699143@kernel.org> User-Agent: quilt/0.68 Date: Thu, 28 Aug 2025 14:03:06 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, bpf@vger.kernel.org, x86@kernel.org Cc: Masami Hiramatsu , Mathieu Desnoyers , Josh Poimboeuf , Peter Zijlstra , Ingo Molnar , Jiri Olsa , Arnaldo Carvalho de Melo , Namhyung Kim , Thomas Gleixner , Andrii Nakryiko , Indu Bhagat , "Jose E. Marchesi" , Beau Belgrave , Jens Remus , Linus Torvalds , Andrew Morton , Florian Weimer , Sam James , Kees Cook , "Carlos O'Donell" Subject: [PATCH v6 6/6] tracing: Add an event to map the inodes to their file names References: <20250828180300.591225320@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Steven Rostedt The userstacktrace_delay stack trace shows for each frame of the listed stack, the address in the file of the code, the inode number of the file, and the device number of the file. This can be used by a user space tool to find exactly where the stack walk is in the source code. But the issue with this is that it also requires the tool to find the application on disk from its device number and inode. This can take a bit of time. The output of the usestacktrace_delay looks like this: trace-cmd-1053 [007] ..... 1290.400226: cookie=3D300000008 =3D> <000000000008f687> : 1340007 : 254:3 =3D> <0000000000014560> : 1488818 : 254:3 =3D> <000000000001f94a> : 1488818 : 254:3 =3D> <000000000001fc9e> : 1488818 : 254:3 =3D> <000000000001fcfa> : 1488818 : 254:3 =3D> <000000000000ebae> : 1488818 : 254:3 =3D> <0000000000029ca8> : 1340007 : 254:3 To help out, create a "inode_cache" that maps the device/inode to the path of the file. Use a rhashtable to store the device/inode as a key, and every time a new inode is added, it triggers a trace event that prints the device, inode and the path. A tool can use this trace event to find the paths without having to look for them on the device: trace-cmd start -B map -e inode_cache [..] trace-cmd show -B map [..] trace-cmd-1053 [007] ...1. 1290.400956: inode_cache: inode=3D134= 0007 dev=3D[254:3] path=3D/usr/lib/x86_64-linux-gnu/libc.so.6 trace-cmd-1053 [007] ...1. 1290.401175: inode_cache: inode=3D148= 8818 dev=3D[254:3] path=3D/usr/local/bin/trace-cmd trace-cmd-1053 [007] ...1. 1290.401249: inode_cache: inode=3D130= 8544 dev=3D[254:3] path=3D/usr/local/lib64/libtracefs.so.1.8.2 trace-cmd-1053 [007] ...1. 1290.401288: inode_cache: inode=3D131= 9848 dev=3D[254:3] path=3D/usr/local/lib64/libtraceevent.so.1.8.4 trace-cmd-1053 [007] ...1. 1290.401338: inode_cache: inode=3D131= 1769 dev=3D[254:3] path=3D/usr/lib/x86_64-linux-gnu/libzstd.so.1.5.7 bash-1044 [006] ...1. 1290.402620: inode_cache: inode=3D130= 8405 dev=3D[254:3] path=3D/usr/bin/bash bash-1044 [006] ...1. 1293.945511: inode_cache: inode=3D130= 9170 dev=3D[254:3] path=3D/usr/lib/x86_64-linux-gnu/libtinfo.so.6.5 trace-cmd-1054 [001] ...1. 1293.956178: inode_cache: inode=3D133= 9989 dev=3D[254:3] path=3D/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 less-1055 [000] ...1. 1293.962161: inode_cache: inode=3D130= 9556 dev=3D[254:3] path=3D/usr/bin/less trace-cmd-1054 [001] ...1. 1293.963118: inode_cache: inode=3D130= 9303 dev=3D[254:3] path=3D/usr/lib/x86_64-linux-gnu/libz.so.1.3.1 NetworkManager-592 [000] ...1. 1296.802760: inode_cache: inode=3D131= 0774 dev=3D[254:3] path=3D/usr/sbin/NetworkManager systemd-udevd-323 [002] ...1. 1327.342209: inode_cache: inode=3D130= 8579 dev=3D[254:3] path=3D/usr/lib/x86_64-linux-gnu/systemd/libsystemd-shar= ed-257.so sshd-session-1041 [001] ...1. 1352.996159: inode_cache: inode=3D157= 0224 dev=3D[254:3] path=3D/usr/lib/openssh/sshd-session The event is only triggered when a new inode device combo is added to the rhashtable. To help make sure new tracing can read this event, every time the trace starts and stops and some other changes to the tracing system occur, the cache is cleared so that it will show the paths again. Signed-off-by: Steven Rostedt (Google) --- kernel/trace/Makefile | 3 + kernel/trace/inode_cache.c | 144 +++++++++++++++++++++++++++++++ kernel/trace/trace.c | 15 +++- kernel/trace/trace.h | 10 +++ kernel/trace/trace_inode_cache.h | 42 +++++++++ 5 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 kernel/trace/inode_cache.c create mode 100644 kernel/trace/trace_inode_cache.h diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index dcb4e02afc5f..c13f8ec48dc2 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -71,6 +71,7 @@ obj-$(CONFIG_FUNCTION_GRAPH_TRACER) +=3D trace_functions_= graph.o obj-$(CONFIG_TRACE_BRANCH_PROFILING) +=3D trace_branch.o obj-$(CONFIG_BLK_DEV_IO_TRACE) +=3D blktrace.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) +=3D fgraph.o +obj-$(CONFIG_UNWIND_USER) +=3D inode_cache.o ifeq ($(CONFIG_BLOCK),y) obj-$(CONFIG_EVENT_TRACING) +=3D blktrace.o endif @@ -110,4 +111,6 @@ obj-$(CONFIG_FPROBE_EVENTS) +=3D trace_fprobe.o obj-$(CONFIG_TRACEPOINT_BENCHMARK) +=3D trace_benchmark.o obj-$(CONFIG_RV) +=3D rv/ =20 +CFLAGS_inode_cache.o :=3D -I$(src) + libftrace-y :=3D ftrace.o diff --git a/kernel/trace/inode_cache.c b/kernel/trace/inode_cache.c new file mode 100644 index 000000000000..bf177f7a5dad --- /dev/null +++ b/kernel/trace/inode_cache.c @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2025 Google, author: Steven Rostedt + */ +#include +#include "trace.h" + +#define CREATE_TRACE_POINTS +#include "trace_inode_cache.h" + +struct inode_cache_key { + unsigned long inode_nr; + unsigned long dev_nr; +}; + +struct inode_cache { + struct rhash_head rh; + struct inode_cache_key key; +}; + +struct inode_cache_hash { + struct rhashtable rhash; + struct rcu_head rcu; +}; + +static const struct rhashtable_params inode_cache_params =3D { + .nelem_hint =3D 32, + .key_len =3D sizeof(struct inode_cache_key), + .key_offset =3D offsetof(struct inode_cache, key), + .head_offset =3D offsetof(struct inode_cache, rh), +}; + +static DEFINE_MUTEX(inode_cache_mutex); +static struct inode_cache_hash *imhash; + +static void free_inode_cache(void *ptr, void *arg) +{ + kfree(ptr); +} + +static const char *get_vma_name(struct vm_area_struct *vma, char *buf, int= size) +{ + struct anon_vma_name *anon_name =3D anon_vma_name(vma); + const struct path *path; + + if (anon_name) + return anon_name->name; + + path =3D file_user_path(vma->vm_file); + + return d_path(path, buf, size); +} + +#define PATH_BUF_SZ 128 + +static void print_inode_vma(struct vm_area_struct *vma, + unsigned long inode, unsigned int dev) +{ + static char buf[PATH_BUF_SZ]; + const char *name; + + lockdep_assert_held(&inode_cache_mutex); + + name =3D get_vma_name(vma, buf, PATH_BUF_SZ); + + trace_inode_cache(inode, dev, name); +} + +/** + * trace_inode_cache_add - Add a inode/dev to the cache and trigger path t= race + * @vma: The vma that maps to the inode/dev + * @inode: The inode number of the vma->vm_file + * @dev: The device number of the vma->vm_file + * + * This is used to trigger the inode_cache trace event when a new inode/dev + * is added. This only gets called when that trace event is active. + * Whenever a inode/dev is added to the userstacktrace, this function + * gets called with the associated @vma and if it wasn't added before, it + * triggers the trace event that will write the @inode, @dev and lookup + * the file it is associated with. This can be used by user space tools to + * map the inode/dev in the userspace stack traces to their corresponding + * files. + * + * This gets reset when certain events happen in the tracefs system, such = as, + * enabling or disabling tracing, or enabling or disabling the deferred us= er + * space stack tracing. This is done to not miss events. + */ +void trace_inode_cache_add(struct vm_area_struct *vma, + unsigned long inode, unsigned int dev) +{ + struct inode_cache_hash *rht =3D READ_ONCE(imhash); + struct inode_cache_key key; + struct inode_cache *item; + + if (!vma->vm_file) + return; + + key.inode_nr =3D inode; + key.dev_nr =3D dev; + + /* First check if the inode, dev exist already */ + if (rht && rhashtable_lookup_fast(&rht->rhash, &key, inode_cache_params) = !=3D NULL) + return; + + guard(mutex)(&inode_cache_mutex); + + rht =3D imhash; + + /* Make sure it wasn't added between the lookup and taking the lock */ + if (rht && rhashtable_lookup_fast(&rht->rhash, &key, inode_cache_params) = !=3D NULL) + return; + + if (!rht) { + rht =3D kmalloc(sizeof(*rht), GFP_KERNEL); + if (!rht) + goto print; + if (rhashtable_init(&rht->rhash, &inode_cache_params) < 0) { + kfree(rht); + goto print; + } + imhash =3D rht; + } + + item =3D kmalloc(sizeof(*item), GFP_KERNEL); + if (!item) + goto print; + + item->key =3D key; + + rhashtable_insert_fast(&rht->rhash, &item->rh, inode_cache_params); + + print: + print_inode_vma(vma, inode, dev); +} + +void trace_inode_cache_reset(void) +{ + guard(mutex)(&inode_cache_mutex); + if (!imhash) + return; + rhashtable_free_and_destroy(&imhash->rhash, free_inode_cache, NULL); + kfree_rcu(imhash, rcu); + imhash =3D NULL; +} diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index c6e1471e4615..983b885fee88 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -57,6 +57,7 @@ =20 #include "trace.h" #include "trace_output.h" +#include "trace_inode_cache.h" =20 #ifdef CONFIG_FTRACE_STARTUP_TEST /* @@ -3203,6 +3204,9 @@ static void trace_user_unwind_callback(struct unwind_= work *unwind, if (vma->vm_file && vma->vm_file->f_inode) { inodes[i] =3D vma->vm_file->f_inode->i_ino; devs[i] =3D vma->vm_file->f_inode->i_sb->s_dev; + + if (trace_inode_cache_enabled()) + trace_inode_cache_add(vma, inodes[i], devs[i]); } else { inodes[i] =3D 0; devs[i] =3D 0; @@ -4979,9 +4983,10 @@ static int tracing_open(struct inode *inode, struct = file *file) trace_buf =3D &tr->max_buffer; #endif =20 - if (cpu =3D=3D RING_BUFFER_ALL_CPUS) + if (cpu =3D=3D RING_BUFFER_ALL_CPUS) { tracing_reset_online_cpus(trace_buf); - else + trace_inode_cache_reset(); + } else tracing_reset_cpu(trace_buf, cpu); } =20 @@ -5324,6 +5329,7 @@ int trace_keep_overwrite(struct tracer *tracer, u32 m= ask, int set) =20 static int update_unwind_deferred(struct trace_array *tr, int enabled) { + trace_inode_cache_reset(); if (enabled) { return unwind_deferred_init(&tr->unwinder, trace_user_unwind_callback); @@ -6041,6 +6047,7 @@ tracing_set_trace_read(struct file *filp, char __user= *ubuf, int tracer_init(struct tracer *t, struct trace_array *tr) { tracing_reset_online_cpus(&tr->array_buffer); + trace_inode_cache_reset(); return t->init(tr); } =20 @@ -7518,6 +7525,7 @@ int tracing_set_clock(struct trace_array *tr, const c= har *clockstr) * Reset the buffer so that it doesn't have incomparable timestamps. */ tracing_reset_online_cpus(&tr->array_buffer); + trace_inode_cache_reset(); =20 #ifdef CONFIG_TRACER_MAX_TRACE if (tr->max_buffer.buffer) @@ -9478,6 +9486,9 @@ rb_simple_write(struct file *filp, const char __user = *ubuf, if (ret) return ret; =20 + /* Cleare the inode cache whenever tracing starts or stops */ + trace_inode_cache_reset(); + if (buffer) { guard(mutex)(&trace_types_lock); if (!!val =3D=3D tracer_tracing_is_on(tr)) { diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 940107ba618a..d04563f088bf 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -450,6 +450,16 @@ struct trace_array { bool ring_buffer_expanded; }; =20 +#ifdef CONFIG_UNWIND_USER +void trace_inode_cache_add(struct vm_area_struct *vma, + unsigned long inode, unsigned int dev); +void trace_inode_cache_reset(void); +#else +static inline void trace_inode_cache_add(struct vm_area_struct *vma, + unsigned long inode, unsigned int dev) {} +static inline void trace_inode_cache_reset(void) {} +#endif + enum { TRACE_ARRAY_FL_GLOBAL =3D BIT(0), TRACE_ARRAY_FL_BOOT =3D BIT(1), diff --git a/kernel/trace/trace_inode_cache.h b/kernel/trace/trace_inode_ca= che.h new file mode 100644 index 000000000000..3a71d0104fbb --- /dev/null +++ b/kernel/trace/trace_inode_cache.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifdef CONFIG_UNWIND_USER +#undef TRACE_SYSTEM +#define TRACE_SYSTEM inode_cache + +#if !defined(_TRACE_inode_cache_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_inode_cache_H + +TRACE_EVENT(inode_cache, + + TP_PROTO(unsigned long inode, unsigned int dev, const char *path), + + TP_ARGS(inode, dev, path), + + TP_STRUCT__entry( + __field( unsigned long, inode ) + __field( unsigned int, dev ) + __string( path, path ) + ), + TP_fast_assign( + __entry->inode =3D inode; + __entry->dev =3D dev; + __assign_str(path); + ), + TP_printk("inode=3D%lu dev=3D[%u:%u] path=3D%s", + __entry->inode, MAJOR(__entry->dev), MINOR(__entry->dev), + __get_str(path)) +); + + +#endif /* if !defined(_TRACE_inode_cache_H) || defined(TRACE_HEADER_MULTI_= READ) */ + +#undef TRACE_INCLUDE_PATH +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE trace_inode_cache + +/* This part must be outside protection */ +#include +#else /* CONFIG_UNWIND_USER */ +static inline bool trace_inode_cache_enabled(void) { return false; } +#endif /* !CONFIG_UNWIND_USER */ --=20 2.50.1