diff options
-rw-r--r-- | block-migration.c | 22 | ||||
-rw-r--r-- | hw/m25p80.c | 15 | ||||
-rw-r--r-- | include/migration/qemu-file.h | 1 | ||||
-rw-r--r-- | savevm.c | 9 | ||||
-rw-r--r-- | trace/simple.c | 24 |
5 files changed, 57 insertions, 14 deletions
diff --git a/block-migration.c b/block-migration.c index bcd0039025..43ab2028c0 100644 --- a/block-migration.c +++ b/block-migration.c @@ -539,6 +539,7 @@ static int block_save_setup(QEMUFile *f, void *opaque) static int block_save_iterate(QEMUFile *f, void *opaque) { int ret; + int64_t last_ftell = qemu_ftell(f); DPRINTF("Enter save live iterate submitted %d transferred %d\n", block_mig_state.submitted, block_mig_state.transferred); @@ -582,12 +583,7 @@ static int block_save_iterate(QEMUFile *f, void *opaque) qemu_put_be64(f, BLK_MIG_FLAG_EOS); - /* Complete when bulk transfer is done and all dirty blocks have been - * transferred. - */ - return block_mig_state.bulk_completed && - block_mig_state.submitted == 0 && - block_mig_state.read_done == 0; + return qemu_ftell(f) - last_ftell; } static int block_save_complete(QEMUFile *f, void *opaque) @@ -629,10 +625,18 @@ static int block_save_complete(QEMUFile *f, void *opaque) static uint64_t block_save_pending(QEMUFile *f, void *opaque, uint64_t max_size) { + /* Estimate pending number of bytes to send */ + uint64_t pending = get_remaining_dirty() + + block_mig_state.submitted * BLOCK_SIZE + + block_mig_state.read_done * BLOCK_SIZE; + + /* Report at least one block pending during bulk phase */ + if (pending == 0 && !block_mig_state.bulk_completed) { + pending = BLOCK_SIZE; + } - DPRINTF("Enter save live pending %ld\n", get_remaining_dirty()); - - return get_remaining_dirty(); + DPRINTF("Enter save live pending %" PRIu64 "\n", pending); + return pending; } static int block_load(QEMUFile *f, void *opaque, int version_id) diff --git a/hw/m25p80.c b/hw/m25p80.c index 788c19608c..461b41c4ac 100644 --- a/hw/m25p80.c +++ b/hw/m25p80.c @@ -184,6 +184,7 @@ static const FlashPartInfo known_devices[] = { typedef enum { NOP = 0, + WRSR = 0x1, WRDI = 0x4, RDSR = 0x5, WREN = 0x6, @@ -379,6 +380,11 @@ static void complete_collecting_data(Flash *s) case ERASE_SECTOR: flash_erase(s, s->cur_addr, s->cmd_in_progress); break; + case WRSR: + if (s->write_enable) { + s->write_enable = false; + } + break; default: break; } @@ -443,6 +449,15 @@ static void decode_new_cmd(Flash *s, uint32_t value) s->state = STATE_COLLECTING_DATA; break; + case WRSR: + if (s->write_enable) { + s->needed_bytes = 1; + s->pos = 0; + s->len = 0; + s->state = STATE_COLLECTING_DATA; + } + break; + case WRDI: s->write_enable = false; break; diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h index 68deefbcfb..46fc11dc99 100644 --- a/include/migration/qemu-file.h +++ b/include/migration/qemu-file.h @@ -81,6 +81,7 @@ QEMUFile *qemu_popen(FILE *popen_file, const char *mode); QEMUFile *qemu_popen_cmd(const char *command, const char *mode); int qemu_get_fd(QEMUFile *f); int qemu_fclose(QEMUFile *f); +int64_t qemu_ftell(QEMUFile *f); void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size); void qemu_put_byte(QEMUFile *f, int v); @@ -673,9 +673,14 @@ int qemu_get_byte(QEMUFile *f) return result; } -static int64_t qemu_ftell(QEMUFile *f) +int64_t qemu_ftell(QEMUFile *f) { - return f->buf_offset - f->buf_size + f->buf_index; + /* buf_offset excludes buffer for writing but includes it for reading */ + if (f->is_write) { + return f->buf_offset + f->buf_index; + } else { + return f->buf_offset - f->buf_size + f->buf_index; + } } int qemu_file_rate_limit(QEMUFile *f) diff --git a/trace/simple.c b/trace/simple.c index 74701e3272..375d98f70b 100644 --- a/trace/simple.c +++ b/trace/simple.c @@ -40,8 +40,18 @@ * records to become available, writes them out, and then waits again. */ static GStaticMutex trace_lock = G_STATIC_MUTEX_INIT; + +/* g_cond_new() was deprecated in glib 2.31 but we still need to support it */ +#if GLIB_CHECK_VERSION(2, 31, 0) +static GCond the_trace_available_cond; +static GCond the_trace_empty_cond; +static GCond *trace_available_cond = &the_trace_available_cond; +static GCond *trace_empty_cond = &the_trace_empty_cond; +#else static GCond *trace_available_cond; static GCond *trace_empty_cond; +#endif + static bool trace_available; static bool trace_writeout_enabled; @@ -51,9 +61,9 @@ enum { }; uint8_t trace_buf[TRACE_BUF_LEN]; -static unsigned int trace_idx; +static volatile gint trace_idx; static unsigned int writeout_idx; -static int dropped_events; +static volatile gint dropped_events; static FILE *trace_fp; static char *trace_file_name; @@ -267,7 +277,7 @@ void trace_record_finish(TraceBufferRecord *rec) record.event |= TRACE_RECORD_VALID; write_to_buffer(rec->tbuf_idx, &record, sizeof(TraceRecord)); - if ((g_atomic_int_get(&trace_idx) - writeout_idx) + if (((unsigned int)g_atomic_int_get(&trace_idx) - writeout_idx) > TRACE_BUF_FLUSH_THRESHOLD) { flush_trace_file(false); } @@ -397,7 +407,13 @@ static GThread *trace_thread_create(GThreadFunc fn) sigfillset(&set); pthread_sigmask(SIG_SETMASK, &set, &oldset); #endif + +#if GLIB_CHECK_VERSION(2, 31, 0) + thread = g_thread_new("trace-thread", fn, NULL); +#else thread = g_thread_create(fn, NULL, FALSE, NULL); +#endif + #ifndef _WIN32 pthread_sigmask(SIG_SETMASK, &oldset, NULL); #endif @@ -418,8 +434,10 @@ bool trace_backend_init(const char *events, const char *file) #endif } +#if !GLIB_CHECK_VERSION(2, 31, 0) trace_available_cond = g_cond_new(); trace_empty_cond = g_cond_new(); +#endif thread = trace_thread_create(writeout_thread); if (!thread) { |