Linux Trace Kernel
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: Michael Wu <michael@allwinnertech.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>,
	Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
	linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org
Subject: Re: [PATCH v5] tracing: Fix race between update_event_fields and, event_define_fields
Date: Tue, 11 Aug 2026 09:00:45 -0400	[thread overview]
Message-ID: <20260811090045.2a3cbed9@gandalf.local.home> (raw)
In-Reply-To: <3f27bacf-5f01-8cb5-a04c-824ca7b2c13f@allwinnertech.com>

On Tue, 11 Aug 2026 14:00:05 +0800
Michael Wu <michael@allwinnertech.com> wrote:

> > What does the above mean? Are you loading two modules at the same time?  
> Two modules (A and B) are loaded simultaneously on different CPUs. On the arm64,
>  when CPU0's trace_module_notify [pri=1] and CPU1's trace_module_notify [pri=0] 
> simultaneously perform operations on call_A, because they are in different cache lines,
> CPU1 may observe WRITE_ONCE(head->next, &f->link) in step (4) before f->link.next=next in step (2).
>  At this time, CPU1 reads an uninitialized f->link.next and performs an operation that causes to crash.

This is still way too verbose. Is this AI written? If so, AI is *not* your friend.


> 
> > What does "pri=X notifier" mean? What function calls are these coming from?  
> `pri=X notifier` represents `trace_events.c:trace_module_notify [pri=1]` and `trace.c:trace_module_notify [pri=0]`, respectively.

Why are the priorities of the notifiers important here?

I honestly didn't know one was allowed to load two modules at the same time
and thought that it the module logic would prevent that. But if that's not
the case, then yeah, we need protection.


>  CPU0 (loads module A)                      CPU1 (loads module B)
>   ===============================            ===============================
>   load_module(A)                             load_module(B)
>     blocking_notifier_call_chain_robust        blocking_notifier_call_chain_robust
>          notifier_call_chain                     notifier_call_chain
>           nb = trace_events.c:                     nb = trace.c:
>           trace_module_notify [pri=1]              trace_module_notify [pri=0]
>             mutex_lock(&event_mutex)                 trace_event_update_all() 
>             trace_module_add_events(A)               down_write(&trace_event_sem) 
>               __register_event(call_A)                
>               __add_event_to_tracers(call_A)           
>                 event_define_fields(call_A)            
>                   for each f:                          
>                     f = kmem_cache_alloc()             
>                     list_add(&f->link,               	
>                              &class->fields)           
>                       f->link.next=next; (2)       	   
>                       WRITE_ONCE(head->next,        
>                                 &f->link); (4)       update_event_fields(call_A)   											           
>             mutex_unlock(&event_mutex)	               list_for_each_entry(field, 
>                                                          &class->fields, link) 
>                                                          field = class->fields->next 
>                                                                = &f->link 
>                                                        	       = f (offset 0) 
>                                                       up_write(&trace_event_sem)  

Basically this can be summed up to being:

 CPU0 (loads module A)                      CPU1 (loads module B)
 ===============================            ===============================
 load_module(A)                             load_module(B)
   notifier_call_chain                        notifier_call_chain
     trace_module_notify                        trace_module_notify
       mutex_lock(&event_mutex)                   trace_event_update_all() 
         trace_module_add_events(A)                 down_write(&trace_event_sem) 
            __register_event(call_A)                
              __add_event_to_tracers(call_A)           
                event_define_fields(call_A)            
                  for each f:                         list_for_each_entry(field, 
                    list_add(&f->link,                                    &class->fields, link) 
                             &class->fields)            field = class->fields->next;

Where you can see that one is being read while the other is being written
to. You do not need to go into details of the cache visibility here because
this is an obvious race condition. All that information just distracts from
the real issue that is being fixed.

Less is more when it comes to describing a bug.

I'll rewrite you change log and take the patch.

Thanks,

-- Steve

  reply	other threads:[~2026-08-11 13:00 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-10  6:32 [PATCH v5] tracing: Fix race between update_event_fields and, event_define_fields Michael Wu
2026-08-10 14:45 ` Steven Rostedt
2026-08-11  6:00   ` Michael Wu
2026-08-11 13:00     ` Steven Rostedt [this message]
2026-08-12  2:14       ` Michael Wu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260811090045.2a3cbed9@gandalf.local.home \
    --to=rostedt@goodmis.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=mhiramat@kernel.org \
    --cc=michael@allwinnertech.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox