mirror of https://gitee.com/openkylin/qemu.git
pc-dimm: introduce get_vmstate_memory_region callback
This callback returns the MemoryRegion that is the memory of dimm should be kept during live migration nvdimm device is different with pc-dimm as its memory includes not only the MemoryRegion directly mapping to guest's address space but also the memory used as label data Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
f4eda2d429
commit
8df1426e44
|
@ -40,6 +40,8 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
|
||||||
int slot;
|
int slot;
|
||||||
MachineState *machine = MACHINE(qdev_get_machine());
|
MachineState *machine = MACHINE(qdev_get_machine());
|
||||||
PCDIMMDevice *dimm = PC_DIMM(dev);
|
PCDIMMDevice *dimm = PC_DIMM(dev);
|
||||||
|
PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
|
||||||
|
MemoryRegion *vmstate_mr = ddc->get_vmstate_memory_region(dimm);
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
uint64_t existing_dimms_capacity = 0;
|
uint64_t existing_dimms_capacity = 0;
|
||||||
uint64_t addr;
|
uint64_t addr;
|
||||||
|
@ -105,7 +107,7 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
|
||||||
}
|
}
|
||||||
|
|
||||||
memory_region_add_subregion(&hpms->mr, addr - hpms->base, mr);
|
memory_region_add_subregion(&hpms->mr, addr - hpms->base, mr);
|
||||||
vmstate_register_ram(mr, dev);
|
vmstate_register_ram(vmstate_mr, dev);
|
||||||
numa_set_mem_node_id(addr, memory_region_size(mr), dimm->node);
|
numa_set_mem_node_id(addr, memory_region_size(mr), dimm->node);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -116,10 +118,12 @@ void pc_dimm_memory_unplug(DeviceState *dev, MemoryHotplugState *hpms,
|
||||||
MemoryRegion *mr)
|
MemoryRegion *mr)
|
||||||
{
|
{
|
||||||
PCDIMMDevice *dimm = PC_DIMM(dev);
|
PCDIMMDevice *dimm = PC_DIMM(dev);
|
||||||
|
PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
|
||||||
|
MemoryRegion *vmstate_mr = ddc->get_vmstate_memory_region(dimm);
|
||||||
|
|
||||||
numa_unset_mem_node_id(dimm->addr, memory_region_size(mr), dimm->node);
|
numa_unset_mem_node_id(dimm->addr, memory_region_size(mr), dimm->node);
|
||||||
memory_region_del_subregion(&hpms->mr, mr);
|
memory_region_del_subregion(&hpms->mr, mr);
|
||||||
vmstate_unregister_ram(mr, dev);
|
vmstate_unregister_ram(vmstate_mr, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pc_existing_dimms_capacity_internal(Object *obj, void *opaque)
|
static int pc_existing_dimms_capacity_internal(Object *obj, void *opaque)
|
||||||
|
@ -424,6 +428,11 @@ static MemoryRegion *pc_dimm_get_memory_region(PCDIMMDevice *dimm)
|
||||||
return host_memory_backend_get_memory(dimm->hostmem, &error_abort);
|
return host_memory_backend_get_memory(dimm->hostmem, &error_abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MemoryRegion *pc_dimm_get_vmstate_memory_region(PCDIMMDevice *dimm)
|
||||||
|
{
|
||||||
|
return host_memory_backend_get_memory(dimm->hostmem, &error_abort);
|
||||||
|
}
|
||||||
|
|
||||||
static void pc_dimm_class_init(ObjectClass *oc, void *data)
|
static void pc_dimm_class_init(ObjectClass *oc, void *data)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||||
|
@ -434,6 +443,7 @@ static void pc_dimm_class_init(ObjectClass *oc, void *data)
|
||||||
dc->desc = "DIMM memory module";
|
dc->desc = "DIMM memory module";
|
||||||
|
|
||||||
ddc->get_memory_region = pc_dimm_get_memory_region;
|
ddc->get_memory_region = pc_dimm_get_memory_region;
|
||||||
|
ddc->get_vmstate_memory_region = pc_dimm_get_vmstate_memory_region;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TypeInfo pc_dimm_info = {
|
static TypeInfo pc_dimm_info = {
|
||||||
|
|
|
@ -61,7 +61,9 @@ typedef struct PCDIMMDevice {
|
||||||
* @realize: called after common dimm is realized so that the dimm based
|
* @realize: called after common dimm is realized so that the dimm based
|
||||||
* devices get the chance to do specified operations.
|
* devices get the chance to do specified operations.
|
||||||
* @get_memory_region: returns #MemoryRegion associated with @dimm which
|
* @get_memory_region: returns #MemoryRegion associated with @dimm which
|
||||||
* is directly mapped into the physical address space of guest
|
* is directly mapped into the physical address space of guest.
|
||||||
|
* @get_vmstate_memory_region: returns #MemoryRegion which indicates the
|
||||||
|
* memory of @dimm should be kept during live migration.
|
||||||
*/
|
*/
|
||||||
typedef struct PCDIMMDeviceClass {
|
typedef struct PCDIMMDeviceClass {
|
||||||
/* private */
|
/* private */
|
||||||
|
@ -70,6 +72,7 @@ typedef struct PCDIMMDeviceClass {
|
||||||
/* public */
|
/* public */
|
||||||
void (*realize)(PCDIMMDevice *dimm, Error **errp);
|
void (*realize)(PCDIMMDevice *dimm, Error **errp);
|
||||||
MemoryRegion *(*get_memory_region)(PCDIMMDevice *dimm);
|
MemoryRegion *(*get_memory_region)(PCDIMMDevice *dimm);
|
||||||
|
MemoryRegion *(*get_vmstate_memory_region)(PCDIMMDevice *dimm);
|
||||||
} PCDIMMDeviceClass;
|
} PCDIMMDeviceClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue