replay additions
v9 cover replay additions
This set of patches fixes some vmstate creation (and loading) issues in record/replay modes:
- VM start/stop fixes in replay mode
- overlay creation for blkreplay filter
- fixes for vmstate save/load in record/replay mode
- fixes for host clock vmstate
- fixes for icount timers vmstate
v9 changes:
- Added vmstate for host clock parameters and icount timers
- Fixed replay event queue issues
- Fixed vm stopping while recording or replaying the execution
- Fixed save/load vmstate issues in record/replay mode
v8 changes:
- Refined replay exception processing (as suggested by Paolo Bonzini)
- Saving/restoring static variable for APIC only once (as suggested by Paolo Bonzini)
- Removed already queued patches
- Minor fixes
v7 changes:
- Fixed exception replaying when TB cache is full and
when tb_find is called when there are no instructions about to execute
- Added record/replay for audio devices
v6 changes:
- Added overlay creation for blkreplay driver
- Fixed vmstate loading for apic and rtc
- Fixed instruction counting for apic instruction patching
v5 changes:
- Recording is stopped when initial snapshot cannot be created
- Minor changes
v4 changes:
- Overlay option is removed from blkreplay driver (as suggested by Paolo Bonzini)
- Minor changes
v3 changes:
- Added rrsnapshot option for specifying the initial snapshot name (as suggested by Paolo Bonzini)
- Minor changes
---
Pavel Dovgalyuk (10):
block: implement bdrv_snapshot_goto for blkreplay
blkreplay: create temporary overlay for underlaying devices
replay: disable default snapshot for record/replay
replay: fix processing async events
replay: fixed replay_enable_events
replay: fix save/load vm for non-empty queue
replay: added replay log format description
replay: make safe vmstop at record/replay
replay: save prior value of the host clock
icount: fixed saving/restoring of icount warp timers
block/blkreplay.c | 73 +++++++++++++++++++++++++++++++++++++ cpus.c | 90 +++++++++++++++++++++++++++++++++++----------- docs/replay.txt | 69 +++++++++++++++++++++++++++++++++++ include/qemu/timer.h | 14 +++++++ include/sysemu/replay.h | 3 ++ migration/savevm.c | 13 +++++++ replay/replay-events.c | 12 ++++-- replay/replay-internal.h | 2 + replay/replay-snapshot.c | 9 +++++ stubs/replay.c | 1 + util/qemu-timer.c | 12 ++++++ vl.c | 10 ++++- 12 files changed, 279 insertions(+), 29 deletions(-)
Signature · 1 line
Pavel Dovgalyuk
PATCH v9 1/10 block: implement bdrv_snapshot_goto for blkreplay
This patch enables making snapshots with blkreplay used in block devices.
This function is required to make bdrv_snapshot_goto without calling .bdrv_open which is not implemented.
--- block/blkreplay.c | 8 ++++++++ 1 file changed, 8 insertions(+)
block/blkreplay.c +8 -0
@@ -130,6 +130,12 @@ static int coroutine_fn blkreplay_co_flush(BlockDriverState *bs)return ret; } +static int blkreplay_snapshot_goto (BlockDriverState *bs, +const char *snapshot_id) +{ +return bdrv_snapshot_goto (bs->file->bs, snapshot_id); +} +static BlockDriver bdrv_blkreplay = { .format_name ="blkreplay" , .protocol_name ="blkreplay" ,
@@ -146,6 +152,8 @@ static BlockDriver bdrv_blkreplay = { .bdrv_co_pwrite_zeroes = blkreplay_co_pwrite_zeroes, .bdrv_co_pdiscard = blkreplay_co_pdiscard, .bdrv_co_flush = blkreplay_co_flush, + + .bdrv_snapshot_goto = blkreplay_snapshot_goto, };static void bdrv_blkreplay_init (void )
PATCH v9 2/10 blkreplay: create temporary overlay for underlaying devices
In reply to Pavel DovgalyukThis patch allows using '-snapshot' behavior in record/replay mode. blkreplay layer creates temporary overlays on top of underlaying disk images. It is needed, because creating an overlay over blkreplay breaks the determinism.
This patch creates similar temporary overlay (when it is needed) under the blkreplay driver. Therefore all block operations are controlled by blkreplay.
--- block/blkreplay.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++ stubs/replay.c | 1 + vl.c | 2 +- 3 files changed, 67 insertions(+), 1 deletion(-)
block/blkreplay.c +65 -0
@@ -14,12 +14,69 @@#include "block/block_int.h" #include "sysemu/replay.h" #include "qapi/error.h" +#include "qapi/qmp/qstring.h" typedef struct Request {Coroutine *co;QEMUBH *bh; }Request ; +static BlockDriverState *blkreplay_append_snapshot (BlockDriverState *bs, +Error **errp) +{ +int ret; +BlockDriverState *bs_snapshot; +int64_t total_size; +QemuOpts *opts =NULL ; +char tmp_filename[PATH_MAX +1 ]; +QDict *snapshot_options =qdict_new (); + +/* Prepare options QDict for the overlay file */ +qdict_put (snapshot_options,"file.driver" ,qstring_from_str ("file" )); +qdict_put (snapshot_options,"driver" ,qstring_from_str ("qcow2" )); + +/* Create temporary file */ + ret =get_tmp_filename (tmp_filename,PATH_MAX +1 ); +if (ret <0 ) { +error_setg_errno (errp, -ret,"Could not get temporary filename" ); + goto out; + } +qdict_put (snapshot_options,"file.filename" , +qstring_from_str (tmp_filename)); + +/* Get the required size from the image */ + total_size =bdrv_getlength (bs); +if (total_size <0 ) { +error_setg_errno (errp, -total_size,"Could not get image size" ); + goto out; + } + + opts =qemu_opts_create (bdrv_qcow2.create_opts,NULL ,0 , &error_abort); +qemu_opt_set_number (opts,BLOCK_OPT_SIZE , total_size, &error_abort); + ret =bdrv_create (&bdrv_qcow2, tmp_filename, opts, errp); +qemu_opts_del (opts); +if (ret <0 ) { +error_prepend (errp,"Could not create temporary overlay '%s': " , + tmp_filename); + goto out; + } + + bs_snapshot =bdrv_open (NULL ,NULL , snapshot_options, +BDRV_O_RDWR |BDRV_O_TEMPORARY , errp); + snapshot_options =NULL ; +if (!bs_snapshot) { + goto out; + } + +bdrv_append (bs_snapshot, bs, errp); + +return bs_snapshot; + +out: +QDECREF (snapshot_options); +return NULL ; +} +static int blkreplay_open (BlockDriverState *bs,QDict *options,int flags,Error **errp) {
@@ -35,6 +92,14 @@ static int blkreplay_open(BlockDriverState *bs, QDict *options, int flags, goto fail; } +/* Add temporary snapshot to preserve the image */ +if (!replay_snapshot + && !blkreplay_append_snapshot (bs->file->bs, &local_err)) { + ret = -EINVAL ; +error_propagate (errp, local_err); + goto fail; + } + ret =0 ; fail:if (ret <0 ) {
stubs/replay.c +1 -0
@@ -3,6 +3,7 @@#include "sysemu/sysemu.h" ReplayMode replay_mode; +char *replay_snapshot;int64_t replay_save_clock (unsigned int kind,int64_t clock) {
vl.c +1 -1
@@ -4492,7 +4492,7 @@ int main(int argc, char **argv, char **envp)qapi_free_BlockdevOptions (bdo->bdo);g_free (bdo); } -if (snapshot || replay_mode !=REPLAY_MODE_NONE ) { +if (snapshot) {qemu_opts_foreach (qemu_find_opts ("drive" ), drive_enable_snapshot,NULL ,NULL ); }
PATCH v9 3/10 replay: disable default snapshot for record/replay
In reply to Pavel DovgalyukThis patch disables setting '-snapshot' option on by default in record/replay mode. This is needed for creating vmstates in record and replay modes.
--- vl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
vl.c +7 -1
@@ -3168,7 +3168,13 @@ int main(int argc, char **argv, char **envp)drive_add (IF_PFLASH ,-1 , optarg,PFLASH_OPTS );break ;case QEMU_OPTION_snapshot: - snapshot =1 ; + { +Error *blocker =NULL ; + snapshot =1 ; +error_setg (&blocker,QERR_REPLAY_NOT_SUPPORTED , +"-snapshot" ); +replay_add_blocker (blocker); + }break ;case QEMU_OPTION_hdachs: {
PATCH v9 4/10 replay: fix processing async events
In reply to Pavel DovgalyukFrom: Pavel Dovgalyuk <[email protected]>
Asynchronous events saved at checkpoints may invoke callbacks when processed. These callbacks may also generate/read new events (e.g. clock reads). Therefore event processing flag must be reset before callback invocation.
--- replay/replay-events.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
replay/replay-events.c +2 -2
@@ -295,13 +295,13 @@ void replay_read_events(int checkpoint)if (!event) {break ; } +replay_finish_event (); + read_event_kind =-1 ;replay_mutex_unlock ();replay_run_event (event);replay_mutex_lock ();g_free (event); -replay_finish_event (); - read_event_kind =-1 ; } }
Re: [Qemu-devel] [PATCH v9 04/10] replay: fix processing async events
Quoted 19 lines · Pavel Dovgalyuk
From: Pavel Dovgalyuk <[email protected]>
Asynchronous events saved at checkpoints may invoke callbacks when processed. These callbacks may also generate/read new events (e.g. clock reads). Therefore event processing flag must be reset before callback invocation.
Signed-off-by Pavel Dovgalyuk <[email protected]>--- replay/replay-events.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)replay/replay-events.c +0
-0@@ -295,13 +295,13 @@ void replay_read_events(int checkpoint)if (!event) {break ;
replay/replay-events.c void replay_read_events(int checkpoint) · line 304
Quoted 10 lines
replay/replay-events.c +2
-2} +replay_finish_event (); + read_event_kind =-1 ;replay_mutex_unlock ();replay_run_event (event);replay_mutex_lock ();g_free (event); -replay_finish_event (); - read_event_kind =-1 ;
While at it, g_free can be moved outside the lock.
Also, replay_flush_events and replay_save_events are leaving the event in events_list while releasing the lock, and only doing QTAILQ_REMOVE after taking it back. This can cause events to be processed twice.
I think it is worth fixing all of these.
Paolo
Quoted 4 lines
replay/replay-events.c +0
-0} }
Re: [Qemu-devel] [PATCH v9 04/10] replay: fix processing async events
Quoted 28 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 26 lines · Pavel Dovgalyuk
From: Pavel Dovgalyuk <[email protected]>
Asynchronous events saved at checkpoints may invoke callbacks when processed. These callbacks may also generate/read new events (e.g. clock reads). Therefore event processing flag must be reset before callback invocation.
Signed-off-by Pavel Dovgalyuk <[email protected]>--- replay/replay-events.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)replay/replay-events.c +2
-0@@ -295,13 +295,13 @@ void replay_read_events(int checkpoint)if (!event) {break ; } +replay_finish_event (); + read_event_kind =-1 ;replay_mutex_unlock ();replay_run_event (event);replay_mutex_lock ();
Quoted 5 lines
replay/replay-events.c void replay_read_events(int checkpoint) · line 304
Quoted 3 lines
replay/replay-events.c +0
-2g_free (event); -replay_finish_event (); - read_event_kind =-1 ;While at it,
g_freecan be moved outside the lock.
There is no difference where to free the memory.
The only reason for unlocking and locking again is that replay_run_event may try to read more data from the log.
Quoted 3 lines
Also,
replay_flush_eventsandreplay_save_eventsare leaving the event inevents_listwhile releasing the lock, and only doingQTAILQ_REMOVEafter taking it back. This can cause events to be processed twice.
How this could happen? If something will try to call replay_save_events again, while in replay_save_events, then we'll have an infinite loop and notice it. But it couldn't, because saving only occurs at checkpoints and there are no recursive ones.
Pavel Dovgalyuk
PATCH v9 5/10 replay: fixed replay_enable_events
In reply to Pavel DovgalyukFrom: Pavel Dovgalyuk <[email protected]>
This patch fixes assignment to internal events_enabled variable. Now it is set only in record/replay mode. This affects the behavior of the external functions that check this flag.
--- replay/replay-events.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
replay/replay-events.c +5 -3
@@ -67,7 +67,9 @@ static void replay_run_event(Event *event)void replay_enable_events (void ) { - events_enabled = true; +if (replay_mode !=REPLAY_MODE_NONE ) { + events_enabled = true; + } }bool replay_has_events (void )
@@ -141,7 +143,7 @@ void replay_add_event(ReplayAsyncEventKind event_kind,void replay_bh_schedule_event (QEMUBH *bh) { -if (replay_mode !=REPLAY_MODE_NONE && events_enabled) { +if (events_enabled) {uint64_t id =replay_get_current_step ();replay_add_event (REPLAY_ASYNC_EVENT_BH , bh,NULL , id); }else {
@@ -161,7 +163,7 @@ void replay_add_input_sync_event(void)void replay_block_event (QEMUBH *bh,uint64_t id) { -if (replay_mode !=REPLAY_MODE_NONE && events_enabled) { +if (events_enabled) {replay_add_event (REPLAY_ASYNC_EVENT_BLOCK , bh,NULL , id); }else {qemu_bh_schedule (bh);
PATCH v9 6/10 replay: fix save/load vm for non-empty queue
In reply to Pavel DovgalyukFrom: Pavel Dovgalyuk <[email protected]>
This patch does not allows saving/loading vmstate when replay events queue is not empty. There is no reliable way to save events queue, because it describes internal coroutine state. Therefore saving and loading operations should be deferred to another record/replay step.
--- include/sysemu/replay.h | 3 +++ migration/savevm.c | 13 +++++++++++++ replay/replay-snapshot.c | 6 ++++++ 3 files changed, 22 insertions(+)
include/sysemu/replay.h +3 -0
@@ -164,5 +164,8 @@ void replay_audio_in(int *recorded, void *samples, int *wpos, int size);/*! Called at the start of execution. Loads or saves initial vmstate depending on execution mode. */ void replay_vmstate_init (void ); +/*! Called to ensure that replay state is consistent and VM snapshot +can be created */ +bool replay_can_snapshot (void );#endif
migration/savevm.c +13 -0
@@ -54,6 +54,7 @@#include "qemu/cutils.h" #include "io/channel-buffer.h" #include "io/channel-file.h" +#include "sysemu/replay.h" #ifndef ETH_P_RARP #define ETH_P_RARP 0x8035
@@ -2083,6 +2084,12 @@ int save_vmstate(Monitor *mon, const char *name)Error *local_err =NULL ;AioContext *aio_context; +if (!replay_can_snapshot ()) { +monitor_printf (mon,"Record/replay does not allow making snapshot right now. " +"Try stopping at another step.\n" ); +return ret; + } +if (!bdrv_all_can_snapshot (&bs)) {monitor_printf (mon,"Device '%s' is writable but does not " "support snapshots.\n" ,bdrv_get_device_name (bs));
@@ -2244,6 +2251,12 @@ int load_vmstate(const char *name)AioContext *aio_context;MigrationIncomingState *mis =migration_incoming_get_current (); +if (!replay_can_snapshot ()) { +error_report ("Record/replay does not allow loading snapshot right now. " +"Try stopping at another step.\n" ); +return -EINVAL ; + } +if (!bdrv_all_can_snapshot (&bs)) {error_report ("Device '%s' is writable but does not support snapshots." ,bdrv_get_device_name (bs));
replay/replay-snapshot.c +6 -0
@@ -76,3 +76,9 @@ void replay_vmstate_init(void) } } } + +bool replay_can_snapshot (void ) +{ +return replay_mode ==REPLAY_MODE_NONE + || !replay_has_events (); +}
Re: [Qemu-devel] [PATCH v9 06/10] replay: fix save/load vm for non-empty queue
Quoted 9 lines · Pavel Dovgalyuk
From: Pavel Dovgalyuk <[email protected]>
This patch does not allows saving/loading vmstate when replay events queue is not empty. There is no reliable way to save events queue, because it describes internal coroutine state. Therefore saving and loading operations should be deferred to another record/replay step.
Signed-off-by Pavel Dovgalyuk <[email protected]>
This functions have changed, see last series (but change is trivial from monitor_printf to error_<something>)
migration/savevm.c int save_vmstate(Monitor *mon, const char *name) · line 2092
Quoted 10 lines
migration/savevm.c +6
-0@@ -2083,6 +2084,12 @@ int save_vmstate(Monitor *mon, const char *name)Error *local_err =NULL ;AioContext *aio_context; +if (!replay_can_snapshot ()) { +monitor_printf (mon,"Record/replay does not allow making snapshot right now. " +"Try stopping at another step.\n" ); +return ret; + } +
To issue a savevm/loadvm the user don't have to stop qemu, so I think we can improve the message to something les in both places?
"Try saving/loading later"?
Thanks, Juan.
Re: [Qemu-devel] [PATCH v9 06/10] replay: fix save/load vm for non-empty queue
Quoted 29 lines
From: Juan Quintela [mailto:[email protected]]
Quoted 9 lines · Pavel Dovgalyuk
From: Pavel Dovgalyuk <[email protected]>
This patch does not allows saving/loading vmstate when replay events queue is not empty. There is no reliable way to save events queue, because it describes internal coroutine state. Therefore saving and loading operations should be deferred to another record/replay step.
Signed-off-by Pavel Dovgalyuk <[email protected]>This functions have changed, see last series (but change is trivial from
monitor_printfto error_<something>)migration/savevm.c int save_vmstate(Monitor *mon, const char *name) · line 2092
Quoted 10 lines
migration/savevm.c +6
-0@@ -2083,6 +2084,12 @@ int save_vmstate(Monitor *mon, const char *name)Error *local_err =NULL ;AioContext *aio_context; +if (!replay_can_snapshot ()) { +monitor_printf (mon,"Record/replay does not allow making snapshot right now. " +"Try stopping at another step.\n" ); +return ret; + } +To issue a savevm/loadvm the user don't have to stop qemu, so I think we can improve the message to something les in both places?
Quoted 1 line
"Try saving/loading later"?
Right, thanks.
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v9 06/10] replay: fix save/load vm for non-empty queue
In reply to Pavel DovgalyukQuoted 7 lines · Pavel Dovgalyuk
From: Pavel Dovgalyuk <[email protected]>
This patch does not allows saving/loading vmstate when replay events queue is not empty. There is no reliable way to save events queue, because it describes internal coroutine state. Therefore saving and loading operations should be deferred to another record/replay step.
Can it actually be non-empty after bdrv_drain_all?
Paolo
Quoted 73 lines
Signed-off-by Pavel Dovgalyuk <[email protected]>--- include/sysemu/replay.h | 3 +++ migration/savevm.c | 13 +++++++++++++ replay/replay-snapshot.c | 6 ++++++ 3 files changed, 22 insertions(+)include/sysemu/replay.h +3
-0@@ -164,5 +164,8 @@ void replay_audio_in(int *recorded, void *samples, int *wpos, int size);/*! Called at the start of execution. Loads or saves initial vmstate depending on execution mode. */ void replay_vmstate_init (void ); +/*! Called to ensure that replay state is consistent and VM snapshot +can be created */ +bool replay_can_snapshot (void );#endif migration/savevm.c +13
-0@@ -54,6 +54,7 @@#include "qemu/cutils.h" #include "io/channel-buffer.h" #include "io/channel-file.h" +#include "sysemu/replay.h" #ifndef ETH_P_RARP #define ETH_P_RARP 0x8035@@ -2083,6 +2084,12 @@ int save_vmstate(Monitor *mon, const char *name)Error *local_err =NULL ;AioContext *aio_context; +if (!replay_can_snapshot ()) { +monitor_printf (mon,"Record/replay does not allow making snapshot right now. " +"Try stopping at another step.\n" ); +return ret; + } +if (!bdrv_all_can_snapshot (&bs)) {monitor_printf (mon,"Device '%s' is writable but does not " "support snapshots.\n" ,bdrv_get_device_name (bs));@@ -2244,6 +2251,12 @@ int load_vmstate(const char *name)AioContext *aio_context;MigrationIncomingState *mis =migration_incoming_get_current (); +if (!replay_can_snapshot ()) { +error_report ("Record/replay does not allow loading snapshot right now. " +"Try stopping at another step.\n" ); +return -EINVAL ; + } +if (!bdrv_all_can_snapshot (&bs)) {error_report ("Device '%s' is writable but does not support snapshots." ,bdrv_get_device_name (bs));replay/replay-snapshot.c +6
-0@@ -76,3 +76,9 @@ void replay_vmstate_init(void) } } } + +bool replay_can_snapshot (void ) +{ +return replay_mode ==REPLAY_MODE_NONE + || !replay_has_events (); +}
Re: [Qemu-devel] [PATCH v9 06/10] replay: fix save/load vm for non-empty queue
Quoted 11 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 7 lines · Pavel Dovgalyuk
From: Pavel Dovgalyuk <[email protected]>
This patch does not allows saving/loading vmstate when replay events queue is not empty. There is no reliable way to save events queue, because it describes internal coroutine state. Therefore saving and loading operations should be deferred to another record/replay step.
Can it actually be non-empty after
bdrv_drain_all?
drain/flush cannot succeed, because started requests are prisoned in the replay events queue.
Quoted 65 lines
Quoted 65 lines
Signed-off-by Pavel Dovgalyuk <[email protected]>--- include/sysemu/replay.h | 3 +++ migration/savevm.c | 13 +++++++++++++ replay/replay-snapshot.c | 6 ++++++ 3 files changed, 22 insertions(+)include/sysemu/replay.h +3
-0@@ -164,5 +164,8 @@ void replay_audio_in(int *recorded, void *samples, int *wpos, int size);/*! Called at the start of execution. Loads or saves initial vmstate depending on execution mode. */ void replay_vmstate_init (void ); +/*! Called to ensure that replay state is consistent and VM snapshot +can be created */ +bool replay_can_snapshot (void );#endif migration/savevm.c +13
-0@@ -54,6 +54,7 @@#include "qemu/cutils.h" #include "io/channel-buffer.h" #include "io/channel-file.h" +#include "sysemu/replay.h" #ifndef ETH_P_RARP #define ETH_P_RARP 0x8035@@ -2083,6 +2084,12 @@ int save_vmstate(Monitor *mon, const char *name)Error *local_err =NULL ;AioContext *aio_context; +if (!replay_can_snapshot ()) { +monitor_printf (mon,"Record/replay does not allow making snapshot right now. " +"Try stopping at another step.\n" ); +return ret; + } +if (!bdrv_all_can_snapshot (&bs)) {monitor_printf (mon,"Device '%s' is writable but does not " "support snapshots.\n" ,bdrv_get_device_name (bs));@@ -2244,6 +2251,12 @@ int load_vmstate(const char *name)AioContext *aio_context;MigrationIncomingState *mis =migration_incoming_get_current (); +if (!replay_can_snapshot ()) { +error_report ("Record/replay does not allow loading snapshot right now. " +"Try stopping at another step.\n" ); +return -EINVAL ; + } +if (!bdrv_all_can_snapshot (&bs)) {error_report ("Device '%s' is writable but does not support snapshots." ,bdrv_get_device_name (bs));replay/replay-snapshot.c +0
-0@@ -76,3 +76,9 @@ void replay_vmstate_init(void) } }
Quoted 8 lines
replay/replay-snapshot.c void replay_vmstate_init(void) · line 84
Quoted 8 lines
replay/replay-snapshot.c +6
-0} + +bool replay_can_snapshot (void ) +{ +return replay_mode ==REPLAY_MODE_NONE + || !replay_has_events (); +}
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v9 06/10] replay: fix save/load vm for non-empty queue
Quoted 10 lines · Pavel Dovgalyuk
Quoted 7 lines
Quoted 5 lines
This patch does not allows saving/loading vmstate when replay events queue is not empty. There is no reliable way to save events queue, because it describes internal coroutine state. Therefore saving and loading operations should be deferred to another record/replay step.
Can it actually be non-empty after
bdrv_drain_all?drain/flush cannot succeed, because started requests are prisoned in the replay events queue.
But that would apply to loading only. Saving should still be always possible.
Paolo
Re: [Qemu-devel] [PATCH v9 06/10] replay: fix save/load vm for non-empty queue
Quoted 8 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 6 lines · Pavel Dovgalyuk
Quoted 6 lines
Quoted 5 lines
This patch does not allows saving/loading vmstate when replay events queue is not empty. There is no reliable way to save events queue, because it describes internal coroutine state. Therefore saving and loading operations should be deferred to another record/replay step.
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
Can it actually be non-empty after
bdrv_drain_all?drain/flush cannot succeed, because started requests are prisoned in the replay events queue.
But that would apply to loading only. Saving should still be always possible.
We can save it. But it wouldn't load correctly - replay queue will be empty after loading.
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v9 06/10] replay: fix save/load vm for non-empty queue
Quoted 10 lines · Pavel Dovgalyuk
Quoted 10 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 8 lines · Pavel Dovgalyuk
Quoted 7 lines
Quoted 5 lines
This patch does not allows saving/loading vmstate when replay events queue is not empty. There is no reliable way to save events queue, because it describes internal coroutine state. Therefore saving and loading operations should be deferred to another record/replay step.
Can it actually be non-empty after
bdrv_drain_all?
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
drain/flush cannot succeed, because started requests are prisoned in the replay events queue.
But that would apply to loading only. Saving should still be always possible.
We can save it. But it wouldn't load correctly - replay queue will be empty after loading.
When saving you can drain, and then the events queue should be empty. Or I am misunderstanding how it works, which is possible too.
Paolo
Re: [Qemu-devel] [PATCH v9 06/10] replay: fix save/load vm for non-empty queue
Quoted 15 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 13 lines · Pavel Dovgalyuk
Quoted 13 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 10 lines · Pavel Dovgalyuk
Quoted 7 lines
Quoted 5 lines
This patch does not allows saving/loading vmstate when replay events queue is not empty. There is no reliable way to save events queue, because it describes internal coroutine state. Therefore saving and loading operations should be deferred to another record/replay step.
Can it actually be non-empty after
bdrv_drain_all?drain/flush cannot succeed, because started requests are prisoned in the replay events queue.
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
But that would apply to loading only. Saving should still be always possible.
We can save it. But it wouldn't load correctly - replay queue will be empty after loading.
When saving you can drain, and then the events queue should be empty. Or I am misunderstanding how it works, which is possible too.
Drain will wait until the queue becomes empty.
Queue is processed only at checkpoints.
Checkpoints are met in iothread (at timers processing and so on). But iothread is waiting for finishing the drain.
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v9 06/10] replay: fix save/load vm for non-empty queue
Quoted 20 lines · Pavel Dovgalyuk
Quoted 20 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 17 lines · Pavel Dovgalyuk
Quoted 8 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 6 lines · Pavel Dovgalyuk
Quoted 6 lines
Quoted 5 lines
This patch does not allows saving/loading vmstate when replay events queue is not empty. There is no reliable way to save events queue, because it describes internal coroutine state. Therefore saving and loading operations should be deferred to another record/replay step.
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
Can it actually be non-empty after
bdrv_drain_all?drain/flush cannot succeed, because started requests are prisoned in the replay events queue.
But that would apply to loading only. Saving should still be always possible.
We can save it. But it wouldn't load correctly - replay queue will be empty after loading.
Quoted 7 lines
Quoted 2 lines
When saving you can drain, and then the events queue should be empty. Or I am misunderstanding how it works, which is possible too.
Drain will wait until the queue becomes empty.
Queue is processed only at checkpoints.
Checkpoints are met in iothread (at timers processing and so on). But iothread is waiting for finishing the drain.
What checkpoint can hang the drain during a save?
Paolo
Re: [Qemu-devel] [PATCH v9 06/10] replay: fix save/load vm for non-empty queue
Quoted 25 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 23 lines · Pavel Dovgalyuk
Quoted 22 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 10 lines · Pavel Dovgalyuk
Quoted 10 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 8 lines · Pavel Dovgalyuk
Quoted 7 lines
Quoted 5 lines
This patch does not allows saving/loading vmstate when replay events queue is not empty. There is no reliable way to save events queue, because it describes internal coroutine state. Therefore saving and loading operations should be deferred to another record/replay step.
Can it actually be non-empty after
bdrv_drain_all?Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
drain/flush cannot succeed, because started requests are prisoned in the replay events queue.
But that would apply to loading only. Saving should still be always possible.
We can save it. But it wouldn't load correctly - replay queue will be empty after loading.
When saving you can drain, and then the events queue should be empty. Or I am misunderstanding how it works, which is possible too.
Quoted 6 lines
Quoted 4 lines
Drain will wait until the queue becomes empty.
Queue is processed only at checkpoints.
Checkpoints are met in iothread (at timers processing and so on). But iothread is waiting for finishing the drain.What checkpoint can hang the drain during a save?
No one. There are no checkpoins during vmsave and during drain. Therefore the queue will never become empty.
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v9 06/10] replay: fix save/load vm for non-empty queue
Quoted 30 lines · Pavel Dovgalyuk
Quoted 30 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 27 lines · Pavel Dovgalyuk
Quoted 15 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 13 lines · Pavel Dovgalyuk
Quoted 13 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 10 lines · Pavel Dovgalyuk
Quoted 7 lines
Quoted 5 lines
This patch does not allows saving/loading vmstate when replay events queue is not empty. There is no reliable way to save events queue, because it describes internal coroutine state. Therefore saving and loading operations should be deferred to another record/replay step.
Can it actually be non-empty after
bdrv_drain_all?drain/flush cannot succeed, because started requests are prisoned in the replay events queue.
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
But that would apply to loading only. Saving should still be always possible.
We can save it. But it wouldn't load correctly - replay queue will be empty after loading.
When saving you can drain, and then the events queue should be empty. Or I am misunderstanding how it works, which is possible too.
Drain will wait until the queue becomes empty.
Queue is processed only at checkpoints.
Checkpoints are met in iothread (at timers processing and so on). But iothread is waiting for finishing the drain.
Quoted 4 lines
Quoted 1 line
What checkpoint can hang the drain during a save?
No one. There are no checkpoins during vmsave and during drain. Therefore the queue will never become empty.
Understood. And what checkpoint will you be waiting for during drain, causing a deadlock?
Paolo
Re: [Qemu-devel] [PATCH v9 06/10] replay: fix save/load vm for non-empty queue
Quoted 33 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 14 lines · Pavel Dovgalyuk
Quoted 14 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 12 lines · Pavel Dovgalyuk
Quoted 12 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 10 lines · Pavel Dovgalyuk
Quoted 10 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 8 lines · Pavel Dovgalyuk
Quoted 7 lines
Quoted 5 lines
This patch does not allows saving/loading vmstate when replay events queue is not empty. There is no reliable way to save events queue, because it describes internal coroutine state. Therefore saving and loading operations should be deferred to another record/replay step.
Can it actually be non-empty after
bdrv_drain_all?Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
drain/flush cannot succeed, because started requests are prisoned in the replay events queue.
But that would apply to loading only. Saving should still be always possible.
We can save it. But it wouldn't load correctly - replay queue will be empty after
loading.
Quoted 9 lines
Quoted 9 lines
Quoted 8 lines
Quoted 3 lines
When saving you can drain, and then the events queue should be empty. Or I am misunderstanding how it works, which is possible too.
Drain will wait until the queue becomes empty.
Queue is processed only at checkpoints.
Checkpoints are met in iothread (at timers processing and so on). But iothread is waiting for finishing the drain.
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
What checkpoint can hang the drain during a save?
No one. There are no checkpoins during vmsave and during drain. Therefore the queue will never become empty.
Understood. And what checkpoint will you be waiting for during drain, causing a deadlock?
Every checkpoint processes the queue, but none of them are invoked,
because iothread (which invokes all the checkpoints) is waiting for the end of the drain.
And we cannot add a checkpoint into the drain, because then vmstop will affect the behavior of the guest.
Pavel Dovgalyuk
Re: [Qemu-devel] [PATCH v9 06/10] replay: fix save/load vm for non-empty queue
Quoted 7 lines · Pavel Dovgalyuk
Quoted 2 lines
Understood. And what checkpoint will you be waiting for during drain, causing a deadlock?
Every checkpoint processes the queue, but none of them are invoked,
because iothread (which invokes all the checkpoints) is waiting for the end of the drain.And we cannot add a checkpoint into the drain, because then vmstop will affect the behavior of the guest.
But it does affect the behavior already when RR is off. And it shouldn't be a problem if it does in record mode (as long as the effect can be replayed).
If RR cannot do drain reliably, not even in record mode, that is a huge problem because a lot of block layer operations assume they can.
Paolo
Re: [Qemu-devel] [PATCH v9 06/10] replay: fix save/load vm for non-empty queue
Quoted 7 lines
From: Paolo Bonzini [mailto:[email protected]]
Quoted 5 lines · Pavel Dovgalyuk
Quoted 2 lines
Understood. And what checkpoint will you be waiting for during drain, causing a deadlock?
Every checkpoint processes the queue, but none of them are invoked,
because iothread (which invokes all the checkpoints) is waiting for the end of the drain.
Quoted 6 lines
Quoted 2 lines
And we cannot add a checkpoint into the drain, because then vmstop will affect the behavior of the guest.
But it does affect the behavior already when RR is off. And it shouldn't be a problem if it does in record mode (as long as the effect can be replayed).
Then we'll have to add something like "stop" event which flushes the queue. And there is still a problem with stopping in replay mode, because there is no way to flush the queue, because coroutines are executing somewhere.
Quoted 2 lines
If RR cannot do drain reliably, not even in record mode, that is a huge problem because a lot of block layer operations assume they can.
I think it could be an acceptable limitation (like disabling savevm/loadvm when queue is not empty).
I assume that RR is mostly used for debugging and analysis and it could have some limitations of this kind.
Making our own block queue (instead of coroutines) is much worse, therefore we have to replay the original internal behavior.
Pavel Dovgalyuk
PATCH v9 7/10 replay: added replay log format description
In reply to Pavel DovgalyukThis patch adds description of the replay log file format into the docs/replay.txt.
--- docs/replay.txt | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+)
docs/replay.txt +69 -0
@@ -232,3 +232,72 @@ Audio devices Audio data is recorded and replay automatically. The command line for recording and replaying must contain identical specifications of audio hardware, e.g.: -soundhw ac97 + +Replay log format +----------------- + +Record/replay log consits of the header and the sequence of execution +events. The header includes 4-byte replay version id and 8-byte reserved +field. Version is updated every time replay log format changes to prevent +using replay log created by another build of qemu. + +The sequence of the events describes virtual machine state changes. +It includes all non-deterministic inputs of VM, synchronization marks and +instruction counts used to correctly inject inputs at replay. + +Synchronization marks (checkpoints) are used for synchronizing qemu threads +that perform operations with virtual hardware. These operations may change +system's state (e.g., change some register or generate interrupt) and +therefore should execute synchronously with CPU thread. + +Every event in the log includes 1-byte event id and optional arguments. +When argument is an array, it is stored as 4-byte array length +and corresponding number of bytes with data. +Here is the list of events that are written into the log: + + - EVENT_INSTRUCTION. Instructions executed since last event. + Argument: 4-byte number of executed instructions. + - EVENT_INTERRUPT. Used to synchronize interrupt processing. + - EVENT_EXCEPTION. Used to synchronize exception handling. + - EVENT_ASYNC. This is a group of events. They are always processed + together with checkpoints. When such an event is generated, it is + stored in the queue and processed only when checkpoint occurs. + Every such event is followed by 1-byte checkpoint id and 1-byte + async event id from the following list: + - REPLAY_ASYNC_EVENT_BH. Bottom-half callback. This event synchronizes + callbacks that affect virtual machine state, but normally called + asyncronously. + Argument: 8-byte operation id. + - REPLAY_ASYNC_EVENT_INPUT. Input device event. Contains + parameters of keyboard and mouse input operations + (key press/release, mouse pointer movement). + Arguments: 9-16 bytes depending of input event. + - REPLAY_ASYNC_EVENT_INPUT_SYNC. Internal input synchronization event. + - REPLAY_ASYNC_EVENT_CHAR_READ. Character (e.g., serial port) device input + initiated by the sender. + Arguments: 1-byte character device id. + Array with bytes were read. + - REPLAY_ASYNC_EVENT_BLOCK. Block device operation. Used to synchronize + operations with disk and flash drives with CPU. + Argument: 8-byte operation id. + - REPLAY_ASYNC_EVENT_NET. Incoming network packet. + Arguments: 1-byte network adapter id. + 4-byte packet flags. + Array with packet bytes. + - EVENT_SHUTDOWN. Occurs when user sends shutdown event to qemu, + e.g., by closing the window. + - EVENT_CHAR_WRITE. Used to synchronize character output operations. + Arguments: 4-byte output function return value. + 4-byte offset in the output array. + - EVENT_CHAR_READ_ALL. Used to synchronize character input operations, + initiated by qemu. + Argument: Array with bytes that were read. + - EVENT_CHAR_READ_ALL_ERROR. Unsuccessful character input operation, + initiated by qemu. + Argument: 4-byte error code. + - EVENT_CLOCK + clock_id. Group of events for host clock read operations. + Argument: 8-byte clock value. + - EVENT_CHECKPOINT + checkpoint_id. Checkpoint for synchronization of + CPU, internal threads, and asynchronous input events. May be followed + by one or more EVENT_ASYNC events. + - EVENT_END. Last event in the log.
PATCH v9 8/10 replay: make safe vmstop at record/replay
In reply to Pavel DovgalyukThis patch disables bdrv flush/drain in record/replay mode. When block request is in the replay queue it cannot be processed with drain/flush until it is found in the log. Therefore vm should just stop leaving unfinished operations in the queue.
--- cpus.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
cpus.c +4 -3
@@ -932,9 +932,10 @@ static int do_vm_stop(RunState state)qapi_event_send_stop (&error_abort); } -bdrv_drain_all (); -replay_disable_events (); - ret =bdrv_flush_all (); +if (!replay_events_enabled ()) { +bdrv_drain_all (); + ret =bdrv_flush_all (); + }return ret; }
PATCH v9 9/10 replay: save prior value of the host clock
In reply to Pavel DovgalyukFrom: Pavel Dovgalyuk <[email protected]>
This patch adds saving/restoring of the host clock field 'last'. It is used in host clock calculation and therefore clock may become incorrect when using restored vmstate.
--- include/qemu/timer.h | 14 ++++++++++++++ replay/replay-internal.h | 2 ++ replay/replay-snapshot.c | 3 +++ util/qemu-timer.c | 12 ++++++++++++ 4 files changed, 31 insertions(+)
include/qemu/timer.h +14 -0
@@ -251,6 +251,20 @@ bool qemu_clock_run_timers(QEMUClockType type);*/ bool qemu_clock_run_all_timers (void ); +/** +* qemu_clock_get_last: +* +* Returns last clock query time. +*/ +uint64_t qemu_clock_get_last (QEMUClockType type); +/** +* qemu_clock_set_last: +* +* Sets last clock query time. +*/ +void qemu_clock_set_last (QEMUClockType type,uint64_t last); + +/* * QEMUTimerList */
replay/replay-internal.h +2 -0
@@ -77,6 +77,8 @@ typedef struct ReplayState {This counter is global, because requests from different block devices should not get overlapping ids. */ uint64_t block_request_id; +/*! Prior value of the host clock */ +uint64_t host_clock_last; } ReplayState;extern ReplayState replay_state;
replay/replay-snapshot.c +3 -0
@@ -24,12 +24,14 @@ static void replay_pre_save(void *opaque) {ReplayState *state = opaque; state->file_offset =ftell (replay_file); + state->host_clock_last =qemu_clock_get_last (QEMU_CLOCK_HOST ); }static int replay_post_load (void *opaque,int version_id) {ReplayState *state = opaque;fseek (replay_file, state->file_offset,SEEK_SET ); +qemu_clock_set_last (QEMU_CLOCK_HOST , state->host_clock_last);/* If this was a vmstate, saved in recording mode, we need to initialize replay data fields. */ replay_fetch_data_kind ();
@@ -51,6 +53,7 @@ static const VMStateDescription vmstate_replay = { VMSTATE_UINT32(has_unread_data, ReplayState), VMSTATE_UINT64(file_offset, ReplayState), VMSTATE_UINT64(block_request_id, ReplayState), + VMSTATE_UINT64(host_clock_last, ReplayState),VMSTATE_END_OF_LIST () }, };
util/qemu-timer.c +12 -0
@@ -622,6 +622,18 @@ int64_t qemu_clock_get_ns(QEMUClockType type) } } +uint64_t qemu_clock_get_last (QEMUClockType type) +{ +QEMUClock *clock =qemu_clock_ptr (type); +return clock->last; +} + +void qemu_clock_set_last (QEMUClockType type,uint64_t last) +{ +QEMUClock *clock =qemu_clock_ptr (type); + clock->last = last; +} +void qemu_clock_register_reset_notifier (QEMUClockType type,Notifier *notifier) {
PATCH v9 10/10 icount: fixed saving/restoring of icount warp timers
In reply to Pavel DovgalyukFrom: Pavel Dovgalyuk <[email protected]>
This patch adds saving and restoring of the icount warp timers in the vmstate.
It is needed because there timers affect the virtual clock value. Therefore determinism of the execution in icount record/replay mode depends on determinism of the timers.
--- cpus.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 64 insertions(+), 19 deletions(-)
cpus.c +64 -19
@@ -118,16 +118,11 @@ static bool all_cpu_threads_idle(void)/* Protected by TimersState seqlock */ static bool icount_sleep = true; -static int64_t vm_clock_warp_start =-1 ;/* Conversion factor from emulated instructions to virtual clock ticks. */ static int icount_time_shift;/* Arbitrarily pick 1MIPS as the minimum allowable speed. */ #define MAX_ICOUNT_SHIFT 10 -static QEMUTimer *icount_rt_timer; -static QEMUTimer *icount_vm_timer; -static QEMUTimer *icount_warp_timer; - typedef struct TimersState { /* Protected by BQL. */ int64_t cpu_ticks_prev;
@@ -145,6 +140,11 @@ typedef struct TimersState {int64_t qemu_icount_bias;/* Only written by TCG thread */ int64_t qemu_icount; +/* for adjusting icount */ +int64_t vm_clock_warp_start; +QEMUTimer *icount_rt_timer; +QEMUTimer *icount_vm_timer; +QEMUTimer *icount_warp_timer; } TimersState;static TimersState timers_state;
@@ -430,14 +430,14 @@ static void icount_adjust(void)static void icount_adjust_rt (void *opaque) { -timer_mod (icount_rt_timer, +timer_mod (timers_state.icount_rt_timer,qemu_clock_get_ms (QEMU_CLOCK_VIRTUAL_RT ) +1000 );icount_adjust (); }static void icount_adjust_vm (void *opaque) { -timer_mod (icount_vm_timer, +timer_mod (timers_state.icount_vm_timer,qemu_clock_get_ns (QEMU_CLOCK_VIRTUAL ) +NANOSECONDS_PER_SECOND /10 );icount_adjust ();
@@ -458,7 +458,7 @@ static void icount_warp_rt(void)*/ do { seq =seqlock_read_begin (&timers_state.vm_clock_seqlock); - warp_start = vm_clock_warp_start; + warp_start = timers_state.vm_clock_warp_start; }while (seqlock_read_retry (&timers_state.vm_clock_seqlock, seq));if (warp_start ==-1 ) {
@@ -471,7 +471,7 @@ static void icount_warp_rt(void) cpu_get_clock_locked());int64_t warp_delta; - warp_delta = clock - vm_clock_warp_start; + warp_delta = clock - timers_state.vm_clock_warp_start;if (use_icount ==2 ) {/* * In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too
@@ -483,7 +483,7 @@ static void icount_warp_rt(void) } timers_state.qemu_icount_bias += warp_delta; } - vm_clock_warp_start =-1 ; + timers_state.vm_clock_warp_start =-1 ;seqlock_write_end (&timers_state.vm_clock_seqlock);if (qemu_clock_expired (QEMU_CLOCK_VIRTUAL )) {
@@ -592,11 +592,11 @@ void qemu_start_warp_timer(void)* every 100ms. */ seqlock_write_begin (&timers_state.vm_clock_seqlock); -if (vm_clock_warp_start ==-1 || vm_clock_warp_start > clock) { - vm_clock_warp_start = clock; +if (timers_state.vm_clock_warp_start ==-1 || timers_state.vm_clock_warp_start > clock) { + timers_state.vm_clock_warp_start = clock; }seqlock_write_end (&timers_state.vm_clock_seqlock); -timer_mod_anticipate (icount_warp_timer, clock + deadline); +timer_mod_anticipate (timers_state.icount_warp_timer, clock + deadline); } }else if (deadline ==0 ) {qemu_clock_notify (QEMU_CLOCK_VIRTUAL );
@@ -621,7 +621,7 @@ static void qemu_account_warp_timer(void)return ; } -timer_del (icount_warp_timer); +timer_del (timers_state.icount_warp_timer);icount_warp_rt (); }
@@ -630,6 +630,44 @@ static bool icount_state_needed(void *opaque)return use_icount; } +static bool warp_timer_state_needed (void *opaque) +{ +TimersState *s = opaque; +return s->icount_warp_timer !=NULL ; +} + +static bool adjust_timers_state_needed (void *opaque) +{ +TimersState *s = opaque; +return s->icount_rt_timer !=NULL ; +} + +/* +* Subsection for warp timer migration is optional, because may not be created +*/ +static const VMStateDescription icount_vmstate_warp_timer = { + .name ="timer/icount/warp_timer" , + .version_id =1 , + .minimum_version_id =1 , + .needed = warp_timer_state_needed, + .fields = (VMStateField []) { +VMSTATE_TIMER_PTR (icount_warp_timer, TimersState), +VMSTATE_END_OF_LIST () + } +}; + +static const VMStateDescription icount_vmstate_adjust_timers = { + .name ="timer/icount/timers" , + .version_id =1 , + .minimum_version_id =1 , + .needed = adjust_timers_state_needed, + .fields = (VMStateField []) { +VMSTATE_TIMER_PTR (icount_rt_timer, TimersState), +VMSTATE_TIMER_PTR (icount_vm_timer, TimersState), +VMSTATE_END_OF_LIST () + } +}; +/* * This is a subsection for icount migration. */
@@ -641,7 +679,13 @@ static const VMStateDescription icount_vmstate_timers = { .fields = (VMStateField[]) {VMSTATE_INT64 (qemu_icount_bias, TimersState),VMSTATE_INT64 (qemu_icount, TimersState), +VMSTATE_INT64 (vm_clock_warp_start, TimersState),VMSTATE_END_OF_LIST () + }, + .subsections = (const VMStateDescription *[]) { + &icount_vmstate_warp_timer, + &icount_vmstate_adjust_timers, +NULL } };
@@ -752,7 +796,7 @@ void configure_icount(QemuOpts *opts, Error **errp) icount_sleep =qemu_opt_get_bool (opts,"sleep" , true);if (icount_sleep) { - icount_warp_timer =timer_new_ns (QEMU_CLOCK_VIRTUAL_RT , + timers_state.icount_warp_timer =timer_new_ns (QEMU_CLOCK_VIRTUAL_RT , icount_timer_cb,NULL ); }
@@ -786,13 +830,14 @@ void configure_icount(QemuOpts *opts, Error **errp)the virtual time trigger catches emulated time passing too fast. Realtime triggers occur even when idle, so use them less frequently than VM triggers. */ - icount_rt_timer =timer_new_ms (QEMU_CLOCK_VIRTUAL_RT , + timers_state.vm_clock_warp_start =-1 ; + timers_state.icount_rt_timer =timer_new_ms (QEMU_CLOCK_VIRTUAL_RT , icount_adjust_rt,NULL ); -timer_mod (icount_rt_timer, +timer_mod (timers_state.icount_rt_timer,qemu_clock_get_ms (QEMU_CLOCK_VIRTUAL_RT ) +1000 ); - icount_vm_timer =timer_new_ns (QEMU_CLOCK_VIRTUAL , + timers_state.icount_vm_timer =timer_new_ns (QEMU_CLOCK_VIRTUAL , icount_adjust_vm,NULL ); -timer_mod (icount_vm_timer, +timer_mod (timers_state.icount_vm_timer,qemu_clock_get_ns (QEMU_CLOCK_VIRTUAL ) +NANOSECONDS_PER_SECOND /10 ); }
This series seems to have some coding style problems. See output below for more information:
Hi,
This series seems to have some coding style problems. See output below for more information:
Subject: [Qemu-devel] [PATCH v9 00/10] replay additions
Message-id: 20170504084135.7488.24715.stgit@PASHA-ISP
Type: series
=== TEST SCRIPT BEGIN ===
#!/bin/bash
BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0
git config --local diff.renamelimit 0
git config --local diff.renames True
commits="$(git log --format=%H --reverse $BASE..)" for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))done
exit $failed
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
- [tag update] patchew/[email protected] -> patchew/[email protected]
* [new tag] patchew/[email protected] -> patchew/[email protected]
Switched to a new branch 'test'
bf3cfc0 icount: fixed saving/restoring of icount warp timers 37b3637 replay: save prior value of the host clock 0a8766b replay: make safe vmstop at record/replay 3aecd8c replay: added replay log format description 0d8963d replay: fix save/load vm for non-empty queue 9c14e13 replay: fixed replay_enable_events
70c9cd1 replay: fix processing async events
37292c3 replay: disable default snapshot for record/replay 5973813 blkreplay: create temporary overlay for underlaying devices f34a13b block: implement bdrv_snapshot_goto for blkreplay
=== OUTPUT BEGIN ===
Checking PATCH 1/10: block: implement bdrv_snapshot_goto for blkreplay... Checking PATCH 2/10: blkreplay: create temporary overlay for underlaying devices... Checking PATCH 3/10: replay: disable default snapshot for record/replay... Checking PATCH 4/10: replay: fix processing async events...
Checking PATCH 5/10: replay: fixed replay_enable_events...
Checking PATCH 6/10: replay: fix save/load vm for non-empty queue...
WARNING: line over 80 characters
#45: FILE: migration/savevm.c:2088:
+ monitor_printf(mon, "Record/replay does not allow making snapshot right now. "
ERROR: Error messages should not contain newlines
#59: FILE: migration/savevm.c:2256:
+ "Try stopping at another step.\n");
total: 1 errors, 1 warnings, 48 lines checked
Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS.
Checking PATCH 7/10: replay: added replay log format description... Checking PATCH 8/10: replay: make safe vmstop at record/replay... Checking PATCH 9/10: replay: save prior value of the host clock... Checking PATCH 10/10: icount: fixed saving/restoring of icount warp timers...
ERROR: line over 90 characters
#98: FILE: cpus.c:595:
+ if (timers_state.vm_clock_warp_start == -1 || timers_state.vm_clock_warp_start > clock) {
WARNING: line over 80 characters
#103: FILE: cpus.c:599:
+ timer_mod_anticipate(timers_state.icount_warp_timer, clock + deadline);
ERROR: spaces required around that '*' (ctx:VxV)
#168: FILE: cpus.c:685:
+ .subsections = (const VMStateDescription*[]) {
^total: 2 errors, 1 warnings, 172 lines checked
Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===
Test command exited with code: 1
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to [email protected]