Fix xbzrle vs last_sent_block update
My fix (84e7b80a
) replaced the last_sent_block update that I'd removed earlier; however it was too aggressive in the xbzrle case. save_xbzrle_page might return '0' to mean that the page didn't need sending since it was the same as the last sent version; in this case we can't update 'last_sent_block' since we didn't actually send it. Symptom: 'Illegal RAM offset 1018000' as we try and send a page to the wrong RAMBlock; potentially that could be a data corruption if you were really unlucky. Fixes:84e7b80a05
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Reviewed-by: Juan Quintela <quintela@redhat.com> Message-id: 1449765106-6528-1-git-send-email-dgilbert@redhat.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
b969526adf
commit
3fd3c4b37c
@ -716,6 +716,9 @@ static int save_zero_page(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
|
||||
* ram_save_page: Send the given page to the stream
|
||||
*
|
||||
* Returns: Number of pages written.
|
||||
* < 0 - error
|
||||
* >=0 - Number of pages written - this might legally be 0
|
||||
* if xbzrle noticed the page was the same.
|
||||
*
|
||||
* @f: QEMUFile where to send the data
|
||||
* @block: block that contains the page we want to send
|
||||
@ -1249,7 +1252,13 @@ static int ram_save_target_page(MigrationState *ms, QEMUFile *f,
|
||||
if (unsentmap) {
|
||||
clear_bit(dirty_ram_abs >> TARGET_PAGE_BITS, unsentmap);
|
||||
}
|
||||
last_sent_block = block;
|
||||
/* Only update last_sent_block if a block was actually sent; xbzrle
|
||||
* might have decided the page was identical so didn't bother writing
|
||||
* to the stream.
|
||||
*/
|
||||
if (res > 0) {
|
||||
last_sent_block = block;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
|
Loading…
Reference in New Issue
Block a user