Revision e44359c3

b/arch_init.c
105 105

  
106 106
static int ram_save_block(QEMUFile *f)
107 107
{
108
    static ram_addr_t current_addr = 0;
109
    ram_addr_t saved_addr = current_addr;
110
    ram_addr_t addr = 0;
111
    uint64_t total_ram = ram_bytes_total();
108
    static RAMBlock *last_block = NULL;
109
    static ram_addr_t last_offset = 0;
110
    RAMBlock *block = last_block;
111
    ram_addr_t offset = last_offset;
112
    ram_addr_t current_addr;
112 113
    int bytes_sent = 0;
113 114

  
114
    while (addr < total_ram) {
115
    if (!block)
116
        block = QLIST_FIRST(&ram_list.blocks);
117

  
118
    current_addr = block->offset + offset;
119

  
120
    do {
115 121
        if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
116
            RAMBlock *block;
117
            ram_addr_t offset;
118 122
            uint8_t *p;
119 123

  
120 124
            cpu_physical_memory_reset_dirty(current_addr,
121 125
                                            current_addr + TARGET_PAGE_SIZE,
122 126
                                            MIGRATION_DIRTY_FLAG);
123 127

  
124
            QLIST_FOREACH(block, &ram_list.blocks, next) {
125
                if (current_addr - block->offset < block->length)
126
                    break;
127
            }
128
            offset = current_addr - block->offset;
129 128
            p = block->host + offset;
130 129

  
131 130
            if (is_dup_page(p, *p)) {
......
146 145

  
147 146
            break;
148 147
        }
149
        addr += TARGET_PAGE_SIZE;
150
        current_addr = (saved_addr + addr) % total_ram;
151
    }
148

  
149
        offset += TARGET_PAGE_SIZE;
150
        if (offset >= block->length) {
151
            offset = 0;
152
            block = QLIST_NEXT(block, next);
153
            if (!block)
154
                block = QLIST_FIRST(&ram_list.blocks);
155
        }
156

  
157
        current_addr = block->offset + offset;
158

  
159
    } while (current_addr != last_block->offset + last_offset);
160

  
161
    last_block = block;
162
    last_offset = offset;
152 163

  
153 164
    return bytes_sent;
154 165
}
......
157 168

  
158 169
static ram_addr_t ram_save_remaining(void)
159 170
{
160
    ram_addr_t addr;
171
    RAMBlock *block;
161 172
    ram_addr_t count = 0;
162
    uint64_t total_ram = ram_bytes_total();
163 173

  
164
    for (addr = 0; addr < total_ram; addr += TARGET_PAGE_SIZE) {
165
        if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) {
166
            count++;
174
    QLIST_FOREACH(block, &ram_list.blocks, next) {
175
        ram_addr_t addr;
176
        for (addr = block->offset; addr < block->offset + block->length;
177
             addr += TARGET_PAGE_SIZE) {
178
            if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) {
179
                count++;
180
            }
167 181
        }
168 182
    }
169 183

  
......
210 224

  
211 225
    if (stage == 1) {
212 226
        RAMBlock *block;
213
        uint64_t total_ram = ram_bytes_total();
214 227
        bytes_transferred = 0;
215 228

  
216 229
        /* Make sure all dirty bits are set */
217
        for (addr = 0; addr < total_ram; addr += TARGET_PAGE_SIZE) {
218
            if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) {
219
                cpu_physical_memory_set_dirty(addr);
230
        QLIST_FOREACH(block, &ram_list.blocks, next) {
231
            for (addr = block->offset; addr < block->offset + block->length;
232
                 addr += TARGET_PAGE_SIZE) {
233
                if (!cpu_physical_memory_get_dirty(addr,
234
                                                   MIGRATION_DIRTY_FLAG)) {
235
                    cpu_physical_memory_set_dirty(addr);
236
                }
220 237
            }
221 238
        }
222 239

  
223 240
        /* Enable dirty memory tracking */
224 241
        cpu_physical_memory_set_dirty_tracking(1);
225 242

  
226
        qemu_put_be64(f, total_ram | RAM_SAVE_FLAG_MEM_SIZE);
243
        qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE);
227 244

  
228 245
        QLIST_FOREACH(block, &ram_list.blocks, next) {
229 246
            qemu_put_byte(f, strlen(block->idstr));

Also available in: Unified diff