qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

replay: don't drain/flush bdrv queue while RR is working

In record/replay mode bdrv queue is controlled by replay mechanism.
It does not allow saving or loading the snapshots
when bdrv queue is not empty. Stopping the VM is not blocked by nonempty
queue, but flushing the queue is still impossible there,
because it may cause deadlocks in replay mode.
This patch disables bdrv_drain_all and bdrv_flush_all in
record/replay mode.

Stopping the machine when the IO requests are not finished is needed
for the debugging. E.g., breakpoint may be set at the specified step,
and forcing the IO requests to finish may break the determinism
of the execution.

Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
Acked-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>

authored by

Pavel Dovgalyuk and committed by
Kevin Wolf
c8aa7895 de499eb6

+28 -2
+28
block/io.c
··· 33 33 #include "qapi/error.h" 34 34 #include "qemu/error-report.h" 35 35 #include "qemu/main-loop.h" 36 + #include "sysemu/replay.h" 36 37 37 38 #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */ 38 39 ··· 600 601 return; 601 602 } 602 603 604 + /* 605 + * bdrv queue is managed by record/replay, 606 + * waiting for finishing the I/O requests may 607 + * be infinite 608 + */ 609 + if (replay_events_enabled()) { 610 + return; 611 + } 612 + 603 613 /* AIO_WAIT_WHILE() with a NULL context can only be called from the main 604 614 * loop AioContext, so make sure we're in the main context. */ 605 615 assert(qemu_get_current_aio_context() == qemu_get_aio_context()); ··· 628 638 { 629 639 BlockDriverState *bs = NULL; 630 640 int drained_end_counter = 0; 641 + 642 + /* 643 + * bdrv queue is managed by record/replay, 644 + * waiting for finishing the I/O requests may 645 + * be endless 646 + */ 647 + if (replay_events_enabled()) { 648 + return; 649 + } 631 650 632 651 while ((bs = bdrv_next_all_states(bs))) { 633 652 AioContext *aio_context = bdrv_get_aio_context(bs); ··· 2123 2142 BdrvNextIterator it; 2124 2143 BlockDriverState *bs = NULL; 2125 2144 int result = 0; 2145 + 2146 + /* 2147 + * bdrv queue is managed by record/replay, 2148 + * creating new flush request for stopping 2149 + * the VM may break the determinism 2150 + */ 2151 + if (replay_events_enabled()) { 2152 + return result; 2153 + } 2126 2154 2127 2155 for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { 2128 2156 AioContext *aio_context = bdrv_get_aio_context(bs);
-2
cpus.c
··· 1097 1097 } 1098 1098 1099 1099 bdrv_drain_all(); 1100 - replay_disable_events(); 1101 1100 ret = bdrv_flush_all(); 1102 1101 1103 1102 return ret; ··· 2181 2180 /* We are sending this now, but the CPUs will be resumed shortly later */ 2182 2181 qapi_event_send_resume(); 2183 2182 2184 - replay_enable_events(); 2185 2183 cpu_enable_ticks(); 2186 2184 runstate_set(RUN_STATE_RUNNING); 2187 2185 vm_state_notify(1, RUN_STATE_RUNNING);