On 10/24/2012 10:06 AM, liu ping fan wrote:
On Tue, Oct 23, 2012 at 8:25 PM, Stefan Hajnoczi stefanha@gmail.com wrote:
On Fri, Sep 21, 2012 at 01:17:21PM +0200, Vasilis Liaskovitis wrote:
+static void dimm_populate(DimmDevice *s) +{
- DeviceState *dev= (DeviceState*)s;
- MemoryRegion *new = NULL;
- new = g_malloc(sizeof(MemoryRegion));
- memory_region_init_ram(new, dev->id, s->size);
- vmstate_register_ram_global(new);
- memory_region_add_subregion(get_system_memory(), s->start, new);
- s->mr = new;
+}
+static void dimm_depopulate(DimmDevice *s) +{
- assert(s);
- vmstate_unregister_ram(s->mr, NULL);
- memory_region_del_subregion(get_system_memory(), s->mr);
- memory_region_destroy(s->mr);
- s->mr = NULL;
+}
How is dimm hot unplug protected against callers who currently have RAM mapped (from cpu_physical_memory_map())?
Emulated devices call cpu_physical_memory_map() directly or indirectly through DMA emulation code. The RAM pointer may be held for arbitrary lengths of time, across main loop iterations, etc.
It's not clear to me that it is safe to unplug a DIMM that has network or disk I/O buffers, for example. We also need to be robust against malicious guests who abuse the hotplug lifecycle. QEMU should never be left with dangling pointers.
Not sure about the block layer. But I think those thread are already out of big lock, so there should be a MemoryListener to catch the RAM-unplug event, and if needed, bdrv_flush.
IMO we should use the same mechanism as proposed for other devices: address_space_map() should grab a reference on the dimm device, and address_space_unmap() can release it. This way device destruction will be deferred as soon as all devices complete I/O.
We will have to be careful with network receive buffers though, since they can be held indefinitely.
On Wed, Oct 31, 2012 at 12:15 PM, Avi Kivity avi@redhat.com wrote:
On 10/24/2012 10:06 AM, liu ping fan wrote:
On Tue, Oct 23, 2012 at 8:25 PM, Stefan Hajnoczi stefanha@gmail.com wrote:
On Fri, Sep 21, 2012 at 01:17:21PM +0200, Vasilis Liaskovitis wrote:
+static void dimm_populate(DimmDevice *s) +{
- DeviceState *dev= (DeviceState*)s;
- MemoryRegion *new = NULL;
- new = g_malloc(sizeof(MemoryRegion));
- memory_region_init_ram(new, dev->id, s->size);
- vmstate_register_ram_global(new);
- memory_region_add_subregion(get_system_memory(), s->start, new);
- s->mr = new;
+}
+static void dimm_depopulate(DimmDevice *s) +{
- assert(s);
- vmstate_unregister_ram(s->mr, NULL);
- memory_region_del_subregion(get_system_memory(), s->mr);
- memory_region_destroy(s->mr);
- s->mr = NULL;
+}
How is dimm hot unplug protected against callers who currently have RAM mapped (from cpu_physical_memory_map())?
Emulated devices call cpu_physical_memory_map() directly or indirectly through DMA emulation code. The RAM pointer may be held for arbitrary lengths of time, across main loop iterations, etc.
It's not clear to me that it is safe to unplug a DIMM that has network or disk I/O buffers, for example. We also need to be robust against malicious guests who abuse the hotplug lifecycle. QEMU should never be left with dangling pointers.
Not sure about the block layer. But I think those thread are already out of big lock, so there should be a MemoryListener to catch the RAM-unplug event, and if needed, bdrv_flush.
IMO we should use the same mechanism as proposed for other devices: address_space_map() should grab a reference on the dimm device, and address_space_unmap() can release it. This way device destruction will be deferred as soon as all devices complete I/O.
We will have to be careful with network receive buffers though, since they can be held indefinitely.
Network receive buffers aren't mapped. Net receive is not zero-copy. For example, virtio-net does virtqueue_pop() inside virtio_net_receive().
I don't see a problem with networking.
Stefan