/* * At the end of migration, undo the effects of init_range * opaque should be the MIS. */ static int cleanup_range(const char *block_name, void *host_addr, ram_addr_t offset, ram_addr_t length, void *opaque) { MigrationIncomingState *mis = opaque; struct uffdio_range range_struct; trace_postcopy_cleanup_range(block_name, host_addr, offset, length); /* * We turned off hugepage for the precopy stage with postcopy enabled * we can turn it back on now. */ qemu_madvise(host_addr, length, QEMU_MADV_HUGEPAGE); /* * We can also turn off userfault now since we should have all the * pages. It can be useful to leave it on to debug postcopy * if you're not sure it's always getting every page. */ range_struct.start = (uintptr_t)host_addr; range_struct.len = length; if (ioctl(mis->userfault_fd, UFFDIO_UNREGISTER, &range_struct)) { error_report("%s: userfault unregister %s", __func__, strerror(errno)); return -1; } return 0; }
static void balloon_page(void *addr, int deflate) { if (!qemu_balloon_is_inhibited()) { qemu_madvise(addr, BALLOON_PAGE_SIZE, deflate ? QEMU_MADV_WILLNEED : QEMU_MADV_DONTNEED); } }
static void balloon_page(void *addr, int deflate) { #if defined(__linux__) if (!kvm_enabled() || kvm_has_sync_mmu()) qemu_madvise(addr, TARGET_PAGE_SIZE, deflate ? QEMU_MADV_WILLNEED : QEMU_MADV_DONTNEED); #endif }
static void balloon_page(void *addr, int deflate) { if (!qemu_balloon_is_inhibited() && (!kvm_enabled() || kvm_has_sync_mmu())) { qemu_madvise(addr, BALLOON_PAGE_SIZE, deflate ? QEMU_MADV_WILLNEED : QEMU_MADV_DONTNEED); } }
static void file_backend_unparent(Object *obj) { HostMemoryBackend *backend = MEMORY_BACKEND(obj); HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(obj); if (host_memory_backend_mr_inited(backend) && fb->discard_data) { void *ptr = memory_region_get_ram_ptr(&backend->mr); uint64_t sz = memory_region_size(&backend->mr); qemu_madvise(ptr, sz, QEMU_MADV_REMOVE); } }
/* * Disable huge pages on an area */ static int nhp_range(const char *block_name, void *host_addr, ram_addr_t offset, ram_addr_t length, void *opaque) { trace_postcopy_nhp_range(block_name, host_addr, offset, length); /* * Before we do discards we need to ensure those discards really * do delete areas of the page, even if THP thinks a hugepage would * be a good idea, so force hugepages off. */ qemu_madvise(host_addr, length, QEMU_MADV_NOHUGEPAGE); return 0; }
static void balloon_deflate_page(VirtIOBalloon *balloon, MemoryRegion *mr, hwaddr offset) { void *addr = memory_region_get_ram_ptr(mr) + offset; RAMBlock *rb; size_t rb_page_size; ram_addr_t ram_offset, host_page_base; void *host_addr; int ret; /* XXX is there a better way to get to the RAMBlock than via a * host address? */ rb = qemu_ram_block_from_host(addr, false, &ram_offset); rb_page_size = qemu_ram_pagesize(rb); host_page_base = ram_offset & ~(rb_page_size - 1); if (balloon->pbp && rb == balloon->pbp->rb && host_page_base == balloon->pbp->base) { int subpages = rb_page_size / BALLOON_PAGE_SIZE; /* * This means the guest has asked to discard some of the 4kiB * subpages of a host page, but then changed its mind and * asked to keep them after all. It's exceedingly unlikely * for a guest to do this in practice, but handle it anyway, * since getting it wrong could mean discarding memory the * guest is still using. */ bitmap_clear(balloon->pbp->bitmap, (ram_offset - balloon->pbp->base) / BALLOON_PAGE_SIZE, subpages); if (bitmap_empty(balloon->pbp->bitmap, subpages)) { g_free(balloon->pbp); balloon->pbp = NULL; } } host_addr = (void *)((uintptr_t)addr & ~(rb_page_size - 1)); /* When a page is deflated, we hint the whole host page it lives * on, since we can't do anything smaller */ ret = qemu_madvise(host_addr, rb_page_size, QEMU_MADV_WILLNEED); if (ret != 0) { warn_report("Couldn't MADV_WILLNEED on balloon deflate: %s", strerror(errno)); /* Otherwise ignore, failing to page hint shouldn't be fatal */ } }
static void qcow2_cache_table_release(BlockDriverState *bs, Qcow2Cache *c, int i, int num_tables) { #if QEMU_MADV_DONTNEED != QEMU_MADV_INVALID BDRVQcow2State *s = bs->opaque; void *t = qcow2_cache_get_table_addr(bs, c, i); int align = getpagesize(); size_t mem_size = (size_t) s->cluster_size * num_tables; size_t offset = QEMU_ALIGN_UP((uintptr_t) t, align) - (uintptr_t) t; size_t length = QEMU_ALIGN_DOWN(mem_size - offset, align); if (length > 0) { qemu_madvise((uint8_t *) t + offset, length, QEMU_MADV_DONTNEED); } #endif }
static void host_memory_backend_set_dump(Object *obj, bool value, Error **errp) { HostMemoryBackend *backend = MEMORY_BACKEND(obj); if (!memory_region_size(&backend->mr)) { backend->dump = value; return; } if (value != backend->dump) { void *ptr = memory_region_get_ram_ptr(&backend->mr); uint64_t sz = memory_region_size(&backend->mr); qemu_madvise(ptr, sz, value ? QEMU_MADV_DODUMP : QEMU_MADV_DONTDUMP); backend->dump = value; } }
static void host_memory_backend_memory_complete(UserCreatable *uc, Error **errp) { HostMemoryBackend *backend = MEMORY_BACKEND(uc); HostMemoryBackendClass *bc = MEMORY_BACKEND_GET_CLASS(uc); Error *local_err = NULL; void *ptr; uint64_t sz; if (bc->alloc) { bc->alloc(backend, &local_err); if (local_err) { error_propagate(errp, local_err); return; } ptr = memory_region_get_ram_ptr(&backend->mr); sz = memory_region_size(&backend->mr); if (backend->merge) { qemu_madvise(ptr, sz, QEMU_MADV_MERGEABLE); } if (!backend->dump) { qemu_madvise(ptr, sz, QEMU_MADV_DONTDUMP); } #ifdef CONFIG_NUMA unsigned long lastbit = find_last_bit(backend->host_nodes, MAX_NODES); /* lastbit == MAX_NODES means maxnode = 0 */ unsigned long maxnode = (lastbit + 1) % (MAX_NODES + 1); /* ensure policy won't be ignored in case memory is preallocated * before mbind(). note: MPOL_MF_STRICT is ignored on hugepages so * this doesn't catch hugepage case. */ unsigned flags = MPOL_MF_STRICT | MPOL_MF_MOVE; /* check for invalid host-nodes and policies and give more verbose * error messages than mbind(). */ if (maxnode && backend->policy == MPOL_DEFAULT) { error_setg(errp, "host-nodes must be empty for policy default," " or you should explicitly specify a policy other" " than default"); return; } else if (maxnode == 0 && backend->policy != MPOL_DEFAULT) { error_setg(errp, "host-nodes must be set for policy %s", HostMemPolicy_lookup[backend->policy]); return; } /* We can have up to MAX_NODES nodes, but we need to pass maxnode+1 * as argument to mbind() due to an old Linux bug (feature?) which * cuts off the last specified node. This means backend->host_nodes * must have MAX_NODES+1 bits available. */ assert(sizeof(backend->host_nodes) >= BITS_TO_LONGS(MAX_NODES + 1) * sizeof(unsigned long)); assert(maxnode <= MAX_NODES); if (mbind(ptr, sz, backend->policy, maxnode ? backend->host_nodes : NULL, maxnode + 1, flags)) { error_setg_errno(errp, errno, "cannot bind memory to host NUMA nodes"); return; } #endif /* Preallocate memory after the NUMA policy has been instantiated. * This is necessary to guarantee memory is allocated with * specified NUMA policy in place. */ if (backend->prealloc) { os_mem_prealloc(memory_region_get_fd(&backend->mr), ptr, sz); } } }