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:
Xiao Guangrong 2016-06-07 20:21:57 +08:00 committed by Michael S. Tsirkin
parent f4eda2d429
commit 8df1426e44
2 changed files with 16 additions and 3 deletions

View File

@ -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 = {

View File

@ -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;
/** /**