The CXL Type-3 device reset path (ct3d_reset) has several issues:
1) Resource leaks:
- cxl_destroy_cci() never frees the QEMUTimer allocated by
cxl_init_cci(), leaking a timer on each destroy/reinit cycle.
- The primary CCI (ct3d->cci) is re-initialized through
cxl_device_register_init_t3() without being destroyed first,
leaking the timer and leaving the mutex undestroyed on every
reset.
- The secondary CCIs are never destroyed at device exit time,
leaking their timers and mutexes on device removal.
2) Incomplete state cleanup:
- Background commands do not survive Conventional Resets (CXL r4.0
Section 8.2.9.4), yet the in-flight sanitize state is never freed.
- Scan media results are explicitly invalidated after reset (Section
8.2.10.9.4.6), yet scan_media_hasrun is never cleared.
- Event interrupt settings shall be reset to 00b on Conventional
Reset (Section 8.2.10.2.5), yet irq_enabled is never cleared.
- When "Injects Persistent Poison" is 0 (the QEMU default), injected
poison shall be automatically cleared on reset (Table 8-309), yet
the poison lists are never drained.
- Stale event records remain in the queues across reset even though
the Event Status register (Table 8-203) is non-sticky.
3) Deprecated API usage:
- Uses device_class_set_legacy_reset() instead of the three-phase
resettable interface, preventing reset-type-aware behavior.
This series fixes the issues incrementally:
- Patches 1-2: fix resource leaks (deterministic bugs)
- Patch 3: mechanical conversion to three-phase reset
- Patch 4: factor the primary CCI teardown into a
cxl_destroy_mailbox_t3() helper pairing cxl_initialize_mailbox_t3()
- Patches 5-7: clean up device state on reset
The state cleanup in patches 6-7 is gated on reset type:
RESET_TYPE_WAKEUP returns early (patch 6) since a resume from S3 is
not a Conventional or CXL Reset. The CCI re-initialization and the
in-flight sanitize discard run unconditionally regardless of type.
Not addressed here:
- Committed Feature attributes and alert thresholds (Table 8-276
Deepest Reset Persistence = None) are not reverted to defaults.
Factoring the realize-time defaults into a reset helper is left
for a follow-up.
- Dynamic Capacity extent lifecycle across reset.
- The Media Disabled latch after an interrupted Sanitize (Section
8.2.10.9.5.1); patch 5 addresses only the resource leak.
Tested: per-commit build clean; cxl qtest passes. Differential
LeakSanitizer (5x system_reset): pre-series leaks 720 B / 15 allocs
in cxl_init_cci -> timer_new_ms; post-series zero (re-verified on
v3). Poison inject -> reset -> re-inject same DPAs succeeds (no
stale "Overlap" rejection). 20x inject+reset stress cycles with no
crash.
Changes since v2:
- New patch 4: factor the primary CCI teardown into
cxl_destroy_mailbox_t3(), the teardown counterpart of
cxl_initialize_mailbox_t3(), called from both the reset path and
ct3_exit(). [Philippe]
- Patch 5 (was patch 4): discard the in-flight sanitize state from
cxl_destroy_mailbox_t3() through a helper shared with the
__do_sanitize() completion path, so the whole media_op_sanitize
lifecycle stays within cxl-mailbox-utils.c. This also plugs the
same leak on device unrealize, which v2 missed. [Philippe]
- Picked up Philippe's Reviewed-by on patches 1 and 3.
Changes since v1:
- Patch 1: reorder cxl_destroy_cci() teardown to reverse
cxl_init_cci() order, per Jonathan's review.
v2:
https://lore.kernel.org/qemu-devel/[email protected]/
v1:
https://lore.kernel.org/qemu-devel/[email protected]/
Junjie Cao (7):
hw/cxl: fix timer leak in cxl_destroy_cci()
hw/cxl: destroy primary CCI before re-initialization on reset
hw/cxl: convert cxl-type3 to three-phase reset
hw/cxl: add cxl_destroy_mailbox_t3() as the mailbox teardown
counterpart
hw/cxl: discard in-flight sanitize state on mailbox teardown
hw/cxl: clear event logs, scan media and interrupt policy on reset
hw/cxl: clear poison lists and feature transfer state on reset
hw/cxl/cxl-mailbox-utils.c | 24 +++++++++++++--
hw/mem/cxl_type3.c | 60 +++++++++++++++++++++++++++++++++----
include/hw/cxl/cxl_device.h | 3 ++
3 files changed, 80 insertions(+), 7 deletions(-)
base-commit: e1705a25aff35635c360bbaba4c2731d019a422a
--
2.43.0