diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2024-02-08 20:08:44 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2024-02-08 20:08:44 +0000 |
commit | e2beaf7bad96c7e458f08eee033351e6b83032b2 (patch) | |
tree | 385c0e5f2f29ef9f3223f1043a3f9313d481ce48 /hw/scsi | |
parent | 03e4bc0bc02779fdf6f8e8d83197f05e70881abf (diff) | |
parent | bfa36802d1704fc413c590ebdcc4e5ae0eacf439 (diff) | |
download | qemu-e2beaf7bad96c7e458f08eee033351e6b83032b2.zip qemu-e2beaf7bad96c7e458f08eee033351e6b83032b2.tar.gz qemu-e2beaf7bad96c7e458f08eee033351e6b83032b2.tar.bz2 |
Merge tag 'for-upstream' of https://repo.or.cz/qemu/kevin into staging
Block layer patches
- Allow concurrent BB context changes
- virtio: Re-enable notifications after drain
- virtio-blk: Fix missing use of irqfd
- scsi: Don't ignore most usb-storage properties
- blkio: Respect memory-alignment for bounce buffer allocations
- iotests tmpdir fixes
- virtio-blk: Code cleanups
# -----BEGIN PGP SIGNATURE-----
#
# iQJFBAABCAAvFiEE3D3rFZqa+V09dFb+fwmycsiPL9YFAmXEkwgRHGt3b2xmQHJl
# ZGhhdC5jb20ACgkQfwmycsiPL9Y3jA//TmSBVqHljauyImYOgCt8qCXACttV0xhQ
# Q5ldUNx/JmIFMoUR7OlpVAL2MtvdwE0jjY+sDlEmWtz4IFJcCsCTUCHZZb8blreb
# +mnMkqrQ6Nb3tPR2jeIknrXqNy1ffyjZItktjWXVcl6jaHB8YabHHqszs9DIaf4n
# lcKovBKxula8ckMgvm48wCwTtS7VEPeuC5FrOqUqTtuhg+QKp5ZVoyVFHtf6GKTD
# iuXzCd4yxu4fDKAthJJj4N1bQaOmCKU7K9N/665wj9P2TyfmwlBAfNwNAlYbdX1E
# Sv7eSioQs2+oUxmfD/PUsF7wTYtDCrSAUFn1kP/XdRyXPJR3dHGiBKV9w9CaWNrU
# y8rqOhxVcuoBLRljTF32BK4HniAREjRngtpT2FnQQIyedZrXIwyTAWjs+LW12T6O
# NMiU603Nl9ZYhO1et2+qspsVpNIfEpQWpK+OCon6E+ggj1ea+pfqU30VPx4JU05I
# VLiydluIbehSkRlTHgFcTgApmx843OGW7CvWfRyen86Cexgx3DEjJUQ4/bYqaCha
# yLIi91rToSDmtlzJrg9eYiMs5Y6vz+ORvvX5im1RlbUUb7Kx/LaA4BU/uArEbBt8
# xXm/grO4hFUGqtLgd2LIjWaHSsLoW4jKeEiExFUUfvH5DG9Zl5HmzFwu+DYxX+im
# MJLLetDJAWI=
# =8tc0
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 08 Feb 2024 08:38:32 GMT
# 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:
virtio-blk: avoid using ioeventfd state in irqfd conditional
virtio-blk: Use ioeventfd_attach in start_ioeventfd
virtio: Re-enable notifications after drain
virtio-scsi: Attach event vq notifier with no_poll
blkio: Respect memory-alignment for bounce buffer allocations
scsi: Don't ignore most usb-storage properties
virtio-blk: do not use C99 mixed declarations
iotests: give tempdir an identifying name
iotests: fix leak of tmpdir in dry-run mode
scsi: Await request purging
block-backend: Allow concurrent context changes
monitor: use aio_co_reschedule_self()
virtio-blk: declare VirtIOBlock::rq with a type
virtio-blk: add vq_rq[] bounds check in virtio_blk_dma_restart_cb()
virtio-blk: clarify that there is at least 1 virtqueue
virtio-blk: enforce iothread-vq-mapping validation
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/scsi')
-rw-r--r-- | hw/scsi/scsi-bus.c | 63 | ||||
-rw-r--r-- | hw/scsi/virtio-scsi.c | 7 |
2 files changed, 40 insertions, 30 deletions
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index 0a2eb11..9e40b0c 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -120,17 +120,13 @@ static void scsi_device_for_each_req_async_bh(void *opaque) SCSIRequest *next; /* - * If the AioContext changed before this BH was called then reschedule into - * the new AioContext before accessing ->requests. This can happen when - * scsi_device_for_each_req_async() is called and then the AioContext is - * changed before BHs are run. + * The BB cannot have changed contexts between this BH being scheduled and + * now: BBs' AioContexts, when they have a node attached, can only be + * changed via bdrv_try_change_aio_context(), in a drained section. While + * we have the in-flight counter incremented, that drain must block. */ ctx = blk_get_aio_context(s->conf.blk); - if (ctx != qemu_get_current_aio_context()) { - aio_bh_schedule_oneshot(ctx, scsi_device_for_each_req_async_bh, - g_steal_pointer(&data)); - return; - } + assert(ctx == qemu_get_current_aio_context()); QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) { data->fn(req, data->fn_opaque); @@ -138,11 +134,16 @@ static void scsi_device_for_each_req_async_bh(void *opaque) /* Drop the reference taken by scsi_device_for_each_req_async() */ object_unref(OBJECT(s)); + + /* Paired with blk_inc_in_flight() in scsi_device_for_each_req_async() */ + blk_dec_in_flight(s->conf.blk); } /* * Schedule @fn() to be invoked for each enqueued request in device @s. @fn() * runs in the AioContext that is executing the request. + * Keeps the BlockBackend's in-flight counter incremented until everything is + * done, so draining it will settle all scheduled @fn() calls. */ static void scsi_device_for_each_req_async(SCSIDevice *s, void (*fn)(SCSIRequest *, void *), @@ -163,6 +164,8 @@ static void scsi_device_for_each_req_async(SCSIDevice *s, */ object_ref(OBJECT(s)); + /* Paired with blk_dec_in_flight() in scsi_device_for_each_req_async_bh() */ + blk_inc_in_flight(s->conf.blk); aio_bh_schedule_oneshot(blk_get_aio_context(s->conf.blk), scsi_device_for_each_req_async_bh, data); @@ -373,15 +376,13 @@ static void scsi_qdev_unrealize(DeviceState *qdev) /* handle legacy '-drive if=scsi,...' cmd line args */ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk, - int unit, bool removable, int bootindex, - bool share_rw, - BlockdevOnError rerror, - BlockdevOnError werror, + int unit, bool removable, BlockConf *conf, const char *serial, Error **errp) { const char *driver; char *name; DeviceState *dev; + SCSIDevice *s; DriveInfo *dinfo; if (blk_is_sg(blk)) { @@ -399,11 +400,10 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk, object_property_add_child(OBJECT(bus), name, OBJECT(dev)); g_free(name); + s = SCSI_DEVICE(dev); + s->conf = *conf; + qdev_prop_set_uint32(dev, "scsi-id", unit); - if (bootindex >= 0) { - object_property_set_int(OBJECT(dev), "bootindex", bootindex, - &error_abort); - } if (object_property_find(OBJECT(dev), "removable")) { qdev_prop_set_bit(dev, "removable", removable); } @@ -414,19 +414,12 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk, object_unparent(OBJECT(dev)); return NULL; } - if (!object_property_set_bool(OBJECT(dev), "share-rw", share_rw, errp)) { - object_unparent(OBJECT(dev)); - return NULL; - } - - qdev_prop_set_enum(dev, "rerror", rerror); - qdev_prop_set_enum(dev, "werror", werror); if (!qdev_realize_and_unref(dev, &bus->qbus, errp)) { object_unparent(OBJECT(dev)); return NULL; } - return SCSI_DEVICE(dev); + return s; } void scsi_bus_legacy_handle_cmdline(SCSIBus *bus) @@ -434,6 +427,12 @@ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus) Location loc; DriveInfo *dinfo; int unit; + BlockConf conf = { + .bootindex = -1, + .share_rw = false, + .rerror = BLOCKDEV_ON_ERROR_AUTO, + .werror = BLOCKDEV_ON_ERROR_AUTO, + }; loc_push_none(&loc); for (unit = 0; unit <= bus->info->max_target; unit++) { @@ -443,10 +442,7 @@ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus) } qemu_opts_loc_restore(dinfo->opts); scsi_bus_legacy_add_drive(bus, blk_by_legacy_dinfo(dinfo), - unit, false, -1, false, - BLOCKDEV_ON_ERROR_AUTO, - BLOCKDEV_ON_ERROR_AUTO, - NULL, &error_fatal); + unit, false, &conf, NULL, &error_fatal); } loc_pop(&loc); } @@ -1728,11 +1724,20 @@ static void scsi_device_purge_one_req(SCSIRequest *req, void *opaque) scsi_req_cancel_async(req, NULL); } +/** + * Cancel all requests, and block until they are deleted. + */ void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense) { scsi_device_for_each_req_async(sdev, scsi_device_purge_one_req, NULL); + /* + * Await all the scsi_device_purge_one_req() calls scheduled by + * scsi_device_for_each_req_async(), and all I/O requests that were + * cancelled this way, but may still take a bit of time to settle. + */ blk_drain(sdev->conf.blk); + scsi_device_set_ua(sdev, sense); } diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 690acee..9f02cee 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -1149,6 +1149,7 @@ static void virtio_scsi_drained_begin(SCSIBus *bus) static void virtio_scsi_drained_end(SCSIBus *bus) { VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus); + VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s); VirtIODevice *vdev = VIRTIO_DEVICE(s); uint32_t total_queues = VIRTIO_SCSI_VQ_NUM_FIXED + s->parent_obj.conf.num_queues; @@ -1166,7 +1167,11 @@ static void virtio_scsi_drained_end(SCSIBus *bus) for (uint32_t i = 0; i < total_queues; i++) { VirtQueue *vq = virtio_get_queue(vdev, i); - virtio_queue_aio_attach_host_notifier(vq, s->ctx); + if (vq == vs->event_vq) { + virtio_queue_aio_attach_host_notifier_no_poll(vq, s->ctx); + } else { + virtio_queue_aio_attach_host_notifier(vq, s->ctx); + } } } |