/* State for the incoming migration */
struct MigrationIncomingState {
QEMUFile *from_src_file;
-
+ /* Previously received RAM's RAMBlock pointer */
+ RAMBlock *last_recv_block;
/* A hook to allow cleanup at the end of incoming migration */
void *transport_data;
void (*transport_cleanup)(void *data);
*
* Returns a pointer from within the RCU-protected ram_list.
*
+ * @mis: the migration incoming state pointer
* @f: QEMUFile where to read the data from
* @flags: Page flags (mostly to see if it's a continuation of previous block)
*/
-static inline RAMBlock *ram_block_from_stream(QEMUFile *f, int flags)
+static inline RAMBlock *ram_block_from_stream(MigrationIncomingState *mis,
+ QEMUFile *f, int flags)
{
- static RAMBlock *block;
+ RAMBlock *block = mis->last_recv_block;
char id[256];
uint8_t len;
return NULL;
}
+ mis->last_recv_block = block;
+
return block;
}
trace_ram_load_postcopy_loop((uint64_t)addr, flags);
if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE |
RAM_SAVE_FLAG_COMPRESS_PAGE)) {
- block = ram_block_from_stream(f, flags);
+ block = ram_block_from_stream(mis, f, flags);
if (!block) {
ret = -EINVAL;
break;
*/
static int ram_load_precopy(QEMUFile *f)
{
+ MigrationIncomingState *mis = migration_incoming_get_current();
int flags = 0, ret = 0, invalid_flags = 0, len = 0, i = 0;
/* ADVISE is earlier, it shows the source has the postcopy capability on */
bool postcopy_advised = postcopy_is_advised();
if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE |
RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE)) {
- RAMBlock *block = ram_block_from_stream(f, flags);
+ RAMBlock *block = ram_block_from_stream(mis, f, flags);
host = host_from_ram_block_offset(block, addr);
/*