On Tue, Oct 25, 2022 at 01:47:31AM -0300, Leonardo Bras wrote: > Zero-copy multifd migration sends both the header and the memory pages in a > single syscall. Since it's necessary to flush before reusing the header, a > header array was implemented, so each write call uses a different > array, and flushing only take place after all headers have been used, > meaning 1 flush for each N writes. > > This method has a bottleneck, though: After the last write, a flush will > have to wait for all writes to finish, which will be a lot, meaning the > recvmsg() syscall called in qio_channel_socket_flush() will be called a > lot. On top of that, it will create a time period when the I/O queue is > empty and nothing is getting send: between the flush and the next write. > > To avoid that, use qio_channel_flush()'s new max_pending parameter to wait > until at most half of the array is still in use. (i.e. the LRU half of the > array can be reused) > > Flushing for the LRU half of the array is much faster, since it does not > have to wait for the most recent writes to finish, making up for having > to flush twice per array. > > As a main benefit, this approach keeps the I/O queue from being empty while > there are still data to be sent, making it easier to keep the I/O maximum > throughput while consuming less cpu time.
Doesn't this defeat the reason for adding the flush in the first place, which was to ensure that a migration iteration was fully sent before starting the next iteration over RAM ? If it is OK to only partially flush on each iteration, then why do we need to flush at all ? With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|