cxl_init_cci() allocates a QEMUTimer via timer_new_ms() but
cxl_destroy_cci() never frees it. This leaks a timer object on every
device exit path and, more critically, on every device reset cycle since
the secondary CCIs (vdm_fm_owned_ld_mctp_cci, ld0_cci) are destroyed
and re-initialized each time ct3d_reset() runs.
Tear the CCI down in the reverse of cxl_init_cci()'s setup order:
destroy the mutex, then free the timer. timer_free() cancels any
pending expiry via timer_del() internally and tolerates a NULL pointer;
clear the field afterwards so that a repeated timer_free() on the same
CCI is a safe no-op.
(The function as a whole is still not idempotent: qemu_mutex_destroy()
asserts on an already-destroyed mutex. Callers must not invoke
cxl_destroy_cci() twice; the .initialized guard added in the next patch
enforces that.)
Fixes: 98cbac128f1c ("hw/cxl: Support aborting background commands")
Cc: [email protected]
Signed-off-by: Junjie Cao <[email protected]>
Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
---
hw/cxl/cxl-mailbox-utils.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index ec18338b42..603677a97b 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -4795,6 +4795,8 @@ void cxl_init_cci(CXLCCI *cci, size_t payload_max)
void cxl_destroy_cci(CXLCCI *cci)
{
qemu_mutex_destroy(&cci->bg.lock);
+ timer_free(cci->bg.timer);
+ cci->bg.timer = NULL;
cci->initialized = false;
}
--
2.43.0