aboutsummaryrefslogtreecommitdiff
path: root/replay/replay.c
diff options
context:
space:
mode:
authorPavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>2018-02-27 12:53:05 +0300
committerPaolo Bonzini <pbonzini@redhat.com>2018-03-12 17:10:38 +0100
commit66eb7825d0bd84a870a054fb208fe765317109fa (patch)
treef29488c4f4e8073c185506ae652d38b62605d2cd /replay/replay.c
parent6dc0f5296359ff59c248215a965c8658dea9544b (diff)
replay: avoid recursive call of checkpoints
This patch adds a flag which denies recursive call of replay_checkpoint function. Checkpoints may be accompanied by the hardware events. When event is processed, virtual device may invoke timer modification functions that also invoke the checkpoint function. This leads to infinite loop. Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru> Message-Id: <20180227095305.1060.56463.stgit@pasha-VirtualBox> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
Diffstat (limited to 'replay/replay.c')
-rw-r--r--replay/replay.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/replay/replay.c b/replay/replay.c
index 90f98b7490..eae8daf18a 100644
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -176,13 +176,24 @@ void replay_shutdown_request(ShutdownCause cause)
bool replay_checkpoint(ReplayCheckpoint checkpoint)
{
bool res = false;
+ static bool in_checkpoint;
assert(EVENT_CHECKPOINT + checkpoint <= EVENT_CHECKPOINT_LAST);
- replay_save_instructions();
if (!replay_file) {
return true;
}
+ if (in_checkpoint) {
+ /* If we are already in checkpoint, then there is no need
+ for additional synchronization.
+ Recursion occurs when HW event modifies timers.
+ Timer modification may invoke the checkpoint and
+ proceed to recursion. */
+ return true;
+ }
+ in_checkpoint = true;
+
+ replay_save_instructions();
if (replay_mode == REPLAY_MODE_PLAY) {
g_assert(replay_mutex_locked());
@@ -204,6 +215,7 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint)
res = true;
}
out:
+ in_checkpoint = false;
return res;
}