|
29 | 29 | #define BLK_MIG_FLAG_DEVICE_BLOCK 0x01
|
30 | 30 | #define BLK_MIG_FLAG_EOS 0x02
|
31 | 31 | #define BLK_MIG_FLAG_PROGRESS 0x04
|
| 32 | +#define BLK_MIG_FLAG_ZERO_BLOCK 0x08 |
32 | 33 |
|
33 | 34 | #define MAX_IS_ALLOCATED_SEARCH 65536
|
34 | 35 |
|
@@ -80,6 +81,7 @@ typedef struct BlkMigState {
|
80 | 81 | int shared_base;
|
81 | 82 | QSIMPLEQ_HEAD(bmds_list, BlkMigDevState) bmds_list;
|
82 | 83 | int64_t total_sector_sum;
|
| 84 | + bool zero_blocks; |
83 | 85 |
|
84 | 86 | /* Protected by lock. */
|
85 | 87 | QSIMPLEQ_HEAD(blk_list, BlkMigBlock) blk_list;
|
@@ -114,16 +116,30 @@ static void blk_mig_unlock(void)
|
114 | 116 | static void blk_send(QEMUFile *f, BlkMigBlock * blk)
|
115 | 117 | {
|
116 | 118 | int len;
|
| 119 | + uint64_t flags = BLK_MIG_FLAG_DEVICE_BLOCK; |
| 120 | + |
| 121 | + if (block_mig_state.zero_blocks && |
| 122 | + buffer_is_zero(blk->buf, BLOCK_SIZE)) { |
| 123 | + flags |= BLK_MIG_FLAG_ZERO_BLOCK; |
| 124 | + } |
117 | 125 |
|
118 | 126 | /* sector number and flags */
|
119 | 127 | qemu_put_be64(f, (blk->sector << BDRV_SECTOR_BITS)
|
120 |
| - | BLK_MIG_FLAG_DEVICE_BLOCK); |
| 128 | + | flags); |
121 | 129 |
|
122 | 130 | /* device name */
|
123 | 131 | len = strlen(blk->bmds->bs->device_name);
|
124 | 132 | qemu_put_byte(f, len);
|
125 | 133 | qemu_put_buffer(f, (uint8_t *)blk->bmds->bs->device_name, len);
|
126 | 134 |
|
| 135 | + /* if a block is zero we need to flush here since the network |
| 136 | + * bandwidth is now a lot higher than the storage device bandwidth. |
| 137 | + * thus if we queue zero blocks we slow down the migration */ |
| 138 | + if (flags & BLK_MIG_FLAG_ZERO_BLOCK) { |
| 139 | + qemu_fflush(f); |
| 140 | + return; |
| 141 | + } |
| 142 | + |
127 | 143 | qemu_put_buffer(f, blk->buf, BLOCK_SIZE);
|
128 | 144 | }
|
129 | 145 |
|
@@ -344,6 +360,7 @@ static void init_blk_migration(QEMUFile *f)
|
344 | 360 | block_mig_state.total_sector_sum = 0;
|
345 | 361 | block_mig_state.prev_progress = -1;
|
346 | 362 | block_mig_state.bulk_completed = 0;
|
| 363 | + block_mig_state.zero_blocks = migrate_zero_blocks(); |
347 | 364 |
|
348 | 365 | bdrv_iterate(init_blk_migration_it, NULL);
|
349 | 366 | }
|
@@ -762,12 +779,15 @@ static int block_load(QEMUFile *f, void *opaque, int version_id)
|
762 | 779 | nr_sectors = BDRV_SECTORS_PER_DIRTY_CHUNK;
|
763 | 780 | }
|
764 | 781 |
|
765 |
| - buf = g_malloc(BLOCK_SIZE); |
766 |
| - |
767 |
| - qemu_get_buffer(f, buf, BLOCK_SIZE); |
768 |
| - ret = bdrv_write(bs, addr, buf, nr_sectors); |
| 782 | + if (flags & BLK_MIG_FLAG_ZERO_BLOCK) { |
| 783 | + ret = bdrv_write_zeroes(bs, addr, nr_sectors); |
| 784 | + } else { |
| 785 | + buf = g_malloc(BLOCK_SIZE); |
| 786 | + qemu_get_buffer(f, buf, BLOCK_SIZE); |
| 787 | + ret = bdrv_write(bs, addr, buf, nr_sectors); |
| 788 | + g_free(buf); |
| 789 | + } |
769 | 790 |
|
770 |
| - g_free(buf); |
771 | 791 | if (ret < 0) {
|
772 | 792 | return ret;
|
773 | 793 | }
|
|
0 commit comments