multifd_recv_cleanup() iterates over all receive channels twice:
one loop to join threads and another to clean up each channel.  Unlike
the send side where all threads must be signalled before any is joined
(to avoid deadlock), on the receive side the threads are already
terminated by multifd_recv_terminate_threads().  Each join simply
waits for an already-terminated thread, so the join and cleanup for
channel i are independent of channel j, and the two loops can safely
be merged into one.

This cuts the iteration count in half and improves locality: the
thread's resources are freed immediately after its join.

Signed-off-by: Bin Guo <[email protected]>
---
 migration/multifd.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/migration/multifd.c b/migration/multifd.c
index b3eef875cc..67ee9bdf5e 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -1153,15 +1153,14 @@ void multifd_recv_cleanup(void)
         return;
     }
     multifd_recv_terminate_threads(NULL);
+
     for (i = 0; i < migrate_multifd_channels(); i++) {
         MultiFDRecvParams *p = &multifd_recv_state->params[i];
 
         if (p->thread_created) {
             qemu_thread_join(&p->thread);
         }
-    }
-    for (i = 0; i < migrate_multifd_channels(); i++) {
-        multifd_recv_cleanup_channel(&multifd_recv_state->params[i]);
+        multifd_recv_cleanup_channel(p);
     }
     multifd_recv_cleanup_state();
 }
-- 
2.50.1 (Apple Git-155)


Reply via email to