Re: [PATCH v1 1/6] tools/migration: introduce PAGE_DATA_LZ4 stream record type

Teddy Astie <[email protected]>
Newsgroups org.xenproject.lists.xen-devel
Message-ID <1785834903.8631fc262581453bbf619ec5b2062170.19fcc0e18f8000e099@vates.tech>
Le 03/08/2026 à 19:23, Marcus Granado a écrit :
> On Wed, 29 Jul 2026 at 10:14, Frediano Ziglio <[email protected]> wrote:
>> About compressing all together and considering also the issue of
>> memory changing while sending I would vote to copy the memory in a
>> temporary buffer to avoid this. One advantage is that it simplified
>> the format. The current LZ4 implementation seems to cope with data
>> changes but nothing guarantees it in the future, the buffer you are
>> passing is not supposed to change while you compress it.
> 
> 
> Agreed. Frediano and I discussed this further, including simplifications on
> the compression record for v2 so that the page data compression:
> * compresses the whole batch together
> * and uses a staged copy for it as you and Teddy suggested (so that we do
> not need to worry about mutating buffers affecting LZ4 or other algorithms).
> 
> Once there's exactly one compressed blob per record, there's no need for
> extra fields to describe the compressed data, as the uncompressed batch
> size is known (and bounded by MAX_BATCH_SIZE * page_size), and its
> compressed size can be inferred from the size of the emitted compressed
> record without a need for an explicit field for clen or a field with the
> number of raw compressed blobs. This means the separate PAGE_DATA_LZ4
> record type is not needed, and the proposal for v2 compression record could
> simplify to reusing PAGE_DATA and spending one octet of its reserved word
> as follows:
> 
> 
>       0     1     2     3     4     5     6     7 octet
>      +-----------------------+-----+-------------------+
>      | count (C)             | comp| (reserved)        |
>      +-----------------------+-----+-------------------+
>      | pfn[0]                                          |
>      +-------------------------------------------------+
>      ...
>      +-------------------------------------------------+
>      | pfn[C-1]                                        |
>      +-------------------------------------------------+
>      | page_data[0..N-1] if comp == 0                  |
>      | or page_cdata     if comp != 0                  |
>      +-------------------------------------------------+
> 
> with two new entries in the field table:
> 
> comp        Compression algorithm applied to the page contents. 0
>              means none, and the record is exactly as it is today. 1
>              means LZ4 block format. Other values are reserved for
>              other future formats like ZSTD etc. A comp != 0 can only
>              be emitted if 0 < len(page_cdata) < N * page_size. An
>              unknown comp must cause the receiver to fail with a
>              "Compression algorithm <value> not handled" error.
> 
> page_cdata  Present instead of page_data when comp is non-zero. A
>              single compressed object holding the concatenation of the
>              N page_data entries. The receiver must verify that
>              0 < count <= MAX_BATCH_SIZE.
> 
> 
> Teddy, I hope this format covers your points: it's no longer LZ4 specific,
> the inline clen inconsistency in libxenguest record disappears, it's one
> block over an immutable copy of the batch instead of one per page, the
> decompressed size is known up front, and the allocation derived from count
> is bounded on the receiver.
> 

Looks good to me.

