1
Based-on: <3ad18bc590ef28e1526e8053568086b453e7ffde.1718211878.git.quic_mathbern@quicinc.com>
2
("[PATCH] cpu: fix memleak of 'halt_cond' and 'thread'")
3
4
I saw various sanitizer errors when running check-qtest-ppc64. While
1
I saw various sanitizer errors when running check-qtest-ppc64. While
5
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.
6
3
7
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
8
sanitizer errors remain. All sanitizer errors will be gone with this
5
some cases so some sanitizer errors remain. All sanitizer errors will be
9
patch series combined with the following change for GLib:
6
gone with this patch series combined with the following change for GLib:
10
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4120
7
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4120
11
8
12
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
9
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
13
---
10
---
11
Changes in v7:
12
- Don't open code memory_region_ref(). (Peter Xu)
13
- Link to v6: https://lore.kernel.org/r/20250105-san-v6-0-11fc859b99b7@daynix.com
14
15
Changes in v6:
16
- Avoid referring owner as "the object that tracks the region's
17
reference count".
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
14
Changes in v2:
57
Changes in v2:
15
- Rebased to "[PATCH] cpu: fix memleak of 'halt_cond' and 'thread'".
58
- Rebased to "[PATCH] cpu: fix memleak of 'halt_cond' and 'thread'".
16
(Philippe Mathieu-Daudé)
59
(Philippe Mathieu-Daudé)
17
- Converted IRQs into GPIO lines and removed one qemu_irq usage.
60
- Converted IRQs into GPIO lines and removed one qemu_irq usage.
18
(Peter Maydell)
61
(Peter Maydell)
19
- s/suppresses/fixes/ (Michael S. Tsirkin)
62
- s/suppresses/fixes/ (Michael S. Tsirkin)
20
- Corrected title of patch "hw/virtio: Free vqs after vhost_dev_cleanup()"
63
- Corrected title of patch "hw/virtio: Free vqs after vhost_dev_cleanup()"
21
(was "hw/virtio: Free vqs before vhost_dev_cleanup()")
64
(was "hw/virtio: Free vqs before vhost_dev_cleanup()")
22
- Link to v1: https://lore.kernel.org/r/20240626-san-v1-0-f3cc42302189@daynix.com
65
- Link to v1: https://lore.kernel.org/r/20240626-san-v1-0-f3cc42302189@daynix.com
23
66
24
---
67
---
25
Akihiko Odaki (15):
68
Akihiko Odaki (2):
26
cpu: Free cpu_ases
69
memory: Update inline documentation
27
hw/ide: Convert macio ide_irq into GPIO line
28
hw/ide: Remove internal DMA qemu_irq
29
hw/isa/vt82c686: Define a GPIO line between vt82c686 and i8259
30
spapr: Free stdout path
31
ppc/vof: Fix unaligned FDT property access
32
hw/virtio: Free vqs after vhost_dev_cleanup()
33
migration: Free removed SaveStateEntry
34
memory: Do not create circular reference with subregion
70
memory: Do not create circular reference with subregion
35
tests/qtest: Use qtest_add_data_func_full()
36
tests/qtest: Free unused QMP response
37
tests/qtest: Free old machine variable name
38
tests/qtest: Delete previous boot file
39
tests/qtest: Free paths
40
tests/qtest: Free GThread
41
71
42
include/hw/ppc/mac_dbdma.h | 5 +++--
72
include/exec/memory.h | 59 ++++++++++++++++++++++++---------------------------
43
hw/core/cpu-common.c | 1 +
73
system/memory.c | 24 +++++++++++++++++++--
44
hw/ide/macio.c | 18 +++++++++++++-----
74
2 files changed, 50 insertions(+), 33 deletions(-)
45
hw/isa/vt82c686.c | 7 ++++---
46
hw/misc/macio/mac_dbdma.c | 10 +++++-----
47
hw/ppc/spapr_vof.c | 2 +-
48
hw/ppc/vof.c | 2 +-
49
hw/virtio/vhost-user-base.c | 2 ++
50
migration/savevm.c | 2 ++
51
system/memory.c | 11 +++++++++--
52
tests/qtest/device-introspect-test.c | 7 +++----
53
tests/qtest/libqtest.c | 3 +++
54
tests/qtest/migration-test.c | 18 +++++++++++-------
55
tests/qtest/qos-test.c | 16 ++++++++++++----
56
tests/qtest/vhost-user-test.c | 6 +++---
57
15 files changed, 73 insertions(+), 37 deletions(-)
58
---
75
---
59
base-commit: af799a2337c3e39994411f90631905d809a41da4
76
base-commit: 38d0939b86e2eef6f6a622c6f1f7befda0146595
60
change-id: 20240625-san-097afaf4f1c2
77
change-id: 20240625-san-097afaf4f1c2
61
78
62
Best regards,
79
Best regards,
63
--
80
--
64
Akihiko Odaki <akihiko.odaki@daynix.com>
81
Akihiko Odaki <akihiko.odaki@daynix.com>
65
82
66
83
diff view generated by jsdifflib
Deleted patch
1
This fixes LeakSanitizer warnings.
2
1
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
---
5
hw/core/cpu-common.c | 1 +
6
1 file changed, 1 insertion(+)
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
qemu_cond_destroy(cpu->halt_cond);
14
g_free(cpu->halt_cond);
15
g_free(cpu->thread);
16
+ g_free(cpu->cpu_ases);
17
}
18
19
static int64_t cpu_common_get_arch_id(CPUState *cpu)
20
21
--
22
2.45.2
diff view generated by jsdifflib
Deleted patch
1
macio ide_irq is connected to the IDE bus. This fixes the leak of
2
ide_irq.
3
1
4
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
5
---
6
hw/ide/macio.c | 11 ++++++++---
7
1 file changed, 8 insertions(+), 3 deletions(-)
8
9
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/hw/ide/macio.c
12
+++ b/hw/ide/macio.c
13
@@ -XXX,XX +XXX,XX @@ static void macio_ide_realizefn(DeviceState *dev, Error **errp)
14
s->bus.dma = &s->dma;
15
}
16
17
-static void pmac_ide_irq(void *opaque, int n, int level)
18
+static void pmac_irq(void *opaque, int n, int level)
19
{
20
MACIOIDEState *s = opaque;
21
uint32_t mask = 0x80000000u >> n;
22
@@ -XXX,XX +XXX,XX @@ static void pmac_ide_irq(void *opaque, int n, int level)
23
}
24
}
25
26
+static void pmac_ide_irq(void *opaque, int n, int level)
27
+{
28
+ pmac_irq(opaque, 1, level);
29
+}
30
+
31
static void macio_ide_initfn(Object *obj)
32
{
33
SysBusDevice *d = SYS_BUS_DEVICE(obj);
34
@@ -XXX,XX +XXX,XX @@ static void macio_ide_initfn(Object *obj)
35
sysbus_init_mmio(d, &s->mem);
36
sysbus_init_irq(d, &s->real_ide_irq);
37
sysbus_init_irq(d, &s->real_dma_irq);
38
- s->dma_irq = qemu_allocate_irq(pmac_ide_irq, s, 0);
39
- s->ide_irq = qemu_allocate_irq(pmac_ide_irq, s, 1);
40
+ s->dma_irq = qemu_allocate_irq(pmac_irq, s, 0);
41
+ qdev_init_gpio_in_named_with_opaque(DEVICE(obj), pmac_ide_irq, s, NULL, 1);
42
43
object_property_add_link(obj, "dbdma", TYPE_MAC_DBDMA,
44
(Object **) &s->dbdma,
45
46
--
47
2.45.2
diff view generated by jsdifflib
Deleted patch
1
A function pointer is sufficient for internal usage. Replacing qemu_irq
2
with one fixes the leak of qemu_irq.
3
1
4
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
5
---
6
include/hw/ppc/mac_dbdma.h | 5 +++--
7
hw/ide/macio.c | 11 +++++++----
8
hw/misc/macio/mac_dbdma.c | 10 +++++-----
9
3 files changed, 15 insertions(+), 11 deletions(-)
10
11
diff --git a/include/hw/ppc/mac_dbdma.h b/include/hw/ppc/mac_dbdma.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/include/hw/ppc/mac_dbdma.h
14
+++ b/include/hw/ppc/mac_dbdma.h
15
@@ -XXX,XX +XXX,XX @@
16
typedef struct DBDMA_io DBDMA_io;
17
18
typedef void (*DBDMA_flush)(DBDMA_io *io);
19
+typedef void (*DBDMA_irq)(DBDMA_io *io);
20
typedef void (*DBDMA_rw)(DBDMA_io *io);
21
typedef void (*DBDMA_end)(DBDMA_io *io);
22
struct DBDMA_io {
23
@@ -XXX,XX +XXX,XX @@ typedef struct dbdma_cmd {
24
typedef struct DBDMA_channel {
25
int channel;
26
uint32_t regs[DBDMA_REGS];
27
- qemu_irq irq;
28
+ DBDMA_irq irq;
29
DBDMA_io io;
30
DBDMA_rw rw;
31
DBDMA_flush flush;
32
@@ -XXX,XX +XXX,XX @@ typedef struct DBDMAState DBDMAState;
33
34
/* Externally callable functions */
35
36
-void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
37
+void DBDMA_register_channel(void *dbdma, int nchan, DBDMA_irq irq,
38
DBDMA_rw rw, DBDMA_flush flush,
39
void *opaque);
40
void DBDMA_kick(DBDMAState *dbdma);
41
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/ide/macio.c
44
+++ b/hw/ide/macio.c
45
@@ -XXX,XX +XXX,XX @@ static void macio_ide_realizefn(DeviceState *dev, Error **errp)
46
s->bus.dma = &s->dma;
47
}
48
49
-static void pmac_irq(void *opaque, int n, int level)
50
+static void pmac_irq(MACIOIDEState *s, int n, int level)
51
{
52
- MACIOIDEState *s = opaque;
53
uint32_t mask = 0x80000000u >> n;
54
55
/* We need to reflect the IRQ state in the irq register */
56
@@ -XXX,XX +XXX,XX @@ static void pmac_irq(void *opaque, int n, int level)
57
}
58
}
59
60
+static void pmac_dma_irq(DBDMA_io *io)
61
+{
62
+ pmac_irq(io->opaque, 0, 1);
63
+}
64
+
65
static void pmac_ide_irq(void *opaque, int n, int level)
66
{
67
pmac_irq(opaque, 1, level);
68
@@ -XXX,XX +XXX,XX @@ static void macio_ide_initfn(Object *obj)
69
sysbus_init_mmio(d, &s->mem);
70
sysbus_init_irq(d, &s->real_ide_irq);
71
sysbus_init_irq(d, &s->real_dma_irq);
72
- s->dma_irq = qemu_allocate_irq(pmac_irq, s, 0);
73
qdev_init_gpio_in_named_with_opaque(DEVICE(obj), pmac_ide_irq, s, NULL, 1);
74
75
object_property_add_link(obj, "dbdma", TYPE_MAC_DBDMA,
76
@@ -XXX,XX +XXX,XX @@ void macio_ide_init_drives(MACIOIDEState *s, DriveInfo **hd_table)
77
78
void macio_ide_register_dma(MACIOIDEState *s)
79
{
80
- DBDMA_register_channel(s->dbdma, s->channel, s->dma_irq,
81
+ DBDMA_register_channel(s->dbdma, s->channel, pmac_dma_irq,
82
pmac_ide_transfer, pmac_ide_flush, s);
83
}
84
85
diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/hw/misc/macio/mac_dbdma.c
88
+++ b/hw/misc/macio/mac_dbdma.c
89
@@ -XXX,XX +XXX,XX @@ static void kill_channel(DBDMA_channel *ch)
90
ch->regs[DBDMA_STATUS] |= DEAD;
91
ch->regs[DBDMA_STATUS] &= ~ACTIVE;
92
93
- qemu_irq_raise(ch->irq);
94
+ ch->irq(&ch->io);
95
}
96
97
static void conditional_interrupt(DBDMA_channel *ch)
98
@@ -XXX,XX +XXX,XX @@ static void conditional_interrupt(DBDMA_channel *ch)
99
case INTR_NEVER: /* don't interrupt */
100
return;
101
case INTR_ALWAYS: /* always interrupt */
102
- qemu_irq_raise(ch->irq);
103
+ ch->irq(&ch->io);
104
DBDMA_DPRINTFCH(ch, "%s: raise\n", __func__);
105
return;
106
}
107
@@ -XXX,XX +XXX,XX @@ static void conditional_interrupt(DBDMA_channel *ch)
108
switch(intr) {
109
case INTR_IFSET: /* intr if condition bit is 1 */
110
if (cond) {
111
- qemu_irq_raise(ch->irq);
112
+ ch->irq(&ch->io);
113
DBDMA_DPRINTFCH(ch, "%s: raise\n", __func__);
114
}
115
return;
116
case INTR_IFCLR: /* intr if condition bit is 0 */
117
if (!cond) {
118
- qemu_irq_raise(ch->irq);
119
+ ch->irq(&ch->io);
120
DBDMA_DPRINTFCH(ch, "%s: raise\n", __func__);
121
}
122
return;
123
@@ -XXX,XX +XXX,XX @@ void DBDMA_kick(DBDMAState *dbdma)
124
qemu_bh_schedule(dbdma->bh);
125
}
126
127
-void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
128
+void DBDMA_register_channel(void *dbdma, int nchan, DBDMA_irq irq,
129
DBDMA_rw rw, DBDMA_flush flush,
130
void *opaque)
131
{
132
133
--
134
2.45.2
diff view generated by jsdifflib
Deleted patch
1
This fixes qemu_irq array leak.
2
1
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
---
5
hw/isa/vt82c686.c | 7 ++++---
6
1 file changed, 4 insertions(+), 3 deletions(-)
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
ViaISAState *s = VIA_ISA(d);
14
DeviceState *dev = DEVICE(d);
15
PCIBus *pci_bus = pci_get_bus(d);
16
- qemu_irq *isa_irq;
17
+ qemu_irq isa_irq;
18
ISABus *isa_bus;
19
int i;
20
21
qdev_init_gpio_out(dev, &s->cpu_intr, 1);
22
qdev_init_gpio_in_named(dev, via_isa_pirq, "pirq", PCI_NUM_PINS);
23
- isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
24
+ qdev_init_gpio_in_named(dev, via_isa_request_i8259_irq, "i8259", 1);
25
+ isa_irq = qdev_get_gpio_in_named(dev, "i8259", 0);
26
isa_bus = isa_bus_new(dev, pci_address_space(d), pci_address_space_io(d),
27
errp);
28
29
@@ -XXX,XX +XXX,XX @@ static void via_isa_realize(PCIDevice *d, Error **errp)
30
return;
31
}
32
33
- s->isa_irqs_in = i8259_init(isa_bus, *isa_irq);
34
+ s->isa_irqs_in = i8259_init(isa_bus, isa_irq);
35
isa_bus_register_input_irqs(isa_bus, s->isa_irqs_in);
36
i8254_pit_init(isa_bus, 0x40, 0, NULL);
37
i8257_dma_init(OBJECT(d), isa_bus, 0);
38
39
--
40
2.45.2
diff view generated by jsdifflib
Deleted patch
1
This fixes LeakSanitizer warnings.
2
1
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
---
6
hw/ppc/spapr_vof.c | 2 +-
7
1 file changed, 1 insertion(+), 1 deletion(-)
8
9
diff --git a/hw/ppc/spapr_vof.c b/hw/ppc/spapr_vof.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/hw/ppc/spapr_vof.c
12
+++ b/hw/ppc/spapr_vof.c
13
@@ -XXX,XX +XXX,XX @@ target_ulong spapr_h_vof_client(PowerPCCPU *cpu, SpaprMachineState *spapr,
14
15
void spapr_vof_client_dt_finalize(SpaprMachineState *spapr, void *fdt)
16
{
17
- char *stdout_path = spapr_vio_stdout_path(spapr->vio_bus);
18
+ g_autofree char *stdout_path = spapr_vio_stdout_path(spapr->vio_bus);
19
20
vof_build_dt(fdt, spapr->vof);
21
22
23
--
24
2.45.2
25
26
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 fixes 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
1
This fixes LeakSanitizer warnings.
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>
4
Reviewed-by: Peter Xu <peterx@redhat.com>
41
Reviewed-by: Peter Xu <peterx@redhat.com>
5
---
42
---
6
migration/savevm.c | 2 ++
43
include/exec/memory.h | 59 ++++++++++++++++++++++++---------------------------
7
1 file changed, 2 insertions(+)
44
1 file changed, 28 insertions(+), 31 deletions(-)
8
45
9
diff --git a/migration/savevm.c b/migration/savevm.c
46
diff --git a/include/exec/memory.h b/include/exec/memory.h
10
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
11
--- a/migration/savevm.c
48
--- a/include/exec/memory.h
12
+++ b/migration/savevm.c
49
+++ b/include/exec/memory.h
13
@@ -XXX,XX +XXX,XX @@ int vmstate_replace_hack_for_ppc(VMStateIf *obj, int instance_id,
50
@@ -XXX,XX +XXX,XX @@ void memory_region_section_free_copy(MemoryRegionSection *s);
14
51
* memory_region_add_subregion() to add subregions.
15
if (se) {
52
*
16
savevm_state_handler_remove(se);
53
* @mr: the #MemoryRegion to be initialized
17
+ g_free(se->compat);
54
- * @owner: the object that tracks the region's reference count
18
+ g_free(se);
55
+ * @owner: the object that keeps the region alive
19
}
56
* @name: used for debugging; not visible to the user or ABI
20
return vmstate_register(obj, instance_id, vmsd, opaque);
57
* @size: size of the region; any subregions beyond this size will be clipped
21
}
58
*/
59
@@ -XXX,XX +XXX,XX @@ void memory_region_init(MemoryRegion *mr,
60
uint64_t size);
61
62
/**
63
- * memory_region_ref: Add 1 to a memory region's reference count
64
+ * memory_region_ref: Add a reference to the owner of a memory region
65
*
66
- * Whenever memory regions are accessed outside the BQL, they need to be
67
- * preserved against hot-unplug. MemoryRegions actually do not have their
68
- * own reference count; they piggyback on a QOM object, their "owner".
69
- * This function adds a reference to the owner.
70
- *
71
- * All MemoryRegions must have an owner if they can disappear, even if the
72
- * device they belong to operates exclusively under the BQL. This is because
73
- * the region could be returned at any time by memory_region_find, and this
74
- * is usually under guest control.
75
+ * This function adds a reference to the owner of a memory region to keep the
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
22
236
23
--
237
--
24
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 fixes 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 fixes 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 fixes 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
Deleted patch
1
These GThreads are never referenced.
2
1
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
---
5
tests/qtest/vhost-user-test.c | 6 +++---
6
1 file changed, 3 insertions(+), 3 deletions(-)
7
8
diff --git a/tests/qtest/vhost-user-test.c b/tests/qtest/vhost-user-test.c
9
index XXXXXXX..XXXXXXX 100644
10
--- a/tests/qtest/vhost-user-test.c
11
+++ b/tests/qtest/vhost-user-test.c
12
@@ -XXX,XX +XXX,XX @@ static void *vhost_user_test_setup_reconnect(GString *cmd_line, void *arg)
13
{
14
TestServer *s = test_server_new("reconnect", arg);
15
16
- g_thread_new("connect", connect_thread, s);
17
+ g_thread_unref(g_thread_new("connect", connect_thread, s));
18
append_mem_opts(s, cmd_line, 256, TEST_MEMFD_AUTO);
19
s->vu_ops->append_opts(s, cmd_line, ",server=on");
20
21
@@ -XXX,XX +XXX,XX @@ static void *vhost_user_test_setup_connect_fail(GString *cmd_line, void *arg)
22
23
s->test_fail = true;
24
25
- g_thread_new("connect", connect_thread, s);
26
+ g_thread_unref(g_thread_new("connect", connect_thread, s));
27
append_mem_opts(s, cmd_line, 256, TEST_MEMFD_AUTO);
28
s->vu_ops->append_opts(s, cmd_line, ",server=on");
29
30
@@ -XXX,XX +XXX,XX @@ static void *vhost_user_test_setup_flags_mismatch(GString *cmd_line, void *arg)
31
32
s->test_flags = TEST_FLAGS_DISCONNECT;
33
34
- g_thread_new("connect", connect_thread, s);
35
+ g_thread_unref(g_thread_new("connect", connect_thread, s));
36
append_mem_opts(s, cmd_line, 256, TEST_MEMFD_AUTO);
37
s->vu_ops->append_opts(s, cmd_line, ",server=on");
38
39
40
--
41
2.45.2
diff view generated by jsdifflib