All of lore.kernel.org
 help / color / mirror / Atom feed
From: Evgeny Yakovlev <wrfsh@yandex-team.ru>
To: qemu-devel@nongnu.org, jcody@redhat.com
Cc: asmetanin@yandex-team.ru, Evgeny Yakovlev <wrfsh@yandex-team.ru>
Subject: [Qemu-devel] [PATCH] block/curl: wake read completion coroutine only if necessary
Date: Fri, 25 Aug 2017 18:52:26 +0300	[thread overview]
Message-ID: <1503676346-3762-1-git-send-email-wrfsh@yandex-team.ru> (raw)

When curl_co_preadv is called it sets up an ACB block which points to
current coroutine. It will then call curl_setup_preadv and wait until
request is completed by polling return status and yeilding:

    curl_setup_preadv(bs, &acb);
    while (acb.ret == -EINPROGRESS) {
        qemu_coroutine_yield();
    }

curl_setup_preadv will ask libcurl to handle read request and to use
curl_read_cb as completion callback for each completed chunk.

When curl_read_cb sees request as completed it will attempt to wake up
issuing coroutine assuming that yield was called previously:

    qemu_mutex_unlock(&s->s->mutex);
    aio_co_wake(acb->co);
    qemu_mutex_lock(&s->s->mutex);

However if request is short enough (< 16K in our test) curl_read_cb will
be called right away before returning from libcurl to curl_setup_preadv.
Request will be completed before yield was called from the same
coroutine, which asserts in aio_co_enter.

This change attempts to fix this by waking completion coroutine only if
it is not the current one.

Signed-off-by: Evgeny Yakovlev <wrfsh@yandex-team.ru>
---
 block/curl.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/block/curl.c b/block/curl.c
index 2a244e2..b1106d6 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -271,9 +271,12 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
 
             acb->ret = 0;
             s->acb[i] = NULL;
-            qemu_mutex_unlock(&s->s->mutex);
-            aio_co_wake(acb->co);
-            qemu_mutex_lock(&s->s->mutex);
+
+            if (qemu_coroutine_self() != acb->co) {
+                qemu_mutex_unlock(&s->s->mutex);
+                aio_co_wake(acb->co);
+                qemu_mutex_lock(&s->s->mutex);
+            }
         }
     }
 
-- 
2.7.4

                 reply	other threads:[~2017-08-25 15:52 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1503676346-3762-1-git-send-email-wrfsh@yandex-team.ru \
    --to=wrfsh@yandex-team.ru \
    --cc=asmetanin@yandex-team.ru \
    --cc=jcody@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.