@@ -3491,7 +3491,7 @@ static void virtio_queue_host_notifier_aio_poll_end(EventNotifier *n)
void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx)
{
- aio_set_event_notifier(ctx, &vq->host_notifier, true,
+ aio_set_event_notifier(ctx, &vq->host_notifier, false,
virtio_queue_host_notifier_read,
virtio_queue_host_notifier_aio_poll,
virtio_queue_host_notifier_aio_poll_ready);
@@ -3508,14 +3508,14 @@ void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx)
*/
void virtio_queue_aio_attach_host_notifier_no_poll(VirtQueue *vq, AioContext *ctx)
{
- aio_set_event_notifier(ctx, &vq->host_notifier, true,
+ aio_set_event_notifier(ctx, &vq->host_notifier, false,
virtio_queue_host_notifier_read,
NULL, NULL);
}
void virtio_queue_aio_detach_host_notifier(VirtQueue *vq, AioContext *ctx)
{
- aio_set_event_notifier(ctx, &vq->host_notifier, true, NULL, NULL, NULL);
+ aio_set_event_notifier(ctx, &vq->host_notifier, false, NULL, NULL, NULL);
/* Test and clear notifier before after disabling event,
* in case poll callback didn't have time to run. */
virtio_queue_host_notifier_read(&vq->host_notifier);
Host notifiers trigger virtqueue processing. There are critical sections when new I/O requests must not be submitted because they would cause interference. In the past this was solved using aio_set_event_notifiers() is_external=true argument, which disables fd monitoring between aio_disable/enable_external() calls. This API is not multi-queue block layer friendly because it requires knowledge of the specific AioContext. In a multi-queue block layer world any thread can submit I/O and we don't know which AioContexts are currently involved. virtio-blk and virtio-scsi are the only users that depend on is_external=true. Both rely on the block layer, where we can take advantage of the existing request queuing behavior that happens during drained sections. The block layer's drained sections are the only user of aio_disable_external(). After this patch the virtqueues will be processed during drained section, but submitted I/O requests will be queued in the BlockBackend. Queued requests are resumed when the drained section ends. Therefore, the BlockBackend is still quiesced during drained sections but we no longer rely on is_external=true to achieve this. Note that virtqueues have a finite size, so queuing requests does not lead to unbounded memory usage. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> --- hw/virtio/virtio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)