Am 23.10.2020 um 17:01 hat Greg Kurz geschrieben: > If a BDS gets deleted during blk_drain_all(), it might miss a > call to bdrv_do_drained_end(). This means missing a call to > aio_enable_external() and the AIO context remains disabled for > ever. This can cause a device to become irresponsive and to > disrupt the guest execution, ie. hang, loop forever or worse. > > This scenario is quite easy to encounter with virtio-scsi > on POWER when punching multiple blockdev-create QMP commands > while the guest is booting and it is still running the SLOF > firmware. This happens because SLOF disables/re-enables PCI > devices multiple times via IO/MEM/MASTER bits of PCI_COMMAND > register after the initial probe/feature negotiation, as it > tends to work with a single device at a time at various stages > like probing and running block/network bootloaders without > doing a full reset in-between. This naturally generates many > dataplane stops and starts, and thus many drain sections that > can race with blockdev_create_run(). In the end, SLOF bails > out. > > It is somehow reproducible on x86 but it requires to generate > articial dataplane start/stop activity with stop/cont QMP > commands. In this case, seabios ends up looping for ever, > waiting for the virtio-scsi device to send a response to > a command it never received. > > Add a helper that pairs all previously called bdrv_do_drained_begin() > with a bdrv_do_drained_end() and call it from bdrv_close(). > While at it, update the "/bdrv-drain/graph-change/drain_all" > test in test-bdrv-drain so that it can catch the issue. > > BugId: https://bugzilla.redhat.com/show_bug.cgi?id=1874441 > Signed-off-by: Greg Kurz <gr...@kaod.org>
Thanks, applied to the block branch. Kevin