1
I saw various sanitizer errors when running check-qtest-ppc64. While
1
I saw various sanitizer errors when running check-qtest-ppc64. While
2
I could just turn off sanitizers, I decided to tackle them this time.
2
I could just turn off sanitizers, I decided to tackle them this time.
3
3
4
Unfortunately, GLib does not free test data in some cases so some
4
Unfortunately, GLib versions older than 2.81.0 do not free test data in
5
sanitizer errors remain. All sanitizer errors will be gone with this
5
some cases so some sanitizer errors remain. All sanitizer errors will be
6
patch series combined with the following change for GLib:
6
gone with this patch series combined with the following change for GLib:
7
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4120
7
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4120
8
8
9
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
9
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
10
---
10
---
11
Akihiko Odaki (14):
11
Changes in v7:
12
hw/core: Free CPUState allocations
12
- Don't open code memory_region_ref(). (Peter Xu)
13
hw/ide: Free macio-ide IRQs
13
- Link to v6: https://lore.kernel.org/r/20250105-san-v6-0-11fc859b99b7@daynix.com
14
hw/isa/vt82c686: Free irqs
14
15
spapr: Free stdout path
15
Changes in v6:
16
ppc/vof: Fix unaligned FDT property access
16
- Avoid referring owner as "the object that tracks the region's
17
hw/virtio: Free vqs before vhost_dev_cleanup()
17
reference count".
18
migration: Free removed SaveStateEntry
18
- Noted that memroy_region_ref() and memroy_region_unref() do nothing
19
if the owner is not present.
20
- Explicitly stated that memory_region_unref() may destroy the owner
21
along with the memory region itself.
22
- Link to v5: https://lore.kernel.org/r/20250104-san-v5-0-8b430457b09d@daynix.com
23
24
Changes in v5:
25
- Rebased.
26
- Merged four patches to update inline documentation into one
27
- Link to v4: https://lore.kernel.org/r/20240823-san-v4-0-a24c6dfa4ceb@daynix.com
28
29
Changes in v4:
30
- Changed to create a reference to the subregion instead of its owner
31
when its owner equals to the container's owner.
32
- Dropped R-b from patch "memory: Do not create circular reference with
33
subregion".
34
- Rebased.
35
- Link to v3: https://lore.kernel.org/r/20240708-san-v3-0-b03f671c40c6@daynix.com
36
37
Changes in v3:
38
- Added patch "memory: Clarify that we use owner's reference count".
39
- Added patch "memory: Refer to docs/devel/memory.rst for 'owner'".
40
- Fixed the message of patch
41
"memory: Do not create circular reference with subregion".
42
- Dropped patch "cpu: Free cpu_ases" in favor of:
43
https://lore.kernel.org/r/20240607115649.214622-7-salil.mehta@huawei.com/
44
("[PATCH V13 6/8] physmem: Add helper function to destroy CPU
45
AddressSpace")
46
- Dropped patches "hw/ide: Convert macio ide_irq into GPIO line" and
47
"hw/ide: Remove internal DMA qemu_irq" in favor of commit efb359346c7a
48
("hw/ide/macio: switch from using qemu_allocate_irq() to qdev input
49
GPIOs")
50
- Dropped patch "hw/isa/vt82c686: Define a GPIO line between vt82c686
51
and i8259" in favor of:
52
https://patchew.org/QEMU/20240704205854.18537-1-shentey@gmail.com/
53
("[PATCH 0/3] Resolve vt82c686 and piix4 qemu_irq memory leaks")
54
- Dropped pulled patches.
55
- Link to v2: https://lore.kernel.org/r/20240627-san-v2-0-750bb0946dbd@daynix.com
56
57
Changes in v2:
58
- Rebased to "[PATCH] cpu: fix memleak of 'halt_cond' and 'thread'".
59
(Philippe Mathieu-Daudé)
60
- Converted IRQs into GPIO lines and removed one qemu_irq usage.
61
(Peter Maydell)
62
- s/suppresses/fixes/ (Michael S. Tsirkin)
63
- Corrected title of patch "hw/virtio: Free vqs after vhost_dev_cleanup()"
64
(was "hw/virtio: Free vqs before vhost_dev_cleanup()")
65
- Link to v1: https://lore.kernel.org/r/20240626-san-v1-0-f3cc42302189@daynix.com
66
67
---
68
Akihiko Odaki (2):
69
memory: Update inline documentation
19
memory: Do not create circular reference with subregion
70
memory: Do not create circular reference with subregion
20
tests/qtest: Use qtest_add_data_func_full()
21
tests/qtest: Free unused QMP response
22
tests/qtest: Free old machine variable name
23
tests/qtest: Delete previous boot file
24
tests/qtest: Free paths
25
tests/qtest: Free GThread
26
71
27
hw/core/cpu-common.c | 3 +++
72
include/exec/memory.h | 59 ++++++++++++++++++++++++---------------------------
28
hw/ide/macio.c | 9 +++++++++
73
system/memory.c | 24 +++++++++++++++++++--
29
hw/isa/vt82c686.c | 3 ++-
74
2 files changed, 50 insertions(+), 33 deletions(-)
30
hw/ppc/spapr_vof.c | 2 +-
31
hw/ppc/vof.c | 2 +-
32
hw/virtio/vhost-user-base.c | 2 ++
33
migration/savevm.c | 2 ++
34
system/memory.c | 11 +++++++++--
35
tests/qtest/device-introspect-test.c | 7 +++----
36
tests/qtest/libqtest.c | 3 +++
37
tests/qtest/migration-test.c | 18 +++++++++++-------
38
tests/qtest/qos-test.c | 16 ++++++++++++----
39
tests/qtest/vhost-user-test.c | 6 +++---
40
13 files changed, 61 insertions(+), 23 deletions(-)
41
---
75
---
42
base-commit: 74abb45dac6979e7ff76172b7f0a24e869405184
76
base-commit: 38d0939b86e2eef6f6a622c6f1f7befda0146595
43
change-id: 20240625-san-097afaf4f1c2
77
change-id: 20240625-san-097afaf4f1c2
44
78
45
Best regards,
79
Best regards,
46
--
80
--
47
Akihiko Odaki <akihiko.odaki@daynix.com>
81
Akihiko Odaki <akihiko.odaki@daynix.com>
82
83
diff view generated by jsdifflib
Deleted patch
1
This suppresses LeakSanitizer warnings.
2
1
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
---
5
hw/core/cpu-common.c | 3 +++
6
1 file changed, 3 insertions(+)
7
8
diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c
9
index XXXXXXX..XXXXXXX 100644
10
--- a/hw/core/cpu-common.c
11
+++ b/hw/core/cpu-common.c
12
@@ -XXX,XX +XXX,XX @@ static void cpu_common_finalize(Object *obj)
13
{
14
CPUState *cpu = CPU(obj);
15
16
+ g_free(cpu->thread);
17
+ g_free(cpu->halt_cond);
18
+ g_free(cpu->cpu_ases);
19
g_array_free(cpu->gdb_regs, TRUE);
20
qemu_lockcnt_destroy(&cpu->in_ioctl_lock);
21
qemu_mutex_destroy(&cpu->work_mutex);
22
23
--
24
2.45.2
diff view generated by jsdifflib
Deleted patch
1
This suppresses LeakSanitizer warnings.
2
1
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
---
5
hw/ide/macio.c | 9 +++++++++
6
1 file changed, 9 insertions(+)
7
8
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
9
index XXXXXXX..XXXXXXX 100644
10
--- a/hw/ide/macio.c
11
+++ b/hw/ide/macio.c
12
@@ -XXX,XX +XXX,XX @@ static void macio_ide_initfn(Object *obj)
13
qdev_prop_allow_set_link_before_realize, 0);
14
}
15
16
+static void macio_ide_finalize(Object *obj)
17
+{
18
+ MACIOIDEState *s = MACIO_IDE(obj);
19
+
20
+ qemu_free_irq(s->dma_irq);
21
+ qemu_free_irq(s->ide_irq);
22
+}
23
+
24
static Property macio_ide_properties[] = {
25
DEFINE_PROP_UINT32("channel", MACIOIDEState, channel, 0),
26
DEFINE_PROP_UINT32("addr", MACIOIDEState, addr, -1),
27
@@ -XXX,XX +XXX,XX @@ static const TypeInfo macio_ide_type_info = {
28
.parent = TYPE_SYS_BUS_DEVICE,
29
.instance_size = sizeof(MACIOIDEState),
30
.instance_init = macio_ide_initfn,
31
+ .instance_finalize = macio_ide_finalize,
32
.class_init = macio_ide_class_init,
33
};
34
35
36
--
37
2.45.2
diff view generated by jsdifflib
Deleted patch
1
This suppresses LeakSanitizer warnings.
2
1
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
---
5
hw/isa/vt82c686.c | 3 ++-
6
1 file changed, 2 insertions(+), 1 deletion(-)
7
8
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
9
index XXXXXXX..XXXXXXX 100644
10
--- a/hw/isa/vt82c686.c
11
+++ b/hw/isa/vt82c686.c
12
@@ -XXX,XX +XXX,XX @@ static void via_isa_realize(PCIDevice *d, Error **errp)
13
14
qdev_init_gpio_out(dev, &s->cpu_intr, 1);
15
qdev_init_gpio_in_named(dev, via_isa_pirq, "pirq", PCI_NUM_PINS);
16
- isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
17
isa_bus = isa_bus_new(dev, pci_address_space(d), pci_address_space_io(d),
18
errp);
19
20
@@ -XXX,XX +XXX,XX @@ static void via_isa_realize(PCIDevice *d, Error **errp)
21
return;
22
}
23
24
+ isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
25
s->isa_irqs_in = i8259_init(isa_bus, *isa_irq);
26
+ qemu_free_irqs(isa_irq, 1);
27
isa_bus_register_input_irqs(isa_bus, s->isa_irqs_in);
28
i8254_pit_init(isa_bus, 0x40, 0, NULL);
29
i8257_dma_init(OBJECT(d), isa_bus, 0);
30
31
--
32
2.45.2
diff view generated by jsdifflib
Deleted patch
1
This suppresses LeakSanitizer warnings.
2
1
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
---
5
hw/ppc/spapr_vof.c | 2 +-
6
1 file changed, 1 insertion(+), 1 deletion(-)
7
8
diff --git a/hw/ppc/spapr_vof.c b/hw/ppc/spapr_vof.c
9
index XXXXXXX..XXXXXXX 100644
10
--- a/hw/ppc/spapr_vof.c
11
+++ b/hw/ppc/spapr_vof.c
12
@@ -XXX,XX +XXX,XX @@ target_ulong spapr_h_vof_client(PowerPCCPU *cpu, SpaprMachineState *spapr,
13
14
void spapr_vof_client_dt_finalize(SpaprMachineState *spapr, void *fdt)
15
{
16
- char *stdout_path = spapr_vio_stdout_path(spapr->vio_bus);
17
+ g_autofree char *stdout_path = spapr_vio_stdout_path(spapr->vio_bus);
18
19
vof_build_dt(fdt, spapr->vof);
20
21
22
--
23
2.45.2
diff view generated by jsdifflib
Deleted patch
1
FDT properties are aligned by 4 bytes, not 8 bytes.
2
1
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
---
5
hw/ppc/vof.c | 2 +-
6
1 file changed, 1 insertion(+), 1 deletion(-)
7
8
diff --git a/hw/ppc/vof.c b/hw/ppc/vof.c
9
index XXXXXXX..XXXXXXX 100644
10
--- a/hw/ppc/vof.c
11
+++ b/hw/ppc/vof.c
12
@@ -XXX,XX +XXX,XX @@ static void vof_dt_memory_available(void *fdt, GArray *claimed, uint64_t base)
13
mem0_reg = fdt_getprop(fdt, offset, "reg", &proplen);
14
g_assert(mem0_reg && proplen == sizeof(uint32_t) * (ac + sc));
15
if (sc == 2) {
16
- mem0_end = be64_to_cpu(*(uint64_t *)(mem0_reg + sizeof(uint32_t) * ac));
17
+ mem0_end = ldq_be_p(mem0_reg + sizeof(uint32_t) * ac);
18
} else {
19
mem0_end = be32_to_cpu(*(uint32_t *)(mem0_reg + sizeof(uint32_t) * ac));
20
}
21
22
--
23
2.45.2
diff view generated by jsdifflib
Deleted patch
1
This suppresses LeakSanitizer warnings.
2
1
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
---
5
hw/virtio/vhost-user-base.c | 2 ++
6
1 file changed, 2 insertions(+)
7
8
diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c
9
index XXXXXXX..XXXXXXX 100644
10
--- a/hw/virtio/vhost-user-base.c
11
+++ b/hw/virtio/vhost-user-base.c
12
@@ -XXX,XX +XXX,XX @@ static void vub_disconnect(DeviceState *dev)
13
{
14
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
15
VHostUserBase *vub = VHOST_USER_BASE(vdev);
16
+ struct vhost_virtqueue *vhost_vqs = vub->vhost_dev.vqs;
17
18
if (!vub->connected) {
19
return;
20
@@ -XXX,XX +XXX,XX @@ static void vub_disconnect(DeviceState *dev)
21
22
vub_stop(vdev);
23
vhost_dev_cleanup(&vub->vhost_dev);
24
+ g_free(vhost_vqs);
25
26
/* Re-instate the event handler for new connections */
27
qemu_chr_fe_set_handlers(&vub->chardev,
28
29
--
30
2.45.2
diff view generated by jsdifflib
Deleted patch
1
This suppresses LeakSanitizer warnings.
2
1
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
---
5
migration/savevm.c | 2 ++
6
1 file changed, 2 insertions(+)
7
8
diff --git a/migration/savevm.c b/migration/savevm.c
9
index XXXXXXX..XXXXXXX 100644
10
--- a/migration/savevm.c
11
+++ b/migration/savevm.c
12
@@ -XXX,XX +XXX,XX @@ int vmstate_replace_hack_for_ppc(VMStateIf *obj, int instance_id,
13
14
if (se) {
15
savevm_state_handler_remove(se);
16
+ g_free(se->compat);
17
+ g_free(se);
18
}
19
return vmstate_register(obj, instance_id, vmsd, opaque);
20
}
21
22
--
23
2.45.2
diff view generated by jsdifflib
1
These GThreads are never referenced.
1
Do not refer to "memory region's reference count"
2
-------------------------------------------------
3
4
Now MemoryRegions do have their own reference counts, but they will not
5
be used when their owners are not themselves. However, the documentation
6
of memory_region_ref() says it adds "1 to a memory region's reference
7
count", which is confusing. Avoid referring to "memory region's
8
reference count" and just say: "Add a reference to a memory region".
9
Make a similar change to memory_region_unref() too.
10
11
Refer to docs/devel/memory.rst for "owner"
12
------------------------------------------
13
14
memory_region_ref() and memory_region_unref() used to have their own
15
descriptions of "owner", but they are somewhat out-of-date and
16
misleading.
17
18
In particular, they say "whenever memory regions are accessed outside
19
the BQL, they need to be preserved against hot-unplug", but protecting
20
against hot-unplug is not mandatory if it is known that they will never
21
be hot-unplugged. They also say "MemoryRegions actually do not have
22
their own reference count", but they actually do. They just will not be
23
used unless their owners are not themselves.
24
25
Refer to docs/devel/memory.rst as the single source of truth instead of
26
maintaining duplicate descriptions of "owner".
27
28
Clarify that owner may be missing
29
30
---------------------------------
31
A memory region may not have an owner, and memory_region_ref() and
32
memory_region_unref() do nothing for such.
33
34
memory: Clarify owner must not call memory_region_ref()
35
--------------------------------------------------------
36
37
The owner must not call this function as it results in a circular
38
reference.
2
39
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
40
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
41
Reviewed-by: Peter Xu <peterx@redhat.com>
4
---
42
---
5
tests/qtest/vhost-user-test.c | 6 +++---
43
include/exec/memory.h | 59 ++++++++++++++++++++++++---------------------------
6
1 file changed, 3 insertions(+), 3 deletions(-)
44
1 file changed, 28 insertions(+), 31 deletions(-)
7
45
8
diff --git a/tests/qtest/vhost-user-test.c b/tests/qtest/vhost-user-test.c
46
diff --git a/include/exec/memory.h b/include/exec/memory.h
9
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
10
--- a/tests/qtest/vhost-user-test.c
48
--- a/include/exec/memory.h
11
+++ b/tests/qtest/vhost-user-test.c
49
+++ b/include/exec/memory.h
12
@@ -XXX,XX +XXX,XX @@ static void *vhost_user_test_setup_reconnect(GString *cmd_line, void *arg)
50
@@ -XXX,XX +XXX,XX @@ void memory_region_section_free_copy(MemoryRegionSection *s);
13
{
51
* memory_region_add_subregion() to add subregions.
14
TestServer *s = test_server_new("reconnect", arg);
52
*
15
53
* @mr: the #MemoryRegion to be initialized
16
- g_thread_new("connect", connect_thread, s);
54
- * @owner: the object that tracks the region's reference count
17
+ g_thread_unref(g_thread_new("connect", connect_thread, s));
55
+ * @owner: the object that keeps the region alive
18
append_mem_opts(s, cmd_line, 256, TEST_MEMFD_AUTO);
56
* @name: used for debugging; not visible to the user or ABI
19
s->vu_ops->append_opts(s, cmd_line, ",server=on");
57
* @size: size of the region; any subregions beyond this size will be clipped
20
58
*/
21
@@ -XXX,XX +XXX,XX @@ static void *vhost_user_test_setup_connect_fail(GString *cmd_line, void *arg)
59
@@ -XXX,XX +XXX,XX @@ void memory_region_init(MemoryRegion *mr,
22
60
uint64_t size);
23
s->test_fail = true;
61
24
62
/**
25
- g_thread_new("connect", connect_thread, s);
63
- * memory_region_ref: Add 1 to a memory region's reference count
26
+ g_thread_unref(g_thread_new("connect", connect_thread, s));
64
+ * memory_region_ref: Add a reference to the owner of a memory region
27
append_mem_opts(s, cmd_line, 256, TEST_MEMFD_AUTO);
65
*
28
s->vu_ops->append_opts(s, cmd_line, ",server=on");
66
- * Whenever memory regions are accessed outside the BQL, they need to be
29
67
- * preserved against hot-unplug. MemoryRegions actually do not have their
30
@@ -XXX,XX +XXX,XX @@ static void *vhost_user_test_setup_flags_mismatch(GString *cmd_line, void *arg)
68
- * own reference count; they piggyback on a QOM object, their "owner".
31
69
- * This function adds a reference to the owner.
32
s->test_flags = TEST_FLAGS_DISCONNECT;
70
- *
33
71
- * All MemoryRegions must have an owner if they can disappear, even if the
34
- g_thread_new("connect", connect_thread, s);
72
- * device they belong to operates exclusively under the BQL. This is because
35
+ g_thread_unref(g_thread_new("connect", connect_thread, s));
73
- * the region could be returned at any time by memory_region_find, and this
36
append_mem_opts(s, cmd_line, 256, TEST_MEMFD_AUTO);
74
- * is usually under guest control.
37
s->vu_ops->append_opts(s, cmd_line, ",server=on");
75
+ * This function adds a reference to the owner of a memory region to keep the
38
76
+ * memory region alive. It does nothing if the owner is not present as a memory
77
+ * region without owner will never die.
78
+ * For references internal to the owner, use object_ref() instead to avoid a
79
+ * circular reference.
80
+ * See docs/devel/memory.rst to know about owner.
81
*
82
* @mr: the #MemoryRegion
83
*/
84
void memory_region_ref(MemoryRegion *mr);
85
86
/**
87
- * memory_region_unref: Remove 1 to a memory region's reference count
88
+ * memory_region_unref: Remove a reference to the memory region of the owner
89
*
90
- * Whenever memory regions are accessed outside the BQL, they need to be
91
- * preserved against hot-unplug. MemoryRegions actually do not have their
92
- * own reference count; they piggyback on a QOM object, their "owner".
93
- * This function removes a reference to the owner and possibly destroys it.
94
+ * This function removes a reference to the owner of a memory region and
95
+ * possibly destroys the owner along with the memory region. It does nothing if
96
+ * the owner is not present.
97
+ * See docs/devel/memory.rst to know about owner.
98
*
99
* @mr: the #MemoryRegion
100
*/
101
@@ -XXX,XX +XXX,XX @@ void memory_region_unref(MemoryRegion *mr);
102
* if @size is nonzero, subregions will be clipped to @size.
103
*
104
* @mr: the #MemoryRegion to be initialized.
105
- * @owner: the object that tracks the region's reference count
106
+ * @owner: the object that keeps the region alive
107
* @ops: a structure containing read and write callbacks to be used when
108
* I/O is performed on the region.
109
* @opaque: passed to the read and write callbacks of the @ops structure.
110
@@ -XXX,XX +XXX,XX @@ void memory_region_init_io(MemoryRegion *mr,
111
* directly.
112
*
113
* @mr: the #MemoryRegion to be initialized.
114
- * @owner: the object that tracks the region's reference count
115
+ * @owner: the object that keeps the region alive
116
* @name: Region name, becomes part of RAMBlock name used in migration stream
117
* must be unique within any device
118
* @size: size of the region.
119
@@ -XXX,XX +XXX,XX @@ bool memory_region_init_ram_nomigrate(MemoryRegion *mr,
120
* modify memory directly.
121
*
122
* @mr: the #MemoryRegion to be initialized.
123
- * @owner: the object that tracks the region's reference count
124
+ * @owner: the object that keeps the region alive
125
* @name: Region name, becomes part of RAMBlock name used in migration stream
126
* must be unique within any device
127
* @size: size of the region.
128
@@ -XXX,XX +XXX,XX @@ bool memory_region_init_ram_flags_nomigrate(MemoryRegion *mr,
129
* canceled.
130
*
131
* @mr: the #MemoryRegion to be initialized.
132
- * @owner: the object that tracks the region's reference count
133
+ * @owner: the object that keeps the region alive
134
* @name: Region name, becomes part of RAMBlock name used in migration stream
135
* must be unique within any device
136
* @size: used size of the region.
137
@@ -XXX,XX +XXX,XX @@ bool memory_region_init_resizeable_ram(MemoryRegion *mr,
138
* mmap-ed backend.
139
*
140
* @mr: the #MemoryRegion to be initialized.
141
- * @owner: the object that tracks the region's reference count
142
+ * @owner: the object that keeps the region alive
143
* @name: Region name, becomes part of RAMBlock name used in migration stream
144
* must be unique within any device
145
* @size: size of the region.
146
@@ -XXX,XX +XXX,XX @@ bool memory_region_init_ram_from_file(MemoryRegion *mr,
147
* mmap-ed backend.
148
*
149
* @mr: the #MemoryRegion to be initialized.
150
- * @owner: the object that tracks the region's reference count
151
+ * @owner: the object that keeps the region alive
152
* @name: the name of the region.
153
* @size: size of the region.
154
* @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM,
155
@@ -XXX,XX +XXX,XX @@ bool memory_region_init_ram_from_fd(MemoryRegion *mr,
156
* region will modify memory directly.
157
*
158
* @mr: the #MemoryRegion to be initialized.
159
- * @owner: the object that tracks the region's reference count
160
+ * @owner: the object that keeps the region alive
161
* @name: Region name, becomes part of RAMBlock name used in migration stream
162
* must be unique within any device
163
* @size: size of the region.
164
@@ -XXX,XX +XXX,XX @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
165
* skip_dump flag.
166
*
167
* @mr: the #MemoryRegion to be initialized.
168
- * @owner: the object that tracks the region's reference count
169
+ * @owner: the object that keeps the region alive
170
* @name: the name of the region.
171
* @size: size of the region.
172
* @ptr: memory to be mapped; must contain at least @size bytes.
173
@@ -XXX,XX +XXX,XX @@ void memory_region_init_ram_device_ptr(MemoryRegion *mr,
174
* part of another memory region.
175
*
176
* @mr: the #MemoryRegion to be initialized.
177
- * @owner: the object that tracks the region's reference count
178
+ * @owner: the object that keeps the region alive
179
* @name: used for debugging; not visible to the user or ABI
180
* @orig: the region to be referenced; @mr will be equivalent to
181
* @orig between @offset and @offset + @size - 1.
182
@@ -XXX,XX +XXX,XX @@ void memory_region_init_alias(MemoryRegion *mr,
183
* of the caller.
184
*
185
* @mr: the #MemoryRegion to be initialized.
186
- * @owner: the object that tracks the region's reference count
187
+ * @owner: the object that keeps the region alive
188
* @name: Region name, becomes part of RAMBlock name used in migration stream
189
* must be unique within any device
190
* @size: size of the region.
191
@@ -XXX,XX +XXX,XX @@ bool memory_region_init_rom_nomigrate(MemoryRegion *mr,
192
* of the caller.
193
*
194
* @mr: the #MemoryRegion to be initialized.
195
- * @owner: the object that tracks the region's reference count
196
+ * @owner: the object that keeps the region alive
197
* @ops: callbacks for write access handling (must not be NULL).
198
* @opaque: passed to the read and write callbacks of the @ops structure.
199
* @name: Region name, becomes part of RAMBlock name used in migration stream
200
@@ -XXX,XX +XXX,XX @@ bool memory_region_init_rom_device_nomigrate(MemoryRegion *mr,
201
* @_iommu_mr: the #IOMMUMemoryRegion to be initialized
202
* @instance_size: the IOMMUMemoryRegion subclass instance size
203
* @mrtypename: the type name of the #IOMMUMemoryRegion
204
- * @owner: the object that tracks the region's reference count
205
+ * @owner: the object that keeps the region alive
206
* @name: used for debugging; not visible to the user or ABI
207
* @size: size of the region.
208
*/
209
@@ -XXX,XX +XXX,XX @@ void memory_region_init_iommu(void *_iommu_mr,
210
* region will modify memory directly.
211
*
212
* @mr: the #MemoryRegion to be initialized
213
- * @owner: the object that tracks the region's reference count (must be
214
+ * @owner: the object that keeps the region alive (must be
215
* TYPE_DEVICE or a subclass of TYPE_DEVICE, or NULL)
216
* @name: name of the memory region
217
* @size: size of the region in bytes
218
@@ -XXX,XX +XXX,XX @@ bool memory_region_init_ram_guest_memfd(MemoryRegion *mr,
219
* If you pass a non-NULL non-device @owner then we will assert.
220
*
221
* @mr: the #MemoryRegion to be initialized.
222
- * @owner: the object that tracks the region's reference count
223
+ * @owner: the object that keeps the region alive
224
* @name: Region name, becomes part of RAMBlock name used in migration stream
225
* must be unique within any device
226
* @size: size of the region.
227
@@ -XXX,XX +XXX,XX @@ bool memory_region_init_rom(MemoryRegion *mr,
228
* If you pass a non-NULL non-device @owner then we will assert.
229
*
230
* @mr: the #MemoryRegion to be initialized.
231
- * @owner: the object that tracks the region's reference count
232
+ * @owner: the object that keeps the region alive
233
* @ops: callbacks for write access handling (must not be NULL).
234
* @opaque: passed to the read and write callbacks of the @ops structure.
235
* @name: Region name, becomes part of RAMBlock name used in migration stream
39
236
40
--
237
--
41
2.45.2
238
2.47.1
diff view generated by jsdifflib
1
A memory region does not use their own reference counters, but instead
1
memory_region_update_container_subregions() used to call
2
piggybacks on another QOM object, "owner" (unless the owner is not the
2
memory_region_ref(), which creates a reference to the owner of the
3
memory region itself). When creating a subregion, a new reference to the
3
subregion, on behalf of the owner of the container. This results in a
4
owner of the container must be created. However, if the subregion is
4
circular reference if the subregion and container have the same owner.
5
owned by the same QOM object, this result in a self-reference, and make
5
6
the owner immortal. Avoid such a self-reference.
6
memory_region_ref() creates a reference to the owner instead of the
7
memory region to match the lifetime of the owner and memory region. We
8
do not need such a hack if the subregion and container have the same
9
owner because the owner will be alive as long as the container is.
10
Therefore, create a reference to the subregion itself instead ot its
11
owner in such a case; the reference to the subregion is still necessary
12
to ensure that the subregion gets finalized after the container.
7
13
8
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
14
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
9
---
15
---
10
system/memory.c | 11 +++++++++--
16
system/memory.c | 24 ++++++++++++++++++++++--
11
1 file changed, 9 insertions(+), 2 deletions(-)
17
1 file changed, 22 insertions(+), 2 deletions(-)
12
18
13
diff --git a/system/memory.c b/system/memory.c
19
diff --git a/system/memory.c b/system/memory.c
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/system/memory.c
21
--- a/system/memory.c
16
+++ b/system/memory.c
22
+++ b/system/memory.c
17
@@ -XXX,XX +XXX,XX @@ static void memory_region_update_container_subregions(MemoryRegion *subregion)
23
@@ -XXX,XX +XXX,XX @@ void memory_region_unref(MemoryRegion *mr)
18
24
}
19
memory_region_transaction_begin();
25
}
20
26
21
- memory_region_ref(subregion);
27
+static void memory_region_ref_subregion(MemoryRegion *subregion)
22
+ if (mr->owner != subregion->owner) {
28
+{
29
+ if (subregion->container->owner == subregion->owner) {
30
+ object_ref(OBJECT(subregion));
31
+ } else {
23
+ memory_region_ref(subregion);
32
+ memory_region_ref(subregion);
24
+ }
33
+ }
34
+}
35
+
36
+static void memory_region_unref_subregion(MemoryRegion *subregion)
37
+{
38
+ if (subregion->container->owner == subregion->owner) {
39
+ object_unref(OBJECT(subregion));
40
+ } else {
41
+ memory_region_unref(subregion);
42
+ }
43
+}
44
+
45
uint64_t memory_region_size(MemoryRegion *mr)
46
{
47
if (int128_eq(mr->size, int128_2_64())) {
48
@@ -XXX,XX +XXX,XX @@ static void memory_region_update_container_subregions(MemoryRegion *subregion)
49
50
memory_region_transaction_begin();
51
52
- memory_region_ref(subregion);
53
+ memory_region_ref_subregion(subregion);
25
+
54
+
26
QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
55
QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
27
if (subregion->priority >= other->priority) {
56
if (subregion->priority >= other->priority) {
28
QTAILQ_INSERT_BEFORE(other, subregion, subregions_link);
57
QTAILQ_INSERT_BEFORE(other, subregion, subregions_link);
29
@@ -XXX,XX +XXX,XX @@ void memory_region_del_subregion(MemoryRegion *mr,
58
@@ -XXX,XX +XXX,XX @@ void memory_region_del_subregion(MemoryRegion *mr,
30
assert(alias->mapped_via_alias >= 0);
59
assert(alias->mapped_via_alias >= 0);
31
}
60
}
32
QTAILQ_REMOVE(&mr->subregions, subregion, subregions_link);
61
QTAILQ_REMOVE(&mr->subregions, subregion, subregions_link);
33
- memory_region_unref(subregion);
62
- memory_region_unref(subregion);
34
+
63
+ memory_region_unref_subregion(subregion);
35
+ if (mr->owner != subregion->owner) {
36
+ memory_region_unref(subregion);
37
+ }
38
+
64
+
39
memory_region_update_pending |= mr->enabled && subregion->enabled;
65
memory_region_update_pending |= mr->enabled && subregion->enabled;
40
memory_region_transaction_commit();
66
memory_region_transaction_commit();
41
}
67
}
42
68
43
--
69
--
44
2.45.2
70
2.47.1
diff view generated by jsdifflib
Deleted patch
1
A test function may not be executed depending on the test command line
2
so it is wrong to free data with a test function. Use
3
qtest_add_data_func_full() to register a function to free data.
4
1
5
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
6
---
7
tests/qtest/device-introspect-test.c | 7 +++----
8
1 file changed, 3 insertions(+), 4 deletions(-)
9
10
diff --git a/tests/qtest/device-introspect-test.c b/tests/qtest/device-introspect-test.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tests/qtest/device-introspect-test.c
13
+++ b/tests/qtest/device-introspect-test.c
14
@@ -XXX,XX +XXX,XX @@ static void test_device_intro_concrete(const void *args)
15
16
qobject_unref(types);
17
qtest_quit(qts);
18
- g_free((void *)args);
19
}
20
21
static void test_abstract_interfaces(void)
22
@@ -XXX,XX +XXX,XX @@ static void add_machine_test_case(const char *mname)
23
24
path = g_strdup_printf("device/introspect/concrete/defaults/%s", mname);
25
args = g_strdup_printf("-M %s", mname);
26
- qtest_add_data_func(path, args, test_device_intro_concrete);
27
+ qtest_add_data_func_full(path, args, test_device_intro_concrete, g_free);
28
g_free(path);
29
30
path = g_strdup_printf("device/introspect/concrete/nodefaults/%s", mname);
31
args = g_strdup_printf("-nodefaults -M %s", mname);
32
- qtest_add_data_func(path, args, test_device_intro_concrete);
33
+ qtest_add_data_func_full(path, args, test_device_intro_concrete, g_free);
34
g_free(path);
35
}
36
37
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
38
qtest_add_func("device/introspect/abstract-interfaces", test_abstract_interfaces);
39
if (g_test_quick()) {
40
qtest_add_data_func("device/introspect/concrete/defaults/none",
41
- g_strdup(common_args), test_device_intro_concrete);
42
+ common_args, test_device_intro_concrete);
43
} else {
44
qtest_cb_for_every_machine(add_machine_test_case, true);
45
}
46
47
--
48
2.45.2
diff view generated by jsdifflib
Deleted patch
1
This suppresses LeakSanitizer warnings.
2
1
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
---
5
tests/qtest/libqtest.c | 2 ++
6
1 file changed, 2 insertions(+)
7
8
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
9
index XXXXXXX..XXXXXXX 100644
10
--- a/tests/qtest/libqtest.c
11
+++ b/tests/qtest/libqtest.c
12
@@ -XXX,XX +XXX,XX @@ QDict *qtest_qmp_receive(QTestState *s)
13
response, s->eventData)) {
14
/* Stash the event for a later consumption */
15
s->pending_events = g_list_append(s->pending_events, response);
16
+ } else {
17
+ qobject_unref(response);
18
}
19
}
20
}
21
22
--
23
2.45.2
diff view generated by jsdifflib
Deleted patch
1
This suppresses LeakSanitizer warnings.
2
1
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
---
5
tests/qtest/libqtest.c | 1 +
6
1 file changed, 1 insertion(+)
7
8
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
9
index XXXXXXX..XXXXXXX 100644
10
--- a/tests/qtest/libqtest.c
11
+++ b/tests/qtest/libqtest.c
12
@@ -XXX,XX +XXX,XX @@ static struct MachInfo *qtest_get_machines(const char *var)
13
int idx;
14
15
if (g_strcmp0(qemu_var, var)) {
16
+ g_free(qemu_var);
17
qemu_var = g_strdup(var);
18
19
/* new qemu, clear the cache */
20
21
--
22
2.45.2
diff view generated by jsdifflib
Deleted patch
1
A test run may create boot files several times. Delete the previous boot
2
file before creating a new one.
3
1
4
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
5
---
6
tests/qtest/migration-test.c | 18 +++++++++++-------
7
1 file changed, 11 insertions(+), 7 deletions(-)
8
9
diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tests/qtest/migration-test.c
12
+++ b/tests/qtest/migration-test.c
13
@@ -XXX,XX +XXX,XX @@ static char *bootpath;
14
#include "tests/migration/aarch64/a-b-kernel.h"
15
#include "tests/migration/s390x/a-b-bios.h"
16
17
+static void bootfile_delete(void)
18
+{
19
+ unlink(bootpath);
20
+ g_free(bootpath);
21
+ bootpath = NULL;
22
+}
23
+
24
static void bootfile_create(char *dir, bool suspend_me)
25
{
26
const char *arch = qtest_get_arch();
27
unsigned char *content;
28
size_t len;
29
30
+ if (bootpath) {
31
+ bootfile_delete();
32
+ }
33
+
34
bootpath = g_strdup_printf("%s/bootsect", dir);
35
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
36
/* the assembled x86 boot sector should be exactly one sector large */
37
@@ -XXX,XX +XXX,XX @@ static void bootfile_create(char *dir, bool suspend_me)
38
fclose(bootfile);
39
}
40
41
-static void bootfile_delete(void)
42
-{
43
- unlink(bootpath);
44
- g_free(bootpath);
45
- bootpath = NULL;
46
-}
47
-
48
/*
49
* Wait for some output in the serial output file,
50
* we get an 'A' followed by an endless string of 'B's
51
52
--
53
2.45.2
diff view generated by jsdifflib
Deleted patch
1
This suppresses LeakSanitizer warnings.
2
1
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
---
5
tests/qtest/qos-test.c | 16 ++++++++++++----
6
1 file changed, 12 insertions(+), 4 deletions(-)
7
8
diff --git a/tests/qtest/qos-test.c b/tests/qtest/qos-test.c
9
index XXXXXXX..XXXXXXX 100644
10
--- a/tests/qtest/qos-test.c
11
+++ b/tests/qtest/qos-test.c
12
@@ -XXX,XX +XXX,XX @@
13
static char *old_path;
14
15
16
-
17
/**
18
* qos_set_machines_devices_available(): sets availability of qgraph
19
* machines and devices.
20
@@ -XXX,XX +XXX,XX @@ static void subprocess_run_one_test(const void *arg)
21
g_test_trap_assert_passed();
22
}
23
24
+static void destroy_pathv(void *arg)
25
+{
26
+ g_free(((char **)arg)[0]);
27
+ g_free(arg);
28
+}
29
+
30
/*
31
* in this function, 2 path will be built:
32
* path_str, a one-string path (ex "pc/i440FX-pcihost/...")
33
@@ -XXX,XX +XXX,XX @@ static void walk_path(QOSGraphNode *orig_path, int len)
34
if (path->u.test.subprocess) {
35
gchar *subprocess_path = g_strdup_printf("/%s/%s/subprocess",
36
qtest_get_arch(), path_str);
37
- qtest_add_data_func(path_str, subprocess_path, subprocess_run_one_test);
38
- g_test_add_data_func(subprocess_path, path_vec, run_one_test);
39
+ qtest_add_data_func_full(path_str, subprocess_path,
40
+ subprocess_run_one_test, g_free);
41
+ g_test_add_data_func_full(subprocess_path, path_vec,
42
+ run_one_test, destroy_pathv);
43
} else {
44
- qtest_add_data_func(path_str, path_vec, run_one_test);
45
+ qtest_add_data_func_full(path_str, path_vec,
46
+ run_one_test, destroy_pathv);
47
}
48
49
g_free(path_str);
50
51
--
52
2.45.2
diff view generated by jsdifflib