qemu-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-commits] [qemu/qemu] cae98c: block/mirror: limit qiov to IOV_MAX e


From: GitHub
Subject: [Qemu-commits] [qemu/qemu] cae98c: block/mirror: limit qiov to IOV_MAX elements
Date: Fri, 14 Aug 2015 10:30:04 -0700

  Branch: refs/heads/master
  Home:   https://github.com/qemu/qemu
  Commit: cae98cb87d269c33d23b2bccd79bb8d99a60d811
      
https://github.com/qemu/qemu/commit/cae98cb87d269c33d23b2bccd79bb8d99a60d811
  Author: Stefan Hajnoczi <address@hidden>
  Date:   2015-08-06 (Thu, 06 Aug 2015)

  Changed paths:
    M block/mirror.c
    M trace-events

  Log Message:
  -----------
  block/mirror: limit qiov to IOV_MAX elements

If mirror has more free buffers than IOV_MAX, preadv(2)/pwritev(2)
EINVAL failures may be encountered.

It is possible to trigger this by setting granularity to a low value
like 8192.

This patch stops appending chunks once IOV_MAX is reached.

The spurious EINVAL failure can be reproduced with a qcow2 image file
and the following QMP invocation:

  qmp.command('drive-mirror', device='virtio0', target='/tmp/r7.s1',
        granularity=8192, sync='full', mode='absolute-paths',
        format='raw')

While the guest is running dd if=/dev/zero of=/var/tmp/foo oflag=direct
bs=4k.

Cc: Jeff Cody <address@hidden>
Signed-off-by: Stefan Hajnoczi <address@hidden>
Reviewed-by: Paolo Bonzini <address@hidden>
Message-id: address@hidden
Signed-off-by: Jeff Cody <address@hidden>


  Commit: d90dedfcd5b9faad105bf28b718c9477d8467e77
      
https://github.com/qemu/qemu/commit/d90dedfcd5b9faad105bf28b718c9477d8467e77
  Author: Jeff Cody <address@hidden>
  Date:   2015-08-14 (Fri, 14 Aug 2015)

  Changed paths:
    M block/mirror.c
    M trace-events

  Log Message:
  -----------
  Merge branch 'block-next' into HEAD


  Commit: e424aff5f307227b1c2512bbb8ece891bb895cef
      
https://github.com/qemu/qemu/commit/e424aff5f307227b1c2512bbb8ece891bb895cef
  Author: Kevin Wolf <address@hidden>
  Date:   2015-08-14 (Fri, 14 Aug 2015)

  Changed paths:
    M block/mirror.c

  Log Message:
  -----------
  mirror: Fix coroutine reentrance

This fixes a regression introduced by commit dcfb3beb ("mirror: Do zero
write on target if sectors not allocated"), which was reported to cause
aborts with the message "Co-routine re-entered recursively".

The cause for this bug is the following code in mirror_iteration_done():

    if (s->common.busy) {
  qemu_coroutine_enter(s->common.co, NULL);
    }

This has always been ugly because - unlike most places that reenter - it
doesn't have a specific yield that it pairs with, but is more
uncontrolled.  What we really mean here is "reenter the coroutine if
it's in one of the four explicit yields in mirror.c".

This used to be equivalent with s->common.busy because neither
mirror_run() nor mirror_iteration() call any function that could yield.
However since commit dcfb3beb this doesn't hold true any more:
bdrv_get_block_status_above() can yield.

So what happens is that bdrv_get_block_status_above() wants to take a
lock that is already held, so it adds itself to the queue of waiting
coroutines and yields. Instead of being woken up by the unlock function,
however, it gets woken up by mirror_iteration_done(), which is obviously
wrong.

In most cases the code actually happens to cope fairly well with such
cases, but in this specific case, the unlock must already have scheduled
the coroutine for wakeup when mirror_iteration_done() reentered it. And
then the coroutine happened to process the scheduled restarts and tried
to reenter itself recursively.

This patch fixes the problem by pairing the reenter in
mirror_iteration_done() with specific yields instead of abusing
s->common.busy.

Cc: address@hidden
Signed-off-by: Kevin Wolf <address@hidden>
Reviewed-by: Paolo Bonzini <address@hidden>
Reviewed-by: Stefan Hajnoczi <address@hidden>
Reviewed-by: Jeff Cody <address@hidden>
Message-id: address@hidden
Signed-off-by: Jeff Cody <address@hidden>


  Commit: 074a9925e1cfd659d5376dcaccd1436d3840e611
      
https://github.com/qemu/qemu/commit/074a9925e1cfd659d5376dcaccd1436d3840e611
  Author: Peter Maydell <address@hidden>
  Date:   2015-08-14 (Fri, 14 Aug 2015)

  Changed paths:
    M block/mirror.c
    M trace-events

  Log Message:
  -----------
  Merge remote-tracking branch 'remotes/cody/tags/block-pull-request' into 
staging

# gpg: Signature made Fri 14 Aug 2015 14:54:27 BST using RSA key ID C0DE3057
# gpg: Good signature from "Jeffrey Cody <address@hidden>"
# gpg:                 aka "Jeffrey Cody <address@hidden>"
# gpg:                 aka "Jeffrey Cody <address@hidden>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 9957 4B4D 3474 90E7 9D98  D624 BDBE 7B27 C0DE 3057

* remotes/cody/tags/block-pull-request:
  mirror: Fix coroutine reentrance
  block/mirror: limit qiov to IOV_MAX elements

Signed-off-by: Peter Maydell <address@hidden>


Compare: https://github.com/qemu/qemu/compare/8e0adf64140a...074a9925e1cf

reply via email to

[Prev in Thread] Current Thread [Next in Thread]