Browse Source

Merge tag 'for-upstream' of https://repo.or.cz/qemu/kevin into staging

Block layer patches

- aio-posix: Fix race during epoll upgrade
- vhost-user-blk/VDUSE export: Fix a potential deadlock and an assertion
  failure when the export runs in an iothread
- NBD server: Push pending frames after sending reply to fix performance
  especially when used with TLS

# -----BEGIN PGP SIGNATURE-----
#
# iQJFBAABCAAvFiEE3D3rFZqa+V09dFb+fwmycsiPL9YFAmQi3s4RHGt3b2xmQHJl
# ZGhhdC5jb20ACgkQfwmycsiPL9Yz7hAAq9UVPOfr8SF5WjxuZBNifYI13uazp9cG
# UdDC4Be2zNSkw9WGb+thHHjvqyQ49tAmT70bTocNk8VEAjAJ5J4VrCOlyz7pcy2w
# PdJf1RxaUSEV4Fl5lThrUeOv5sX3hSm/Z8X9WLYLjYxOGJOpITkQ0eM7PDwwsiPd
# hXLOAWabcJbx/m2HQphUG5ZoC2omgfY2ICrlr4Bvziak63cT+ZTVfKTvVebtEZ9B
# zn+BfrzDra/rkLJEM9JfgQXjYo3Cxrv5MjYzDpeRCHPwnseZnlbHlE3nrHWYDuLW
# fsd6RpsoOW6mHEx4aO6xLAVu+iIfouVOjV5ZWRvcKw5UyiejW/DkduppERMbWx/y
# Wfq95O/4UjFop3fw+UGGdHtASjnUJM35QR9wo+bM2vS219DLTJ/7mKOhBDajHQy4
# 3ynk39uEnkRyLrKUMvR9qZ7t7pvumXEEA5qtPGJwnvOXm9shlKrJ8f3TzUGBKpQS
# KPYEAJPO/HmyvswsfTmC7Yy5uh2o67nsMdDy7HEq0MZW5+pBpAML+zv4qyQKtDsg
# GzoIL+zd09Yyh+wK9+NPzX9p7DZus7NRlig9byGCpD48gqzeABL6CQotNlm93pgj
# eybiMStrCPIOt8AZM5j8yxh1RBiM2L7sZeTBaFXyQiwrlYOW4xGybivzcwQAEFGN
# iKRB0fttcQE=
# =+vQj
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 28 Mar 2023 13:34:22 BST
# gpg:                using RSA key DC3DEB159A9AF95D3D7456FE7F09B272C88F2FD6
# gpg:                issuer "kwolf@redhat.com"
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full]
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* tag 'for-upstream' of https://repo.or.cz/qemu/kevin:
  block/export: Fix graph locking in blk_get_geometry() call
  aio-posix: fix race between epoll upgrade and aio_set_fd_handler()
  block/export: only acquire AioContext once for vhost_user_server_stop()
  nbd/server: push pending frames after sending reply

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Peter Maydell 2 năm trước cách đây
mục cha
commit
3b555b5115

+ 3 - 2
block.c

@@ -5879,9 +5879,10 @@ int64_t coroutine_fn bdrv_co_getlength(BlockDriverState *bs)
 }
 
 /* return 0 as number of sectors if no device present or error */
-void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
+void coroutine_fn bdrv_co_get_geometry(BlockDriverState *bs,
+                                       uint64_t *nb_sectors_ptr)
 {
-    int64_t nb_sectors = bdrv_nb_sectors(bs);
+    int64_t nb_sectors = bdrv_co_nb_sectors(bs);
     IO_CODE();
 
     *nb_sectors_ptr = nb_sectors < 0 ? 0 : nb_sectors;

+ 5 - 2
block/block-backend.c

@@ -1615,13 +1615,16 @@ int64_t coroutine_fn blk_co_getlength(BlockBackend *blk)
     return bdrv_co_getlength(blk_bs(blk));
 }
 
-void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr)
+void coroutine_fn blk_co_get_geometry(BlockBackend *blk,
+                                      uint64_t *nb_sectors_ptr)
 {
     IO_CODE();
+    GRAPH_RDLOCK_GUARD();
+
     if (!blk_bs(blk)) {
         *nb_sectors_ptr = 0;
     } else {
-        bdrv_get_geometry(blk_bs(blk), nb_sectors_ptr);
+        bdrv_co_get_geometry(blk_bs(blk), nb_sectors_ptr);
     }
 }
 

+ 4 - 3
block/export/virtio-blk-handler.c

@@ -22,8 +22,9 @@ struct virtio_blk_inhdr {
     unsigned char status;
 };
 
