76daa3
From 96b7b5da2f485e7e9d76b5528f917d6f7e169a64 Mon Sep 17 00:00:00 2001
76daa3
From: Paolo Bonzini <pbonzini@redhat.com>
76daa3
Date: Wed, 17 May 2017 13:09:16 +0200
76daa3
Subject: [PATCH 10/27] curl: never invoke callbacks with s->mutex held
76daa3
76daa3
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
76daa3
Message-id: <20170517130921.27402-3-pbonzini@redhat.com>
76daa3
Patchwork-id: 75262
76daa3
O-Subject: [RHEL7.4 qemu-kvm PATCH v2 2/7] curl: never invoke callbacks with s->mutex held
76daa3
Bugzilla: 1437393
76daa3
RH-Acked-by: Max Reitz <mreitz@redhat.com>
76daa3
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
76daa3
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
76daa3
76daa3
All curl callbacks go through curl_multi_do, and hence are called with
76daa3
s->mutex held.  Note that with comments, and make curl_read_cb drop the
76daa3
lock before invoking the callback.
76daa3
76daa3
Likewise for curl_find_buf, where the callback can be invoked by the
76daa3
caller.
76daa3
76daa3
Cc: qemu-stable@nongnu.org
76daa3
Reviewed-by: Jeff Cody <jcody@redhat.com>
76daa3
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
76daa3
Reviewed-by: Max Reitz <mreitz@redhat.com>
76daa3
Message-id: 20170515100059.15795-3-pbonzini@redhat.com
76daa3
Signed-off-by: Jeff Cody <jcody@redhat.com>
76daa3
(cherry picked from commit 34db05e7ffe8d61ca7288b9532ad6e8300853318)
76daa3
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
76daa3
---
76daa3
 block/curl.c | 12 ++++++++----
76daa3
 1 file changed, 8 insertions(+), 4 deletions(-)
76daa3
76daa3
diff --git a/block/curl.c b/block/curl.c
76daa3
index e77a64b..94a1e16 100644
76daa3
--- a/block/curl.c
76daa3
+++ b/block/curl.c
76daa3
@@ -147,6 +147,7 @@ static void curl_multi_do(void *arg);
76daa3
 static void curl_multi_read(void *arg);
76daa3
 
76daa3
 #ifdef NEED_CURL_TIMER_CALLBACK
76daa3
+/* Called from curl_multi_do_locked, with s->mutex held.  */
76daa3
 static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
76daa3
 {
76daa3
     BDRVCURLState *s = opaque;
76daa3
@@ -163,6 +164,7 @@ static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
76daa3
 }
76daa3
 #endif
76daa3
 
76daa3
+/* Called from curl_multi_do_locked, with s->mutex held.  */
76daa3
 static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
76daa3
                         void *userp, void *sp)
76daa3
 {
76daa3
@@ -212,6 +214,7 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
76daa3
     return 0;
76daa3
 }
76daa3
 
76daa3
+/* Called from curl_multi_do_locked, with s->mutex held.  */
76daa3
 static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
76daa3
 {
76daa3
     BDRVCURLState *s = opaque;
76daa3
@@ -226,6 +229,7 @@ static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
76daa3
     return realsize;
76daa3
 }
76daa3
 
76daa3
+/* Called from curl_multi_do_locked, with s->mutex held.  */
76daa3
 static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
76daa3
 {
76daa3
     CURLState *s = ((CURLState*)opaque);
76daa3
@@ -264,7 +268,9 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
76daa3
                                   request_length - offset);
76daa3
             }
76daa3
 
76daa3
+            qemu_mutex_unlock(&s->s->mutex);
76daa3
             acb->common.cb(acb->common.opaque, 0);
76daa3
+            qemu_mutex_lock(&s->s->mutex);
76daa3
             qemu_aio_unref(acb);
76daa3
             s->acb[i] = NULL;
76daa3
         }
76daa3
@@ -305,8 +311,6 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
76daa3
             if (clamped_len < len) {
76daa3
                 qemu_iovec_memset(acb->qiov, clamped_len, 0, len - clamped_len);
76daa3
             }
76daa3
-            acb->common.cb(acb->common.opaque, 0);
76daa3
-
76daa3
             return FIND_RET_OK;
76daa3
         }
76daa3
 
76daa3
@@ -832,8 +836,8 @@ static void curl_readv_bh_cb(void *p)
76daa3
     // we can just call the callback and be done.
76daa3
     switch (curl_find_buf(s, start, acb->nb_sectors * BDRV_SECTOR_SIZE, acb)) {
76daa3
         case FIND_RET_OK:
76daa3
-            qemu_aio_unref(acb);
76daa3
-            // fall through
76daa3
+            ret = 0;
76daa3
+            goto out;
76daa3
         case FIND_RET_WAIT:
76daa3
             goto out;
76daa3
         default:
76daa3
-- 
76daa3
1.8.3.1
76daa3