Skip to content

Commit

Permalink
migration/multifd: Move header prepare/fill into send_prepare()
Browse files Browse the repository at this point in the history
This patch redefines the interfacing of ->send_prepare().  It further
simplifies multifd_send_thread() especially on zero copy.

Now with the new interface, we require the hook to do all the work for
preparing the IOVs to send.  After it's completed, the IOVs should be ready
to be dumped into the specific multifd QIOChannel later.

So now the API looks like:

  p->pages ----------->  send_prepare() -------------> IOVs

This also prepares for the case where the input can be extended to even not
any p->pages.  But that's for later.

This patch will achieve similar goal of what Fabiano used to propose here:

https://lore.kernel.org/r/20240126221943.26628-1-farosas@suse.de

However the send() interface may not be necessary.  I'm boldly attaching a
"Co-developed-by" for Fabiano.

Co-developed-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Link: https://lore.kernel.org/r/20240202102857.110210-14-peterx@redhat.com
Signed-off-by: Peter Xu <peterx@redhat.com>
  • Loading branch information
xzpeter committed Feb 5, 2024
1 parent 452b205 commit 25a1f87
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 33 deletions.
4 changes: 4 additions & 0 deletions migration/multifd-zlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ static int zlib_send_prepare(MultiFDSendParams *p, Error **errp)
int ret;
uint32_t i;

multifd_send_prepare_header(p);

for (i = 0; i < pages->num; i++) {
uint32_t available = z->zbuff_len - out_size;
int flush = Z_NO_FLUSH;
Expand Down Expand Up @@ -172,6 +174,8 @@ static int zlib_send_prepare(MultiFDSendParams *p, Error **errp)
p->next_packet_size = out_size;
p->flags |= MULTIFD_FLAG_ZLIB;

multifd_send_fill_packet(p);

return 0;
}

Expand Down
4 changes: 4 additions & 0 deletions migration/multifd-zstd.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ static int zstd_send_prepare(MultiFDSendParams *p, Error **errp)
int ret;
uint32_t i;

multifd_send_prepare_header(p);

z->out.dst = z->zbuff;
z->out.size = z->zbuff_len;
z->out.pos = 0;
Expand Down Expand Up @@ -161,6 +163,8 @@ static int zstd_send_prepare(MultiFDSendParams *p, Error **errp)
p->next_packet_size = z->out.pos;
p->flags |= MULTIFD_FLAG_ZSTD;

multifd_send_fill_packet(p);

return 0;
}

Expand Down
61 changes: 28 additions & 33 deletions migration/multifd.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ typedef struct {
/**
* nocomp_send_setup: setup send side
*
* For no compression this function does nothing.
*
* Returns 0 for success or -1 for error
*
* @p: Params for the channel that we are using
* @errp: pointer to an error
*/
static int nocomp_send_setup(MultiFDSendParams *p, Error **errp)
{
if (migrate_zero_copy_send()) {
p->write_flags |= QIO_CHANNEL_WRITE_FLAG_ZERO_COPY;
}

return 0;
}

Expand Down Expand Up @@ -88,7 +88,17 @@ static void nocomp_send_cleanup(MultiFDSendParams *p, Error **errp)
*/
static int nocomp_send_prepare(MultiFDSendParams *p, Error **errp)
{
bool use_zero_copy_send = migrate_zero_copy_send();
MultiFDPages_t *pages = p->pages;
int ret;

if (!use_zero_copy_send) {
/*
* Only !zerocopy needs the header in IOV; zerocopy will
* send it separately.
*/
multifd_send_prepare_header(p);
}

for (int i = 0; i < pages->num; i++) {
p->iov[p->iovs_num].iov_base = pages->block->host + pages->offset[i];
Expand All @@ -98,6 +108,18 @@ static int nocomp_send_prepare(MultiFDSendParams *p, Error **errp)

p->next_packet_size = pages->num * p->page_size;
p->flags |= MULTIFD_FLAG_NOCOMP;

multifd_send_fill_packet(p);

if (use_zero_copy_send) {
/* Send header first, without zerocopy */
ret = qio_channel_write_all(p->c, (void *)p->packet,
p->packet_len, errp);
if (ret != 0) {
return -1;
}
}

return 0;
}

Expand Down Expand Up @@ -266,7 +288,7 @@ static void multifd_pages_clear(MultiFDPages_t *pages)
g_free(pages);
}

static void multifd_send_fill_packet(MultiFDSendParams *p)
void multifd_send_fill_packet(MultiFDSendParams *p)
{
MultiFDPacket_t *packet = p->packet;
MultiFDPages_t *pages = p->pages;
Expand Down Expand Up @@ -688,7 +710,6 @@ static void *multifd_send_thread(void *opaque)
MigrationThread *thread = NULL;
Error *local_err = NULL;
int ret = 0;
bool use_zero_copy_send = migrate_zero_copy_send();

thread = migration_threads_add(p->name, qemu_get_thread_id());

Expand All @@ -713,15 +734,6 @@ static void *multifd_send_thread(void *opaque)
MultiFDPages_t *pages = p->pages;

p->iovs_num = 0;

if (!use_zero_copy_send) {
/*
* Only !zerocopy needs the header in IOV; zerocopy will
* send it separately.
*/
multifd_send_prepare_header(p);
}

assert(pages->num);

ret = multifd_send_state->ops->send_prepare(p, &local_err);
Expand All @@ -730,17 +742,6 @@ static void *multifd_send_thread(void *opaque)
break;
}

multifd_send_fill_packet(p);

if (use_zero_copy_send) {
/* Send header first, without zerocopy */
ret = qio_channel_write_all(p->c, (void *)p->packet,
p->packet_len, &local_err);
if (ret != 0) {
break;
}
}

ret = qio_channel_writev_full_all(p->c, p->iov, p->iovs_num, NULL,
0, p->write_flags, &local_err);
if (ret != 0) {
Expand Down Expand Up @@ -945,13 +946,7 @@ int multifd_save_setup(Error **errp)
p->iov = g_new0(struct iovec, page_count + 1);
p->page_size = qemu_target_page_size();
p->page_count = page_count;

if (migrate_zero_copy_send()) {
p->write_flags = QIO_CHANNEL_WRITE_FLAG_ZERO_COPY;
} else {
p->write_flags = 0;
}

p->write_flags = 0;
multifd_new_send_channel_create(p);
}

Expand Down
1 change: 1 addition & 0 deletions migration/multifd.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ typedef struct {
} MultiFDMethods;

void multifd_register_ops(int method, MultiFDMethods *ops);
void multifd_send_fill_packet(MultiFDSendParams *p);

static inline void multifd_send_prepare_header(MultiFDSendParams *p)
{
Expand Down

0 comments on commit 25a1f87

Please sign in to comment.