diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-03-20 15:48:34 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-03-20 15:48:34 +0000 |
commit | ed627b2ad37469eeba9e9ed5fecfe315df9ecc60 (patch) | |
tree | aca1c6bddbaa61ffe2d029b123539fe20e6ecddc /exec.c | |
parent | 4aafb1b192e5d3685e94cefdce63343a86d64647 (diff) | |
parent | 1dc61e7b37d339c42ec9bd7a7eec1ef2c22f351c (diff) |
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
virtio,vhost,pci,pc: features, cleanups
SRAT tables for DIMM devices
new virtio net flags for speed/duplex
post-copy migration support in vhost
cleanups in pci
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
# gpg: Signature made Tue 20 Mar 2018 14:40:43 GMT
# gpg: using RSA key 281F0DB8D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg: aka "Michael S. Tsirkin <mst@redhat.com>"
# Primary key fingerprint: 0270 606B 6F3C DF3D 0B17 0970 C350 3912 AFBE 8E67
# Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA 8A0D 281F 0DB8 D28D 5469
* remotes/mst/tags/for_upstream: (51 commits)
postcopy shared docs
libvhost-user: Claim support for postcopy
postcopy: Allow shared memory
vhost: Huge page align and merge
vhost+postcopy: Wire up POSTCOPY_END notify
vhost-user: Add VHOST_USER_POSTCOPY_END message
libvhost-user: mprotect & madvises for postcopy
vhost+postcopy: Call wakeups
vhost+postcopy: Add vhost waker
postcopy: postcopy_notify_shared_wake
postcopy: helper for waking shared
vhost+postcopy: Resolve client address
postcopy-ram: add a stub for postcopy_request_shared_page
vhost+postcopy: Helper to send requests to source for shared pages
vhost+postcopy: Stash RAMBlock and offset
vhost+postcopy: Send address back to qemu
libvhost-user+postcopy: Register new regions with the ufd
migration/ram: ramblock_recv_bitmap_test_byte_offset
postcopy+vhost-user: Split set_mem_table for postcopy
vhost+postcopy: Transmit 'listen' to slave
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
# Conflicts:
# scripts/update-linux-headers.sh
Diffstat (limited to 'exec.c')
-rw-r--r-- | exec.c | 86 |
1 files changed, 72 insertions, 14 deletions
@@ -99,6 +99,11 @@ static MemoryRegion io_mem_unassigned; */ #define RAM_RESIZEABLE (1 << 2) +/* UFFDIO_ZEROPAGE is available on this RAMBlock to atomically + * zero the page and wake waiting processes. + * (Set during postcopy) + */ +#define RAM_UF_ZEROPAGE (1 << 3) #endif #ifdef TARGET_PAGE_BITS_VARY @@ -1790,6 +1795,17 @@ bool qemu_ram_is_shared(RAMBlock *rb) return rb->flags & RAM_SHARED; } +/* Note: Only set at the start of postcopy */ +bool qemu_ram_is_uf_zeroable(RAMBlock *rb) +{ + return rb->flags & RAM_UF_ZEROPAGE; +} + +void qemu_ram_set_uf_zeroable(RAMBlock *rb) +{ + rb->flags |= RAM_UF_ZEROPAGE; +} + /* Called with iothread lock held. */ void qemu_ram_set_idstr(RAMBlock *new_block, const char *name, DeviceState *dev) { @@ -2320,6 +2336,16 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr, return ramblock_ptr(block, addr); } +/* Return the offset of a hostpointer within a ramblock */ +ram_addr_t qemu_ram_block_host_offset(RAMBlock *rb, void *host) +{ + ram_addr_t res = (uint8_t *)host - (uint8_t *)rb->host; + assert((uintptr_t)host >= (uintptr_t)rb->host); + assert(res < rb->max_length); + + return res; +} + /* * Translates a host ptr back to a RAMBlock, a ram_addr and an offset * in that RAMBlock. @@ -3744,6 +3770,7 @@ int ram_block_discard_range(RAMBlock *rb, uint64_t start, size_t length) } if ((start + length) <= rb->used_length) { + bool need_madvise, need_fallocate; uint8_t *host_endaddr = host_startaddr + length; if ((uintptr_t)host_endaddr & (rb->page_size - 1)) { error_report("ram_block_discard_range: Unaligned end address: %p", @@ -3753,29 +3780,60 @@ int ram_block_discard_range(RAMBlock *rb, uint64_t start, size_t length) errno = ENOTSUP; /* If we are missing MADVISE etc */ - if (rb->page_size == qemu_host_page_size) { -#if defined(CONFIG_MADVISE) - /* Note: We need the madvise MADV_DONTNEED behaviour of definitely - * freeing the page. - */ - ret = madvise(host_startaddr, length, MADV_DONTNEED); -#endif - } else { - /* Huge page case - unfortunately it can't do DONTNEED, but - * it can do the equivalent by FALLOC_FL_PUNCH_HOLE in the - * huge page file. + /* The logic here is messy; + * madvise DONTNEED fails for hugepages + * fallocate works on hugepages and shmem + */ + need_madvise = (rb->page_size == qemu_host_page_size); + need_fallocate = rb->fd != -1; + if (need_fallocate) { + /* For a file, this causes the area of the file to be zero'd + * if read, and for hugetlbfs also causes it to be unmapped + * so a userfault will trigger. */ #ifdef CONFIG_FALLOCATE_PUNCH_HOLE ret = fallocate(rb->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, start, length); + if (ret) { + ret = -errno; + error_report("ram_block_discard_range: Failed to fallocate " + "%s:%" PRIx64 " +%zx (%d)", + rb->idstr, start, length, ret); + goto err; + } +#else + ret = -ENOSYS; + error_report("ram_block_discard_range: fallocate not available/file" + "%s:%" PRIx64 " +%zx (%d)", + rb->idstr, start, length, ret); + goto err; #endif } - if (ret) { - ret = -errno; - error_report("ram_block_discard_range: Failed to discard range " + if (need_madvise) { + /* For normal RAM this causes it to be unmapped, + * for shared memory it causes the local mapping to disappear + * and to fall back on the file contents (which we just + * fallocate'd away). + */ +#if defined(CONFIG_MADVISE) + ret = madvise(host_startaddr, length, MADV_DONTNEED); + if (ret) { + ret = -errno; + error_report("ram_block_discard_range: Failed to discard range " + "%s:%" PRIx64 " +%zx (%d)", + rb->idstr, start, length, ret); + goto err; + } +#else + ret = -ENOSYS; + error_report("ram_block_discard_range: MADVISE not available" "%s:%" PRIx64 " +%zx (%d)", rb->idstr, start, length, ret); + goto err; +#endif } + trace_ram_block_discard_range(rb->idstr, host_startaddr, length, + need_madvise, need_fallocate, ret); } else { error_report("ram_block_discard_range: Overrun block '%s' (%" PRIu64 "/%zx/" RAM_ADDR_FMT")", |