[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: |
Stefan Hajnoczi |
Subject: |
Re: [Qemu-devel] [RFC 3/6] block: wait for overlapping requests |
Date: |
Thu, 20 Oct 2011 10:34:04 -0700 |
On Tue, Oct 18, 2011 at 6:48 AM, Marcelo Tosatti <address@hidden> wrote:
> 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?
CoQueue is FIFO so overlapping requests are processed in order and
will not wait indefinitely.
Stefan
- [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
- [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