> 
> This simplification is also forward-compatible in two different ways: your
> 64KB chunking for cache locality doesn't depend on the format, as the
> staging copy can be done in chunks while still making a single compress
> call over the whole batch. And if we find benefits in splitting the payload
> into several compressed units, that can be implemented as a new comp value
> using a self-delimiting format like zstd or lz4f frames, which report the
> consumed bytes without a need to specify clen or extra framing fields at the
> record level.
> 
> 
> On Wed, 22 Jul 2026 at 20:42, Frediano Ziglio <[email protected]> wrote:
>> Don't we need to bump the version number while we add a new mandatory record?
> 
> I believe we may avoid having to do a version bump if we adopt the property
> that 0 < len(page_cdata) < N * page_size when comp != 0, as in this case
> the compressed data sent to an old receiver would fail in handle_page_data()
> with "PAGE_DATA record wrong size". Bumping the version would make
> uncompressed migrations fail if they are sent to old receivers that also
> understand uncompressed migration, so avoiding if possible would be good.
> The spec says migration tools "shall always save images using version V",
> so it doesn't seem like we could bump the version only when compression is on.
> 
> 
>> Is there no kind of dialog about the supported version?
> 
> There is no in-stream negotiation, and this proposal does not add one.
> Compression is opt-in at the sender via xl migrate --compress, so an operator
> who enables it against an old receiver gets a clean failure rather than
> corruption.
> 
>> Why not extending the generalization compressing all payload of
>> uncompressed packets (type+body),
> 
> A composable wrapper would be a clean generic mechanism, but I think there
> are two reasons not to go that way in v2: PAGE_DATA is effectively all of the
> stream bytes, so compressing the other record types would not show up in a
> measurement. And the no-extra-fields property above depends on PAGE_DATA
> specifically: a generic wrapper has no pfn array from where we can derive
> the uncompressed size, so it would need explicit algorithm, compressed
> size and uncompressed size fields on every record, which re-adds the fields
> that this proposal tries to avoid.
> 
> 
> Please let me know if the ideas above capture what you had in mind in terms of
> suggestions to improve v1.
> 
> In particular, I wonder what the maintainers think of the use of one of the
> octets of the PAGE_DATA reserved field for the purpose of indicating the data
> is compressed, or is it preferable to use a new PAGE_DATA_COMPRESSED (0x13)
> type record as a mandatory record so that an old receiver fails more cleanly
> when it doesn't understand compression "Mandatory record <name> not handled"
> (caused by the specification of mandatory records) instead of with a generic
> error "PAGE_DATA record wrong size" (caused by the current safety
> implementation that rejects unexpected record sizes)?
> 

The specification says

 > Padding and reserved fields are set to zero on save and must be
ignored during restore.

Which is not really going to help if we add a new field that matters on 
how the content is organized.

To avoid confusion, it may be desirable to add a new type 
(PAGE_DATA_COMPRESSED), but I'm not fully sold on it.

> 
> Marcus
> 
> 

Teddy
OpenPGP_0x660FA9D102CBCFD0.asc (application/pgp-keys, 2.4 KB)
-----BEGIN PGP PUBLIC KEY BLOCK-----

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
x9fhaZEsniw8/bYgC3igkk5YJiOa
=lUIA
-----END PGP PUBLIC KEY BLOCK-----
OpenPGP_signature.asc (application/pgp-signature, 665 B)
-----BEGIN PGP SIGNATURE-----

wsD5BAABCAAjFiEEGAIew9LzHY3pdrqtZg+p0QLLz9AFAmpxrZYFAwAAAAAACgkQZg+p0QLLz9CC
EAwAqmEMd1SikFOClTEEjZw+ESDICB9UuEyhrZ5LK4CaAQsO3HxMYwfN7st4RyL/PBHy4CbyddvQ
hu1HS0T3XyU2WjiahkSx9IhrEYjAU1B89bsNi5hpofhgGpBi4qCocQ6iJgpBWg9z6bPUhDCKC2qs
tWg0wndY7ZwFqx/PiE1vPTpp1FRntQQwS+o9JlsUKuNlk8stMvrQz1j+vyaZlDBKbLZ+j76QrNti
drccO+ikWGn4mAQWqfEdDhkRorR3hYrffs1bRT+/wy6BeoxGzUEPH+JnMY1kB5JohrwKKv0fNqwm
oYj1XVInPKZXAnjMQqoVf/Ykm8xIAtPkWap4Cu9CteUQKe67Jg+wwURzN5HqV4GRFhPvBsRDptom
TVsHe+ZDIQEJ1b73oVJEZzqx60Vq5Ws9ehvWMi0l8lfrwgDZKFu/6hibl5RSfX7YR0BQI+X0Io1/
jFxYTrJjOwF7huiDb9TBj9eVSslKNLS1h0nUvMCFDuN7OAFD+r47h+m0y8Vk
=gycT
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.