[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [RFC 3/6] block: wait for overlapping requests
From: |
Marcelo Tosatti |
Subject: |
Re: [Qemu-devel] [RFC 3/6] block: wait for overlapping requests |
Date: |
Tue, 18 Oct 2011 11:48:23 -0200 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
On Mon, Oct 17, 2011 at 04:47:29PM +0100, Stefan Hajnoczi wrote:
> When copy-on-read is enabled it is necessary to wait for overlapping
> requests before issuing new requests. This prevents races between the
> copy-on-read and a write request.
>
> Signed-off-by: Stefan Hajnoczi <address@hidden>
> ---
> block.c | 39 +++++++++++++++++++++++++++++++++++++++
> 1 files changed, 39 insertions(+), 0 deletions(-)
>
> diff --git a/block.c b/block.c
> index e624ac3..cc3202c 100644
> --- a/block.c
> +++ b/block.c
> @@ -1001,6 +1001,7 @@ struct BdrvTrackedRequest {
> int nb_sectors;
> bool is_write;
> QLIST_ENTRY(BdrvTrackedRequest) list;
> + CoQueue wait_queue; /* coroutines blocked on this request */
> };
>
> /**
> @@ -1014,6 +1015,12 @@ static void tracked_request_remove(BdrvTrackedRequest
> *req)
> {
> if (req) {
> QLIST_REMOVE(req, list);
> +
> + /* Wake up all coroutines blocked on this request */
> + while (qemu_co_queue_next(&req->wait_queue)) {
> + /* Do nothing */
> + }
> +
> g_free(req);
> }
> }
> @@ -1038,12 +1045,36 @@ static BdrvTrackedRequest
> *tracked_request_add(BlockDriverState *bs,
> req->sector_num = sector_num;
> req->nb_sectors = nb_sectors;
> req->is_write = is_write;
> + qemu_co_queue_init(&req->wait_queue);
>
> QLIST_INSERT_HEAD(&bs->tracked_requests, req, list);
>
> return req;
> }
>
> +static bool tracked_request_overlaps(BdrvTrackedRequest *req,
> + int64_t sector_num, int nb_sectors) {
> + return false; /* not yet implemented */
> +}
> +
> +static void coroutine_fn wait_for_overlapping_requests(BlockDriverState *bs,
> + int64_t sector_num, int nb_sectors)
> +{
> + BdrvTrackedRequest *req;
> + bool retry;
> +
> + do {
> + retry = false;
> + QLIST_FOREACH(req, &bs->tracked_requests, list) {
> + if (tracked_request_overlaps(req, sector_num, nb_sectors)) {
> + qemu_co_queue_wait(&req->wait_queue);
> + retry = true;
What prevents overlapping requests (from waiter criteria) to be inserted
to the queue while there are waiters again?
That is, why is it not possible for a waiter to wait indefinetely?
- [Qemu-devel] [RFC 0/6] block: generic copy-on-read, Stefan Hajnoczi, 2011/10/17
- [Qemu-devel] [RFC 5/6] block: core copy-on-read logic, Stefan Hajnoczi, 2011/10/17
- [Qemu-devel] [RFC 3/6] block: wait for overlapping requests, Stefan Hajnoczi, 2011/10/17
- Re: [Qemu-devel] [RFC 3/6] block: wait for overlapping requests,
Marcelo Tosatti <=
- [Qemu-devel] [RFC 1/6] block: add request tracking, Stefan Hajnoczi, 2011/10/17
- [Qemu-devel] [RFC 2/6] block: add bdrv_set_copy_on_read(), Stefan Hajnoczi, 2011/10/17
- [Qemu-devel] [RFC 6/6] block: add -drive copy-on-read=on|off, Stefan Hajnoczi, 2011/10/17
- [Qemu-devel] [RFC 4/6] block: request overlap detection, Stefan Hajnoczi, 2011/10/17