Am 08.04.2013 um 10:38 schrieb Paolo Bonzini <pbonz...@redhat.com>: > Il 06/04/2013 00:06, Peter Lieven ha scritto: >>>> I think we should MADV_DONTNEED it. >> i have to correct myself, on Linux it seems that MADV_DONTNEED guarantees >> that >> subsequent reads will return a zero filled page. >> >> If I am right with that we could MADV_DONTNEED the memory on startup and keep >> not sending zero pages in bulk stage if we are running under Linux. Am I >> right with that? > > Actually we can use mmap+munmap to allocate a well-aligned, always zero > block for the RAM.
like this? diff --git a/exec.c b/exec.c index 786987a..dfd1ad3 100644 --- a/exec.c +++ b/exec.c @@ -1048,27 +1048,31 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, new_block->host = host; new_block->flags |= RAM_PREALLOC_MASK; } else { - if (mem_path) { + if (xen_enabled()) { + xen_ram_alloc(new_block->offset, size, mr); + memory_try_enable_merging(new_block->host, size); + } else { + if (mem_path) { #if defined (__linux__) && !defined(TARGET_S390X) - new_block->host = file_ram_alloc(new_block, size, mem_path); - if (!new_block->host) { - new_block->host = qemu_vmalloc(size); - memory_try_enable_merging(new_block->host, size); - } + new_block->host = file_ram_alloc(new_block, size, mem_path); #else - fprintf(stderr, "-mem-path option unsupported\n"); - exit(1); + fprintf(stderr, "-mem-path option unsupported\n"); + exit(1); #endif - } else { - if (xen_enabled()) { - xen_ram_alloc(new_block->offset, size, mr); - } else if (kvm_enabled()) { + } + if (!new_block->host && kvm_enabled()) { /* some s390/kvm configurations have special constraints */ new_block->host = kvm_vmalloc(size); - } else { - new_block->host = qemu_vmalloc(size); } - memory_try_enable_merging(new_block->host, size); + if (!new_block->host) { + new_block->host = mmap(0, size, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + if (new_block->host == MAP_FAILED) { + fprintf(stderr,"qemu_ram_alloc: can't mmap RAM pages %d\n",errno); + exit(1); + } + memory_try_enable_merging(new_block->host, size); + } } } new_block->length = size; @@ -1142,25 +1146,19 @@ void qemu_ram_free(ram_addr_t addr) ; } else if (mem_path) { #if defined (__linux__) && !defined(TARGET_S390X) + munmap(block->host, block->length); if (block->fd) { - munmap(block->host, block->length); close(block->fd); - } else { - qemu_vfree(block->host); } #else abort(); #endif } else { -#if defined(TARGET_S390X) && defined(CONFIG_KVM) - munmap(block->host, block->length); -#else if (xen_enabled()) { xen_invalidate_map_cache_entry(block->host); } else { - qemu_vfree(block->host); + munmap(block->host, block->length); } -#endif } g_free(block); break; diff --git a/kvm-all.c b/kvm-all.c index 9b433d3..90be8e3 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1742,7 +1742,7 @@ void *kvm_vmalloc(ram_addr_t size) return mem; } #endif - return qemu_vmalloc(size); + return NULL; } void kvm_setup_guest_memory(void *start, size_t size)