Skip to content

Commit

Permalink
Merge tag 'next-pull-request' of https://gitlab.com/juan.quintela/qemu
Browse files Browse the repository at this point in the history
…into staging

Migration PULL request (take 2)

Hi

This time properly signed.

[take 1]
It includes:
- Leonardo fix for zero_copy flush
- Fiona fix for return value of readv/writev
- Peter Xu cleanups
- Peter Xu preempt patches
- Patches ready from zero page (me)
- AVX2 support (ling)
- fix for slow networking and reordering of first packets (manish)

Please, apply.

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEEGJn/jt6/WMzuA0uC9IfvGFhy1yMFAmNzsY0ACgkQ9IfvGFhy
# 1yP58A//XmJyLiS00+2Jro84Iu0HdiORmdry+bXLVtqcqIQsbzs1bgNZSeRPQ27t
# XBgx63owxnVmrErLqYknFD0sQ70xDG5Kw6S8MSf8Bo1fiPizni5hUciyBxKVqEeE
# mS/lH//mG9ZZtUeNmCIrJAaCIFhIvL37Hh4XPWJ0XB6h3RywnoRoihQZqBvUFVWw
# EbKclh5HsEwbJMbXhuA+5sOM/g1l/+eXI1JTjwMJ0A7G9toFrOXDCE8fmR9nmAuK
# p+dvOAj4EIeyHsdjqS8FwM3XBfewowpXy786MX6cY75+lYHKmbDQdiQYd9AUNlhZ
# wrVP5O94TuZV5mNJZgM9ZEqtyKfJZk0C22wGrNZ4RcpqiK+MCX70EABy1b1N+qnA
# 4UXmz7Ct00xXgmmhw9FtxfbTo0cTaVzNESHBYJ9p+DW5b2MrfQ591fHWtHWso9aZ
# IvtNOAwwGTXe2lZD00zWOtJdAN8GM+pbpjUmTjBq3StXsliQJOyh3izNAMF6lxcN
# 8i1WEafv/kFhsQGknEQ6HdoR+pZCJsRL5U3CUo/RtD0PHA08tbjp0kW1TKsHG/w4
# Qin1Bo6tRU76IZ8S1+5XxULVh/4UghSE0+5rGIvSYVEfNMW6IAEBR5GCs0xJj36Y
# W1OoqUH5QuyguOJoSYjt9VJXgwLMIeuOS93zCb8q5igIA819CIw=
# =hiKx
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 15 Nov 2022 10:34:37 EST
# gpg:                using RSA key 1899FF8EDEBF58CCEE034B82F487EF185872D723
# gpg: Good signature from "Juan Quintela <quintela@redhat.com>" [full]
# gpg:                 aka "Juan Quintela <quintela@trasno.org>" [full]
# Primary key fingerprint: 1899 FF8E DEBF 58CC EE03  4B82 F487 EF18 5872 D723

* tag 'next-pull-request' of https://gitlab.com/juan.quintela/qemu: (30 commits)
  migration: Block migration comment or code is wrong
  migration: Drop rs->f
  migration: Remove old preempt code around state maintainance
  migration: Send requested page directly in rp-return thread
  migration: Move last_sent_block into PageSearchStatus
  migration: Make PageSearchStatus part of RAMState
  migration: Add pss_init()
  migration: Introduce pss_channel
  migration: Teach PSS about host page
  migration: Use atomic ops properly for page accountings
  migration: Yield bitmap_mutex properly when sending/sleeping
  migration: Remove RAMState.f references in compression code
  migration: Trivial cleanup save_page_header() on same block check
  migration: Cleanup xbzrle zero page cache update logic
  migration: Add postcopy_preempt_active()
  migration: Take bitmap mutex when completing ram migration
  migration: Disable multifd explicitly with compression
  migration: Use non-atomic ops for clear log bitmap
  migration: Disallow postcopy preempt to be used with compress
  migration: Fix race on qemu_file_shutdown()
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
  • Loading branch information
stefanhaRH committed Nov 15, 2022
2 parents ab8aca7 + d896a7a commit b2d02b5
Show file tree
Hide file tree
Showing 28 changed files with 1,376 additions and 519 deletions.
11 changes: 6 additions & 5 deletions include/exec/ram_addr.h
Expand Up @@ -42,7 +42,8 @@ static inline long clear_bmap_size(uint64_t pages, uint8_t shift)
}