-static bool virtio_blk_sect_range_ok(BlockBackend *blk, uint32_t block_size,
-                                     uint64_t sector, size_t size)
+static bool coroutine_fn
+virtio_blk_sect_range_ok(BlockBackend *blk, uint32_t block_size,
+                         uint64_t sector, size_t size)
 {
     uint64_t nb_sectors;
     uint64_t total_sectors;
@@ -41,7 +42,7 @@ static bool virtio_blk_sect_range_ok(BlockBackend *blk, uint32_t block_size,
     if ((sector << VIRTIO_BLK_SECTOR_BITS) % block_size) {
         return false;
     }
-    blk_get_geometry(blk, &total_sectors);
+    blk_co_get_geometry(blk, &total_sectors);
     if (sector > total_sectors || nb_sectors > total_sectors - sector) {
         return false;
     }

+ 3 - 1
include/block/block-io.h

@@ -89,7 +89,9 @@ int64_t co_wrapper bdrv_get_allocated_file_size(BlockDriverState *bs);
 
 BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
                                BlockDriverState *in_bs, Error **errp);
-void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
+
+void coroutine_fn GRAPH_RDLOCK
+bdrv_co_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
 
 int coroutine_fn GRAPH_RDLOCK
 bdrv_co_delete_file(BlockDriverState *bs, Error **errp);

+ 4 - 1
include/sysemu/block-backend-io.h

@@ -70,7 +70,10 @@ void co_wrapper blk_eject(BlockBackend *blk, bool eject_flag);
 int64_t coroutine_fn blk_co_getlength(BlockBackend *blk);
 int64_t co_wrapper_mixed blk_getlength(BlockBackend *blk);
 
-void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr);
+void coroutine_fn blk_co_get_geometry(BlockBackend *blk,
+                                      uint64_t *nb_sectors_ptr);
+void co_wrapper_mixed blk_get_geometry(BlockBackend *blk,
+                                       uint64_t *nb_sectors_ptr);
 
 int64_t coroutine_fn blk_co_nb_sectors(BlockBackend *blk);
 int64_t co_wrapper_mixed blk_nb_sectors(BlockBackend *blk);

+ 3 - 0
nbd/server.c

@@ -2667,6 +2667,8 @@ static coroutine_fn void nbd_trip(void *opaque)
         goto disconnect;
     }
 
+    qio_channel_set_cork(client->ioc, true);
+
     if (ret < 0) {
         /* It wasn't -EIO, so, according to nbd_co_receive_request()
          * semantics, we should return the error to the client. */
@@ -2692,6 +2694,7 @@ static coroutine_fn void nbd_trip(void *opaque)
         goto disconnect;
     }
 
+    qio_channel_set_cork(client->ioc, false);
 done:
     nbd_request_put(req);
     nbd_client_put(client);

+ 18 - 7
util/fdmon-epoll.c

@@ -127,6 +127,8 @@ static bool fdmon_epoll_try_enable(AioContext *ctx)
 
 bool fdmon_epoll_try_upgrade(AioContext *ctx, unsigned npfd)
 {
+    bool ok;
+
     if (ctx->epollfd < 0) {
         return false;
     }
@@ -136,14 +138,23 @@ bool fdmon_epoll_try_upgrade(AioContext *ctx, unsigned npfd)
         return false;
     }
 
-    if (npfd >= EPOLL_ENABLE_THRESHOLD) {
-        if (fdmon_epoll_try_enable(ctx)) {
-            return true;
-        } else {
-            fdmon_epoll_disable(ctx);
-        }
+    if (npfd < EPOLL_ENABLE_THRESHOLD) {
+        return false;
+    }
+
+    /* The list must not change while we add fds to epoll */
+    if (!qemu_lockcnt_dec_if_lock(&ctx->list_lock)) {
+        return false;
+    }
+
+    ok = fdmon_epoll_try_enable(ctx);
+
+    qemu_lockcnt_inc_and_unlock(&ctx->list_lock);
+
+    if (!ok) {
+        fdmon_epoll_disable(ctx);
     }
-    return false;
+    return ok;
 }
 
 void fdmon_epoll_setup(AioContext *ctx)

+ 1 - 4
util/vhost-user-server.c

@@ -346,10 +346,9 @@ static void vu_accept(QIONetListener *listener, QIOChannelSocket *sioc,
     aio_context_release(server->ctx);
 }
 
+/* server->ctx acquired by caller */
 void vhost_user_server_stop(VuServer *server)
 {
-    aio_context_acquire(server->ctx);
-
     qemu_bh_delete(server->restart_listener_bh);
     server->restart_listener_bh = NULL;
 
@@ -366,8 +365,6 @@ void vhost_user_server_stop(VuServer *server)
         AIO_WAIT_WHILE(server->ctx, server->co_trip);
     }
 
-    aio_context_release(server->ctx);
-
     if (server->listener) {
         qio_net_listener_disconnect(server->listener);
         object_unref(OBJECT(server->listener));