-----BEGIN PGP SIGNATURE-----

Version: GnuPG v1
 
 iQIcBAABAgAGBQJVzfMTAAoJEL2+eyfA3jBXdrcP+gPWb8TuEie92z37UA5S3T+k
 eX6PaGGXIT0k3n7ftsKxli+voHOqQB2L4sSFv742cHzhv2DfvU9yR4AyN7Rmw7aD
 a2yrmzZvPDhXzTkqcpcqVUthNOFBwDd/Swph3NMbVUDp4RCR6ARa00d+/omtI3aD
 BROmnXHNw4OhDHGPpdLEfmgNXKGt8PO5faR+fjZT85hY7Nziqe3pn+zbJwHVteoS
 OIp1FTsyxcPOZf9NF4fnA7HMiguCp2aLa6wzzagZzM6qhj6YLdtAeqR0/1i6Qnf4
 wsmsDLeaaAp4MRfwaNXb4lFXd9w0t+HnffKL4Fw8I3uRgmtkztc3pTlVQWrYkjdE
 4PrIgFSJu/31ds5H74IDa+2PUqjsw2HZx4cc2oJT23rm90x2jzCQluAVnAsctTBO
 TYMms4oi+UztlTQmWOwmhGKU2b3FMNR4Iig417UFMA8LWiL5PGaakUAxTwlcJFjC
 3URuAJNktZyKSjmOtp7jrUKHzai5VXBlWJw45z/UzHzK/WaBJ2T2MFFAkHBdyR+n
 aiILtlIdJRN3m12ypyvJIOlNy7itfyRIsP7LXPYHraR55r7EQEM+gOtTwtA9ZwbJ
 5dtKO7F8jU1DXZlvEj8J68ItuBAq3NUTeoHp+x5EzLJHUzj/uRdqn38U09+Yp7Ly
 Ut2ptxNAUTWW8ji+UPEF
 =tm6s
 -----END PGP SIGNATURE-----

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 <jcody@redhat.com>"
# gpg:                 aka "Jeffrey Cody <jeff@codyprime.org>"
# gpg:                 aka "Jeffrey Cody <codyprime@gmail.com>"
# 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 <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2015-08-14 16:52:34 +01:00
commit 074a9925e1
2 changed files with 15 additions and 5 deletions

View file

@ -60,6 +60,7 @@ typedef struct MirrorBlockJob {
int sectors_in_flight;
int ret;
bool unmap;
bool waiting_for_io;
} MirrorBlockJob;
typedef struct MirrorOp {
@ -114,11 +115,7 @@ static void mirror_iteration_done(MirrorOp *op, int ret)
qemu_iovec_destroy(&op->qiov);
g_slice_free(MirrorOp, op);
/* Enter coroutine when it is not sleeping. The coroutine sleeps to
* rate-limit itself. The coroutine will eventually resume since there is
* a sleep timeout so don't wake it early.
*/
if (s->common.busy) {
if (s->waiting_for_io) {
qemu_coroutine_enter(s->common.co, NULL);
}
}
@ -203,7 +200,9 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
/* Wait for I/O to this cluster (from a previous iteration) to be done. */
while (test_bit(next_chunk, s->in_flight_bitmap)) {
trace_mirror_yield_in_flight(s, sector_num, s->in_flight);
s->waiting_for_io = true;
qemu_coroutine_yield();
s->waiting_for_io = false;
}
do {
@ -239,12 +238,18 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
*/
while (nb_chunks == 0 && s->buf_free_count < added_chunks) {
trace_mirror_yield_buf_busy(s, nb_chunks, s->in_flight);
s->waiting_for_io = true;
qemu_coroutine_yield();
s->waiting_for_io = false;
}
if (s->buf_free_count < nb_chunks + added_chunks) {
trace_mirror_break_buf_busy(s, nb_chunks, s->in_flight);
break;
}
if (IOV_MAX < nb_chunks + added_chunks) {
trace_mirror_break_iov_max(s, nb_chunks, added_chunks);
break;
}
/* We have enough free space to copy these sectors. */
bitmap_set(s->in_flight_bitmap, next_chunk, added_chunks);
@ -333,7 +338,9 @@ static void mirror_free_init(MirrorBlockJob *s)
static void mirror_drain(MirrorBlockJob *s)
{
while (s->in_flight > 0) {
s->waiting_for_io = true;
qemu_coroutine_yield();
s->waiting_for_io = false;
}
}
@ -506,7 +513,9 @@ static void coroutine_fn mirror_run(void *opaque)
if (s->in_flight == MAX_IN_FLIGHT || s->buf_free_count == 0 ||
(cnt == 0 && s->in_flight > 0)) {
trace_mirror_yield(s, s->in_flight, s->buf_free_count, cnt);
s->waiting_for_io = true;
qemu_coroutine_yield();
s->waiting_for_io = false;
continue;
} else if (cnt != 0) {
delay_ns = mirror_iteration(s);

View file

@ -94,6 +94,7 @@ mirror_yield(void *s, int64_t cnt, int buf_free_count, int in_flight) "s %p dirt
mirror_yield_in_flight(void *s, int64_t sector_num, int in_flight) "s %p sector_num %"PRId64" in_flight %d"
mirror_yield_buf_busy(void *s, int nb_chunks, int in_flight) "s %p requested chunks %d in_flight %d"
mirror_break_buf_busy(void *s, int nb_chunks, int in_flight) "s %p requested chunks %d in_flight %d"
mirror_break_iov_max(void *s, int nb_chunks, int added_chunks) "s %p requested chunks %d added_chunks %d"
# block/backup.c
backup_do_cow_enter(void *job, int64_t start, int64_t sector_num, int nb_sectors) "job %p start %"PRId64" sector_num %"PRId64" nb_sectors %d"