Am Mi., 18. März 2026 um 00:23 Uhr schrieb Peter Xu <[email protected]>: > > The loader side of ptr marker is pretty straightforward, instead of playing > the inner_field trick, just do the load manually assuming the marker layout > is a stable ABI (which it is true already). > > This will remove some logic while loading VMSD, and hopefully it makes it > slightly easier to read. Unfortunately, we still need to keep the sender > side because of the JSON blob we're maintaining.. > > This paves way for future processing of non-NULL markers as well. > > Signed-off-by: Peter Xu <[email protected]>
Reviewed-by: Alexander Mikhalitsyn <[email protected]> > --- > migration/vmstate-types.c | 12 ++++-------- > migration/vmstate.c | 40 ++++++++++++++++++++++++--------------- > 2 files changed, 29 insertions(+), 23 deletions(-) > > diff --git a/migration/vmstate-types.c b/migration/vmstate-types.c > index b31689fc3c..ae465c5c2c 100644 > --- a/migration/vmstate-types.c > +++ b/migration/vmstate-types.c > @@ -363,14 +363,10 @@ static bool load_ptr_marker(QEMUFile *f, void *pv, > size_t size, > const VMStateField *field, Error **errp) > > { > - int byte = qemu_get_byte(f); > - > - if (byte == VMS_MARKER_PTR_NULL || byte == VMS_MARKER_PTR_VALID) { > - /* TODO: process PTR_VALID case */ > - return true; > - } > - > - error_setg(errp, "%s: unexpected ptr marker: %d", __func__, byte); > + /* > + * Load is done in vmstate core, see vmstate_ptr_marker_load(). > + */ > + g_assert_not_reached(); > return false; > } > > diff --git a/migration/vmstate.c b/migration/vmstate.c > index a3a5f25946..d65fc84dfa 100644 > --- a/migration/vmstate.c > +++ b/migration/vmstate.c > @@ -142,6 +142,21 @@ static void vmstate_handle_alloc(void *ptr, const > VMStateField *field, > } > } > > +static bool vmstate_ptr_marker_load(QEMUFile *f, bool *load_field, > + Error **errp) > +{ > + int byte = qemu_get_byte(f); > + > + if (byte == VMS_MARKER_PTR_NULL) { > + /* When it's a null ptr marker, do not continue the load */ > + *load_field = false; > + return true; > + } > + > + error_setg(errp, "Unexpected ptr marker: %d", byte); > + return false; > +} > + > static bool vmstate_pre_load(const VMStateDescription *vmsd, void *opaque, > Error **errp) > { > @@ -264,30 +279,25 @@ bool vmstate_load_vmsd(QEMUFile *f, const > VMStateDescription *vmsd, > } > > for (i = 0; i < n_elems; i++) { > - bool ok; > + /* If we will process the load of field? */ > + bool load_field = true; > + bool ok = true; > void *curr_elem = first_elem + size * i; > - const VMStateField *inner_field; > > if (field->flags & VMS_ARRAY_OF_POINTER) { > curr_elem = *(void **)curr_elem; > } > > if (!curr_elem && size) { > - /* > - * If null pointer found (which should only happen in > - * an array of pointers), use null placeholder and do > - * not follow. > - */ > - inner_field = vmsd_create_ptr_marker_field(field); > - } else { > - inner_field = field; > + /* Read the marker instead of VMSD itself */ > + if (!vmstate_ptr_marker_load(f, &load_field, errp)) { > + trace_vmstate_load_field_error(field->name, -EINVAL); > + return false; > + } > } > > - ok = vmstate_load_field(f, curr_elem, size, inner_field, > errp); > - > - /* If we used a fake temp field.. free it now */ > - if (inner_field != field) { > - g_clear_pointer((gpointer *)&inner_field, g_free); > + if (load_field) { > + ok = vmstate_load_field(f, curr_elem, size, field, errp); > } > > if (ok) { > -- > 2.50.1 >
