Peter Xu <[email protected]> writes: > QEMU incoming side may have set a wrong listen() backlog. After the > support of multifd + postcopy now we have four possibilities on setting the > backlog, some of them are wrong: > > Vanilla: 1 (correct) > Multifd: N (wrong, should be N+1) > Preempt: 2 (correct) > Multifd+Preempt: N (wrong, should be N+2) > > No real report for this, found by code observation only. Logically the > backlog (pending accept requests on destination on the listening sockets) > needs to be the maximum of possible channels. Otherwise if the accept > queue full on destination, source QEMU may hit connection errors. > > Cc: Daniel P. Berrangé <[email protected]> > Fixes: 0705e56496 ("multifd: Use number of channels as listen backlog") > Fixes: e274188612 ("migration: enable multifd and postcopy together") > Signed-off-by: Peter Xu <[email protected]> > --- > migration/socket.c | 25 ++++++++++++++++++------- > 1 file changed, 18 insertions(+), 7 deletions(-) > > diff --git a/migration/socket.c b/migration/socket.c > index f57f1a8e7c..31bfa1eeeb 100644 > --- a/migration/socket.c > +++ b/migration/socket.c > @@ -139,21 +139,32 @@ socket_incoming_migration_end(void *opaque) > object_unref(OBJECT(listener)); > } > > +static int socket_get_max_channels(void) > +{ > + /* The main channel is always wanted */ > + int num = 1; > + > + if (migrate_multifd()) { > + num += migrate_multifd_channels(); > + } > + > + if (migrate_postcopy_preempt()) { > + /* The preempt channel */ > + num += 1; > + } > + > + return num; > +} > + > void socket_connect_incoming(SocketAddress *saddr, Error **errp) > { > QIONetListener *listener = qio_net_listener_new(); > MigrationIncomingState *mis = migration_incoming_get_current(); > size_t i; > - int num = 1; > + int num = socket_get_max_channels(); > > qio_net_listener_set_name(listener, "migration-socket-listener"); > > - if (migrate_multifd()) { > - num = migrate_multifd_channels(); > - } else if (migrate_postcopy_preempt()) { > - num = RAM_CHANNEL_MAX; > - } > - > if (qio_net_listener_open_sync(listener, saddr, num, errp) < 0) { > object_unref(OBJECT(listener)); > return;
Reviewed-by: Fabiano Rosas <[email protected]>