/**
* clear_bmap_set: set clear bitmap for the page range
* clear_bmap_set: set clear bitmap for the page range. Must be with
* bitmap_mutex held.
*
* @rb: the ramblock to operate on
* @start: the start page number
Expand All @@ -55,12 +56,12 @@ static inline void clear_bmap_set(RAMBlock *rb, uint64_t start,
{
uint8_t shift = rb->clear_bmap_shift;

bitmap_set_atomic(rb->clear_bmap, start >> shift,
clear_bmap_size(npages, shift));
bitmap_set(rb->clear_bmap, start >> shift, clear_bmap_size(npages, shift));
}

/**
* clear_bmap_test_and_clear: test clear bitmap for the page, clear if set
* clear_bmap_test_and_clear: test clear bitmap for the page, clear if set.
* Must be with bitmap_mutex held.
*
* @rb: the ramblock to operate on
* @page: the page number to check
Expand All @@ -71,7 +72,7 @@ static inline bool clear_bmap_test_and_clear(RAMBlock *rb, uint64_t page)
{
uint8_t shift = rb->clear_bmap_shift;

return bitmap_test_and_clear_atomic(rb->clear_bmap, page >> shift, 1);
return bitmap_test_and_clear(rb->clear_bmap, page >> shift, 1);
}

static inline bool offset_in_ramblock(RAMBlock *b, ram_addr_t offset)
Expand Down
3 changes: 3 additions & 0 deletions include/exec/ramblock.h
Expand Up @@ -53,6 +53,9 @@ struct RAMBlock {
* and split clearing of dirty bitmap on the remote node (e.g.,
* KVM). The bitmap will be set only when doing global sync.
*
* It is only used during src side of ram migration, and it is
* protected by the global ram_state.bitmap_mutex.
*
* NOTE: this bitmap is different comparing to the other bitmaps
* in that one bit can represent multiple guest pages (which is
* decided by the `clear_bmap_shift' variable below). On
Expand Down
25 changes: 25 additions & 0 deletions include/io/channel.h
Expand Up @@ -115,6 +115,10 @@ struct QIOChannelClass {
int **fds,
size_t *nfds,
Error **errp);
ssize_t (*io_read_peek)(QIOChannel *ioc,
void *buf,
size_t nbytes,
Error **errp);
int (*io_close)(QIOChannel *ioc,
Error **errp);
GSource * (*io_create_watch)(QIOChannel *ioc,
Expand Down Expand Up @@ -475,6 +479,27 @@ int qio_channel_write_all(QIOChannel *ioc,
size_t buflen,
Error **errp);

/**
* qio_channel_read_peek_all:
* @ioc: the channel object
* @buf: the memory region to read in data
* @nbytes: the number of bytes to read
* @errp: pointer to a NULL-initialized error object
*
* Read given @nbytes data from peek of channel into
* memory region @buf.
*
* The function will be blocked until read size is
* equal to requested size.
*
* Returns: 1 if all bytes were read, 0 if end-of-file
* occurs without data, or -1 on error
*/
int qio_channel_read_peek_all(QIOChannel *ioc,
void* buf,
size_t nbytes,
Error **errp);

/**
* qio_channel_set_blocking:
* @ioc: the channel object
Expand Down
1 change: 1 addition & 0 deletions include/qemu/bitmap.h
Expand Up @@ -253,6 +253,7 @@ void bitmap_set(unsigned long *map, long i, long len);
void bitmap_set_atomic(unsigned long *map, long i, long len);
void bitmap_clear(unsigned long *map, long start, long nr);
bool bitmap_test_and_clear_atomic(unsigned long *map, long start, long nr);
bool bitmap_test_and_clear(unsigned long *map, long start, long nr);
void bitmap_copy_and_clear_atomic(unsigned long *dst, unsigned long *src,
long nr);
unsigned long bitmap_find_next_zero_area(unsigned long *map,
Expand Down
27 changes: 27 additions & 0 deletions io/channel-socket.c
Expand Up @@ -705,6 +705,32 @@ static ssize_t qio_channel_socket_writev(QIOChannel *ioc,
}
#endif /* WIN32 */

static ssize_t qio_channel_socket_read_peek(QIOChannel *ioc,
void *buf,
size_t nbytes,
Error **errp)
{
QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
ssize_t bytes = 0;

retry:
bytes = recv(sioc->fd, buf, nbytes, MSG_PEEK);

if (bytes < 0) {
if (errno == EINTR) {
goto retry;
}
if (errno == EAGAIN) {
return QIO_CHANNEL_ERR_BLOCK;
}

error_setg_errno(errp, errno,
"Unable to read from peek of socket");
return -1;
}

return bytes;
}

