mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 07:13:54 -06:00

For scarce memory resources, such as hugetlb, we want to be able to prealloc such memory resources in order to not crash later on access. On simple user errors we could otherwise easily run out of memory resources an crash the VM -- pretty much undesired. For ordinary memory devices, such as DIMMs, we preallocate memory via the memory backend for such use cases; however, with virtio-mem we're dealing with sparse memory backends; preallocating the whole memory backend destroys the whole purpose of virtio-mem. Instead, we want to preallocate memory when actually exposing memory to the VM dynamically, and fail plugging memory gracefully + warn the user in case preallocation fails. A common use case for hugetlb will be using "reserve=off,prealloc=off" for the memory backend and "prealloc=on" for the virtio-mem device. This way, no huge pages will be reserved for the process, but we can recover if there are no actual huge pages when plugging memory. Libvirt is already prepared for this. Note that preallocation cannot protect from the OOM killer -- which holds true for any kind of preallocation in QEMU. It's primarily useful only for scarce memory resources such as hugetlb, or shared file-backed memory. It's of little use for ordinary anonymous memory that can be swapped, KSM merged, ... but we won't forbid it. Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20211217134611.31172-9-david@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
87 lines
2.2 KiB
C
87 lines
2.2 KiB
C
/*
|
|
* Virtio MEM device
|
|
*
|
|
* Copyright (C) 2020 Red Hat, Inc.
|
|
*
|
|
* Authors:
|
|
* David Hildenbrand <david@redhat.com>
|
|
*
|
|
* This work is licensed under the terms of the GNU GPL, version 2.
|
|
* See the COPYING file in the top-level directory.
|
|
*/
|
|
|
|
#ifndef HW_VIRTIO_MEM_H
|
|
#define HW_VIRTIO_MEM_H
|
|
|
|
#include "standard-headers/linux/virtio_mem.h"
|
|
#include "hw/virtio/virtio.h"
|
|
#include "qapi/qapi-types-misc.h"
|
|
#include "sysemu/hostmem.h"
|
|
#include "qom/object.h"
|
|
|
|
#define TYPE_VIRTIO_MEM "virtio-mem"
|
|
|
|
OBJECT_DECLARE_TYPE(VirtIOMEM, VirtIOMEMClass,
|
|
VIRTIO_MEM)
|
|
|
|
#define VIRTIO_MEM_MEMDEV_PROP "memdev"
|
|
#define VIRTIO_MEM_NODE_PROP "node"
|
|
#define VIRTIO_MEM_SIZE_PROP "size"
|
|
#define VIRTIO_MEM_REQUESTED_SIZE_PROP "requested-size"
|
|
#define VIRTIO_MEM_BLOCK_SIZE_PROP "block-size"
|
|
#define VIRTIO_MEM_ADDR_PROP "memaddr"
|
|
#define VIRTIO_MEM_PREALLOC_PROP "prealloc"
|
|
|
|
struct VirtIOMEM {
|
|
VirtIODevice parent_obj;
|
|
|
|
/* guest -> host request queue */
|
|
VirtQueue *vq;
|
|
|
|
/* bitmap used to track unplugged memory */
|
|
int32_t bitmap_size;
|
|
unsigned long *bitmap;
|
|
|
|
/* assigned memory backend and memory region */
|
|
HostMemoryBackend *memdev;
|
|
|
|
/* NUMA node */
|
|
uint32_t node;
|
|
|
|
/* assigned address of the region in guest physical memory */
|
|
uint64_t addr;
|
|
|
|
/* usable region size (<= region_size) */
|
|
uint64_t usable_region_size;
|
|
|
|
/* actual size (how much the guest plugged) */
|
|
uint64_t size;
|
|
|
|
/* requested size */
|
|
uint64_t requested_size;
|
|
|
|
/* block size and alignment */
|
|
uint64_t block_size;
|
|
|
|
/* whether to prealloc memory when plugging new blocks */
|
|
bool prealloc;
|
|
|
|
/* notifiers to notify when "size" changes */
|
|
NotifierList size_change_notifiers;
|
|
|
|
/* listeners to notify on plug/unplug activity. */
|
|
QLIST_HEAD(, RamDiscardListener) rdl_list;
|
|
};
|
|
|
|
struct VirtIOMEMClass {
|
|
/* private */
|
|
VirtIODevice parent;
|
|
|
|
/* public */
|
|
void (*fill_device_info)(const VirtIOMEM *vmen, VirtioMEMDeviceInfo *vi);
|
|
MemoryRegion *(*get_memory_region)(VirtIOMEM *vmem, Error **errp);
|
|
void (*add_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier);
|
|
void (*remove_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier);
|
|
};
|
|
|
|
#endif
|