qemu/migration
Peter Xu 488c84acb4 migration/multifd: Optimize sender side to be lockless
When reviewing my attempt to refactor send_prepare(), Fabiano suggested we
try out with dropping the mutex in multifd code [1].

I thought about that before but I never tried to change the code.  Now
maybe it's time to give it a stab.  This only optimizes the sender side.

The trick here is multifd has a clear provider/consumer model, that the
migration main thread publishes requests (either pending_job/pending_sync),
while the multifd sender threads are consumers.  Here we don't have a lot
of complicated data sharing, and the jobs can logically be submitted
lockless.

Arm the code with atomic weapons.  Two things worth mentioning:

  - For multifd_send_pages(): we can use qatomic_load_acquire() when trying
  to find a free channel, but that's expensive if we attach one ACQUIRE per
  channel.  Instead, keep the qatomic_read() on reading the pending_job
  flag as we do already, meanwhile use one smp_mb_acquire() after the loop
  to guarantee the memory ordering.

  - For pending_sync: it doesn't have any extra data required since now
  p->flags are never touched, it should be safe to not use memory barrier.
  That's different from pending_job.

Provide rich comments for all the lockless operations to state how they are
paired.  With that, we can remove the mutex.

[1] https://lore.kernel.org/r/87o7d1jlu5.fsf@suse.de

Suggested-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Link: https://lore.kernel.org/r/20240202102857.110210-24-peterx@redhat.com
Signed-off-by: Peter Xu <peterx@redhat.com>
2024-02-06 11:05:49 +08:00
..
block-dirty-bitmap.c Replace "iothread lock" with "BQL" in comments 2024-01-08 10:45:43 -05:00
block.c Replace "iothread lock" with "BQL" in comments 2024-01-08 10:45:43 -05:00
block.h
channel-block.c
channel-block.h
channel.c
channel.h
colo-failover.c
colo.c Replace "iothread lock" with "BQL" in comments 2024-01-08 10:45:43 -05:00
dirtyrate.c system/cpus: rename qemu_mutex_lock_iothread() to bql_lock() 2024-01-08 10:45:43 -05:00
dirtyrate.h
exec.c
exec.h
fd.c
fd.h
file.c
file.h
global_state.c
meson.build
migration-hmp-cmds.c migration: Plug memory leak on HMP migrate error path 2024-01-29 11:02:12 +08:00
migration-stats.c
migration-stats.h
migration.c migration/multifd: Stick with send/recv on function names 2024-02-05 14:42:11 +08:00
migration.h migration: Centralize BH creation and dispatch 2024-01-29 11:02:12 +08:00
multifd-zlib.c migration/multifd: Move header prepare/fill into send_prepare() 2024-02-05 14:42:10 +08:00
multifd-zstd.c migration/multifd: Move header prepare/fill into send_prepare() 2024-02-05 14:42:10 +08:00
multifd.c migration/multifd: Optimize sender side to be lockless 2024-02-06 11:05:49 +08:00
multifd.h migration/multifd: Optimize sender side to be lockless 2024-02-06 11:05:49 +08:00
options.c
options.h
page_cache.c
page_cache.h
postcopy-ram.c userfaultfd: use 1ULL to build ioctl masks 2024-01-29 11:02:12 +08:00
postcopy-ram.h
qemu-file.c
qemu-file.h
ram-compress.c
ram-compress.h
ram.c migration/multifd: Change retval of multifd_queue_page() 2024-02-05 14:42:10 +08:00
ram.h
rdma.c migration/rdma: define htonll/ntohll only if not predefined 2024-01-16 11:16:10 +08:00
rdma.h
savevm.c migration: Centralize BH creation and dispatch 2024-01-29 11:02:12 +08:00
savevm.h
socket.c
socket.h
target.c
threadinfo.c
threadinfo.h
tls.c
tls.h
trace-events migration/multifd: Split multifd_send_terminate_threads() 2024-02-05 14:42:10 +08:00
trace.h
vmstate-types.c
vmstate.c
xbzrle.c
xbzrle.h
yank_functions.c migration/yank: Use channel features 2024-01-29 11:02:12 +08:00
yank_functions.h