On Mon,  2 Feb 2026 12:33:42 +0000
"jempty.liang" <[email protected]> wrote:

> Commit <66611c0475709607f398e2a5d691b1fc72fe9dfc>
>     (fgraph: Remove calltime and rettime from generic)
> incorrectly modified the offset values for calltime and rettime fields
> in the funcgraph_exit traceevent on 32-bit ARM, which are used to parse
> the corresponding values fromtrace rawdata. The actual memory offset of
> calltime is 20 (not 24), and rettime is 28 (not 32) for the 
> funcgraph_exit event.

OK, so this is a 32bit issue and not an ARM one. I was able to reproduce it
on 32bit x86 too.

Basically the problem is that the structure used to output the field offset
is out of sync with the actual fields of the structure.

> 
> Before the fix,the funcgraph_exit format was:
> 
> ~# cat /sys/kernel/tracing/events/ftrace/funcgraph_exit/format
> 
> name: funcgraph_exit
> ID: 10
> format:
>     ...
>     field:unsigned long long calltime; offset:24; size:8; signed:0;
>     field:unsigned long long rettime; offset:32; size:8; signed:0;
> 
> After the fix, the correct funcgraph_exit format is:
> 
> name: funcgraph_exit
> ID: 10
> format:
>     ...
>     field:unsigned long long calltime; offset:20; size:8; signed:0;
>     field:unsigned long long rettime; offset:28; size:8; signed:0;
> 

Thus, the way the calltime and rettime are defined is via:


> --- a/kernel/trace/trace_entries.h
> +++ b/kernel/trace/trace_entries.h
> @@ -127,8 +127,8 @@ FTRACE_ENTRY_PACKED(funcgraph_exit, 
> ftrace_graph_ret_entry,
>               __field_packed( unsigned long,  ret,            retval  )
>               __field_packed( unsigned int,   ret,            depth   )
>               __field_packed( unsigned int,   ret,            overrun )
> -             __field(unsigned long long,     calltime                )
> -             __field(unsigned long long,     rettime                 )

The __field() macro.

> +             __field_packed(unsigned long long,      ret,    calltime)
> +             __field_packed(unsigned long long,      ret,    rettime)

You converted it to a __field_packed() macro. The reason this worked is
because fields within a structure defined by __field_packed() has an
alignment of "1" to pack it.

Thus, your "fix" is simply hiding the real bug, which is that the alignment
algorithm is wrong.

Can you try this patch to see if it fixes the issue for you?

Thanks,

-- Steve

diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c
index 1698fc22afa0..68ef39cf0710 100644
--- a/kernel/trace/trace_export.c
+++ b/kernel/trace/trace_export.c
@@ -88,7 +88,9 @@ static void __always_unused ____ftrace_check_##name(void)     
        \
 #undef __field_ext
 #define __field_ext(_type, _item, _filter_type) {                      \
        .type = #_type, .name = #_item,                                 \
-       .size = sizeof(_type), .align = __alignof__(_type),             \
+       .size = sizeof(_type),                                          \
+       .align = __alignof__(_type) > __alignof__(long) ? __alignof__(long) :\
+               __alignof__(_type),                                     \
        is_signed_type(_type), .filter_type = _filter_type },
 
 


Reply via email to