提交 732bdd38 编写于 作者: D David Hildenbrand 提交者: Cornelia Huck

s390/sclp: temporarily fix unassignment/reassignment of memory subregions

Commit 374f2981 ("memory: protect current_map by RCU") broke
unassignment of standby memory on s390x. Looks like that the new
parallelism allows races with our (semi broken) memory hotplug code. The
flatview_unref() can now be executed after our unparenting. Therefore
memory_region_unref() tries to unreference the MemoryRegion itself instead
of the parent.

In theory, MemoryRegions are now bound to separate devices that control
their lifetime. We don't have this yet, so we really want to control their
lifetime manually.

This patch fixes it temporarily, until we have a proper rework. The only
drawback is that they won't pop up in "info qom-tree", but that's better
than qemu crashes.

We have to release the reference to a memory region after a
memory_region_find, as it automatically takes a reference. As we're now
able to reassign memory, the MemoryRegion is in fact deleted (otherwise
vmstate_register_ram() would complain).
Reviewed-by: NMatthew Rosato <mjrosato@linux.vnet.ibm.com>
Signed-off-by: NDavid Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: NCornelia Huck <cornelia.huck@de.ibm.com>
上级 35925a7a
......@@ -217,6 +217,7 @@ static void assign_storage(SCCB *sccb)
(assign_addr >= mhd->padded_ram_size)) {
/* Re-use existing memory region if found */
mr = memory_region_find(sysmem, assign_addr, 1).mr;
memory_region_unref(mr);
if (!mr) {
MemoryRegion *standby_ram = g_new(MemoryRegion, 1);
......@@ -242,6 +243,11 @@ static void assign_storage(SCCB *sccb)
}
memory_region_init_ram(standby_ram, NULL, id, this_subregion_size, &error_abort);
/* This is a hack to make memory hotunplug work again. Once we have
* subdevices, we have to unparent them when unassigning memory,
* instead of doing it via the ref count of the MemoryRegion. */
object_ref(OBJECT(standby_ram));
object_unparent(OBJECT(standby_ram));
vmstate_register_ram_global(standby_ram);
memory_region_add_subregion(sysmem, offset, standby_ram);
}
......@@ -269,6 +275,7 @@ static void unassign_storage(SCCB *sccb)
/* find the specified memory region and destroy it */
mr = memory_region_find(sysmem, unassign_addr, 1).mr;
memory_region_unref(mr);
if (mr) {
int i;
int is_removable = 1;
......@@ -287,8 +294,7 @@ static void unassign_storage(SCCB *sccb)
}
if (is_removable) {
memory_region_del_subregion(sysmem, mr);
object_unparent(OBJECT(mr));
g_free(mr);
object_unref(OBJECT(mr));
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册