[pve-devel] Fwd: [Qemu-stable] [PATCH] stream: fix the deadlock bug when stream finish

Stefan Priebe - Profihost AG s.priebe at profihost.ag
Sat Aug 23 06:56:54 CEST 2014


Might this be related to the qemu hang you see when saving vm memory?

Stefan

Excuse my typo sent from my mobile phone.

Anfang der weitergeleiteten E‑Mail:

> Von: Liu Yu <allanliuyu at gmail.com>
> Datum: 23. August 2014 05:43:00 MESZ
> An: qemu-stable at nongnu.org
> Betreff: [Qemu-stable] [PATCH] stream: fix the deadlock bug when stream finish
> 
> From: Liu Yu <allanyuliu at tencent.com>
> 
> The patch against branch stable-2.0
> 
> In case VM does IO while we run a stream job.
> When stream finishes, the stream coroutine drains all IOs before
> close the unused image, in bdrv_drain_all() it may find
> a pending request which is submitted by guest IO coroutine.
> In order to wait the pending req finish, the subsequent aio_poll()
> call poll() to wait the req. however, if the req is already done by
> threadpool and is waiting for the callback, there is no chance to switch
> back to guest IO coroutine to call the callback and so that the stream
> coroutine waits in poll() all the time.
> 
> The patch detects the deadlock case above and switch back to iothread
> coroutine to handle the callback, and work on the stream coroutine
> after the pending req get finished.
> 
> Signed-off-by: Liu Yu <allanyuliu at tencent.com>
> ---
> the issue can be reproduced by
> 1. guest does fio test
> 2. while host runs virsh blockpull repeatedly
> 
> 
> block.c |   27 ++++++++++++++++++++++++++-
> 1 files changed, 26 insertions(+), 1 deletions(-)
> 
> diff --git a/block.c b/block.c
> index 990a754..f8c1a8d 100644
> --- a/block.c
> +++ b/block.c
> @@ -1778,6 +1778,29 @@ static bool bdrv_requests_pending_all(void)
>     return false;
> }
> 
> +static bool bdrv_request_coroutine_wait(void)
> +{
> +    BlockDriverState *bs;
> +    Coroutine *co;
> +
> +    if (!qemu_in_coroutine())
> +        return false;
> +
> +    co = qemu_coroutine_self();
> +    QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
> +        if (!QLIST_EMPTY(&bs->tracked_requests)) {
> +            BdrvTrackedRequest *req = QLIST_FIRST(&bs->tracked_requests);
> +
> +            if(req->co == co)
> +                continue;
> +
> +            qemu_co_queue_wait(&req->wait_queue);
> +            return true;
> +        }
> +    }
> +    return false;
> +}
> +
> /*
>  * Wait for pending requests to complete across all BlockDriverStates
>  *
> @@ -1800,8 +1823,10 @@ void bdrv_drain_all(void)
>         QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
>             bdrv_start_throttled_reqs(bs);
>         }
> -
> +recheck:
>         busy = bdrv_requests_pending_all();
> +        if (busy && bdrv_request_coroutine_wait())
> +            goto recheck;
>         busy |= aio_poll(qemu_get_aio_context(), busy);
>     }
> }
> -- 
> 1.7.1
> 
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://pve.proxmox.com/pipermail/pve-devel/attachments/20140823/471533ce/attachment.html>


More information about the pve-devel mailing list