Re: [PATCH 1/2] qom: Reject temporary object resurrection
Akihiko Odaki <[email protected]> Mon, 15 Jun 2026 17:50:17 +0900
| Newsgroups | org.nongnu.qemu-rust,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
On 2026/06/15 17:34, Kevin Wolf wrote: > Am 15.06.2026 um 06:11 hat Akihiko Odaki geschrieben: >> If object_ref() is called during finalization, it will temporarily >> "resurrect" the object. Although object_finalize() asserts that no >> resurrecting reference remains before freeing the object, the assertion >> cannot catch the case where the resurrecting reference is dropped before >> freeing the object. > > Ok, and why is that a problem? > > In the cover letter, you referred to an earlier patch you had posted: > > The temporary object resurrection patch originated from: > https://lore.kernel.org/qemu-devel/[email protected]/ > ("[PATCH v2 1/3] qom: Do not finalize twice") > > From that patch, it's clear that one problem is that .finalize() can be > called multiple times, which you probably don't want. But what is the > reason for switching from just ignoring the second .finalize() like in > the old patch to completely forbidding a temporary refcount increase? None. I thought merely skipping finalization is not a well-defined semantics (e.g., breaking Rust safety guarantee), but, reconsidering now, I think that's fine. > >> One way to catch this would be to add a check in object_ref() to reject >> resurrecting references before they are created. However, object_ref() >> is frequently called so it is better to minimize the overhead. > > We're talking about a single comparison with zero here. So if that's the > worse alternative, the other one can't have any drawbacks. True. > >> To avoid adding the overhead, change how the reference count is >> represented and let an existing assertion detect resurrection. More >> concretely, obj->ref now stores the current reference count minus 1. The >> stored count is therefore 0 after object_initialize(), and the final >> object_unref() decrements it from 0 to UINT32_MAX and starts >> finalization. A resurrecting object_ref() will then trip the existing >> obj->ref < INT_MAX assertion. > > A refcount field where 0 means that a last reference is still remaining > is highly confusing. If we do want to forbid taking a temporary new > reference in .finalize() for some reason, the explicit check in > object_ref() sounds much better to me. The rationale here is that the field is mostly contained in qom/object.c so the awkward semantics won't have a wide impact. But it's just "mostly" and there are two exceptions: block/throttle-groups.c and tests/unit/check-qom-proplist.c. I withdraw this patch for the drawbacks discussed above. Regards, Akihiko Odaki