On 261005 17:20, Farhan Ali wrote:
<..snip..>
On 9/30/2026 7:52 AM, Konstantin Shkolnyy wrote:
+/*
+ * When pending_sei load is executed, pending_sei can already contain
SEIs
+ * generated here in the target QEMU, for example, by state loads of
zpci
+ * devices. A dumb load here would place the older SEIs from the
source QEMU
+ * after the new SEIs. To fix this, we have pre_load() stash the new
SEIs from
+ * pending_sei and post_load() unstash them after the old ones.
+ */
+static void s390_pci_move_sei_list(SeiContainerList *dst,
SeiContainerList *src)
+{
+ SeiContainer *sei_cont;
+
+ while ((sei_cont = QTAILQ_FIRST(src))) {
+ QTAILQ_REMOVE(src, sei_cont, link);
+ QTAILQ_INSERT_TAIL(dst, sei_cont, link);
+ }
+}
+
+static int s390_pcihost_pending_sei_vmstate_pre_load(void *opaque)
+{
+ S390pciState *s = S390_PCI_HOST_BRIDGE(opaque);
+
+ QTAILQ_INIT(&s->pending_sei_stash);
+ s390_pci_move_sei_list(&s->pending_sei_stash, &s->pending_sei);
+ return 0;
+}
Does this mean we can append SEIs to the list while we are still
migrating? In that case do we need any form of synchronization here when
accessing the pending_sei list?
SEIs can be generated the migration process itself - by
s390_pci_ioat_replay() called from s390_pci_device_post_load_errp().
That happens before the migration process comes here to load
s390_pcihost state (with old SEIs).
Since the migration process is single-threaded I don't think we need to
synchronize between its stages.
Thanks
Farhan
+
+static int s390_pcihost_pending_sei_vmstate_post_load(void *opaque,
+ int version_id)
+{
+ S390pciState *s = S390_PCI_HOST_BRIDGE(opaque);
+
+ s390_pci_move_sei_list(&s->pending_sei, &s->pending_sei_stash);
+ return 0;
+}
+
+static const VMStateDescription s390_pcihost_pending_sei_vmstate = {
+ .name = TYPE_S390_PCI_HOST_BRIDGE "/pending-sei",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = s390_pcihost_pending_sei_vmstate_needed,
+ .pre_load = s390_pcihost_pending_sei_vmstate_pre_load,
+ .post_load = s390_pcihost_pending_sei_vmstate_post_load,
+ .fields = (const VMStateField[]) {
+ VMSTATE_QTAILQ_V(pending_sei, S390pciState, 1,
+ vmstate_sei_container, SeiContainer, link),
+ VMSTATE_END_OF_LIST()
+ }
+};
+