On 2024/10/13 16:31, Akihiko Odaki wrote:
call_rcu() callbacks may have potential memory leaks, but QEMU may
sometimes exit before draining the callbacks and leave the leaks
undetected by LeakSanitizer. For example, PCI devices register a
call_rcu() callback by calling address_space_destroy() and they will
not be freed until it gets drained. This hides memory leaks that
is going to happen when PCI devices loose references to the memory
allocations.

Call drain_call_rcu at exit to expose memory leaks by call_rcu()
callbacks deterministically.

I have revisited this older patch and decided to abandon it.

Adding atexit(drain_call_rcu) creates a deadlock scenario whenever a thread holding an RCU read lock waits on another thread that calls exit().

For example, this may occur during TCG migration:

1. ram_state_pending_sync() acquires an RCU read lock.
2. tcg_log_global_after_sync() waits on run_on_cpu() for a target vCPU.
3. If that target vCPU is handling an ARM semihosting exit, it calls
   exit() before servicing the queued work.
4. The atexit handler triggers and blocks, waiting for the migration
   thread's RCU reader.
5. The migration thread remains blocked waiting for the exiting vCPU.

This type of deadlock is too subtle and easily introduced inadvertently, so it is best to drop this approach.

Regards,
Akihiko Odaki

Reply via email to