#ifdef QEMU_MSG_ZEROCOPY
static int qio_channel_socket_flush(QIOChannel *ioc,
Expand Down Expand Up @@ -902,6 +928,7 @@ static void qio_channel_socket_class_init(ObjectClass *klass,

ioc_klass->io_writev = qio_channel_socket_writev;
ioc_klass->io_readv = qio_channel_socket_readv;
ioc_klass->io_read_peek = qio_channel_socket_read_peek;
ioc_klass->io_set_blocking = qio_channel_socket_set_blocking;
ioc_klass->io_close = qio_channel_socket_close;
ioc_klass->io_shutdown = qio_channel_socket_shutdown;
Expand Down
39 changes: 39 additions & 0 deletions io/channel.c
Expand Up @@ -346,6 +346,45 @@ int qio_channel_write_all(QIOChannel *ioc,
return qio_channel_writev_all(ioc, &iov, 1, errp);
}

int qio_channel_read_peek_all(QIOChannel *ioc,
void* buf,
size_t nbytes,
Error **errp)
{
QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc);
ssize_t bytes = 0;

if (!klass->io_read_peek) {
error_setg(errp, "Channel does not support read peek");
return -1;
}

while (bytes < nbytes) {
bytes = klass->io_read_peek(ioc,
buf,
nbytes,
errp);

if (bytes == QIO_CHANNEL_ERR_BLOCK) {
if (qemu_in_coroutine()) {
qio_channel_yield(ioc, G_IO_OUT);
} else {
qio_channel_wait(ioc, G_IO_OUT);
}
continue;
}
if (bytes == 0) {
error_setg(errp,
"Unexpected end-of-file on channel");
return 0;
}
if (bytes < 0) {
return -1;
}
}

return 1;
}

int qio_channel_set_blocking(QIOChannel *ioc,
bool enabled,
Expand Down
16 changes: 16 additions & 0 deletions meson.build
Expand Up @@ -2344,6 +2344,22 @@ config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
'''), error_message: 'AVX512F not available').allowed())

config_host_data.set('CONFIG_AVX512BW_OPT', get_option('avx512bw') \
.require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512BW') \
.require(cc.links('''
#pragma GCC push_options
#pragma GCC target("avx512bw")
#include <cpuid.h>
#include <immintrin.h>
static int bar(void *a) {
__m512i *x = a;
__m512i res= _mm512_abs_epi8(*x);
return res[1];
}
int main(int argc, char *argv[]) { return bar(argv[0]); }
'''), error_message: 'AVX512BW not available').allowed())

have_pvrdma = get_option('pvrdma') \
.require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \
.require(cc.compiles(gnu_source_prefix + '''
Expand Down
2 changes: 2 additions & 0 deletions meson_options.txt
Expand Up @@ -104,6 +104,8 @@ option('avx2', type: 'feature', value: 'auto',
description: 'AVX2 optimizations')
option('avx512f', type: 'feature', value: 'disabled',
description: 'AVX512F optimizations')
option('avx512bw', type: 'feature', value: 'auto',
description: 'AVX512BW optimizations')
option('keyring', type: 'feature', value: 'auto',
description: 'Linux keyring support')

Expand Down
4 changes: 2 additions & 2 deletions migration/block.c
Expand Up @@ -880,8 +880,8 @@ static void block_save_pending(QEMUFile *f, void *opaque, uint64_t max_size,
blk_mig_unlock();

/* Report at least one block pending during bulk phase */
if (pending <= max_size && !block_mig_state.bulk_completed) {
pending = max_size + BLK_MIG_BLOCK_SIZE;
if (!pending && !block_mig_state.bulk_completed) {
pending = BLK_MIG_BLOCK_SIZE;
}

trace_migration_block_save_pending(pending);
Expand Down
6 changes: 4 additions & 2 deletions migration/channel-block.c
Expand Up @@ -62,7 +62,8 @@ qio_channel_block_readv(QIOChannel *ioc,
qemu_iovec_init_external(&qiov, (struct iovec *)iov, niov);
ret = bdrv_readv_vmstate(bioc->bs, &qiov, bioc->offset);
if (ret < 0) {
return ret;
error_setg_errno(errp, -ret, "bdrv_readv_vmstate failed");
return -1;
}

bioc->offset += qiov.size;
Expand All @@ -86,7 +87,8 @@ qio_channel_block_writev(QIOChannel *ioc,
qemu_iovec_init_external(&qiov, (struct iovec *)iov, niov);
ret = bdrv_writev_vmstate(bioc->bs, &qiov, bioc->offset);
if (ret < 0) {
return ret;
error_setg_errno(errp, -ret, "bdrv_writev_vmstate failed");
return -1;
}

bioc->offset += qiov.size;
Expand Down

0 comments on commit b2d02b5

Please sign in to comment.