qemu/include
Stefan Hajnoczi be2c42b97c virtio-scsi: reset SCSI devices from main loop thread
When an IOThread is configured, the ctrl virtqueue is processed in the
IOThread. TMFs that reset SCSI devices are currently called directly
from the IOThread and trigger an assertion failure in blk_drain() from
the following call stack:

virtio_scsi_handle_ctrl_req -> virtio_scsi_do_tmf -> device_code_reset
-> scsi_disk_reset -> scsi_device_purge_requests -> blk_drain

  ../block/block-backend.c:1780: void blk_drain(BlockBackend *): Assertion `qemu_in_main_thread()' failed.

The blk_drain() function is not designed to be called from an IOThread
because it needs the Big QEMU Lock (BQL).

This patch defers TMFs that reset SCSI devices to a Bottom Half (BH)
that runs in the main loop thread under the BQL. This way it's safe to
call blk_drain() and the assertion failure is avoided.

Introduce s->tmf_bh_list for tracking TMF requests that have been
deferred to the BH. When the BH runs it will grab the entire list and
process all requests. Care must be taken to clear the list when the
virtio-scsi device is reset or unrealized. Otherwise deferred TMF
requests could execute later and lead to use-after-free or other
undefined behavior.

The s->resetting counter that's used by TMFs that reset SCSI devices is
accessed from multiple threads. This patch makes that explicit by using
atomic accessor functions. With this patch applied the counter is only
modified by the main loop thread under the BQL but can be read by any
thread.

Reported-by: Qing Wang <qinwang@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20230221212218.1378734-4-stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2023-02-23 19:49:35 +01:00
..
authz
block block: Mark bdrv_co_refresh_total_sectors() and callers GRAPH_RDLOCK 2023-02-23 19:49:33 +01:00
chardev chardev: src buffer const for write functions 2022-09-29 14:38:05 +04:00
crypto crypto: TLS: introduce check_pending 2023-02-15 11:01:03 -05:00
disas remove unnecessary extern "C" blocks 2023-02-10 14:12:06 +01:00
exec bsd-user/mmap: use TSA_NO_TSA to suppress clang TSA warnings in FreeBSD 2023-02-17 11:22:19 +01:00
fpu fpu: Add rebias bool, value and operation 2022-08-31 14:08:05 -03:00
hw virtio-scsi: reset SCSI devices from main loop thread 2023-02-23 19:49:35 +01:00
io io: Add support for MSG_PEEK for socket channel 2023-02-06 19:22:56 +01:00
libdecnumber Replace config-time define HOST_WORDS_BIGENDIAN 2022-04-06 10:50:37 +02:00
migration migration: Rename res_{postcopy,precopy}_only 2023-02-15 20:04:30 +01:00
monitor monitor: Move remaining HMP commands from misc.c to hmp-cmds.c 2023-02-04 07:56:54 +01:00
net net: Move the code to collect available NIC models to a separate function 2023-02-17 13:31:33 +08:00
qapi qerror: QERR_PERMISSION_DENIED is no longer used, drop 2022-10-27 07:57:18 +02:00
qemu hbitmap: fix hbitmap_status() return value for first dirty bit case 2023-02-17 14:34:24 +01:00
qom qom/object: Remove circular include dependency 2022-06-28 10:53:32 +02:00
scsi coroutine: Clean up superfluous inclusion of qemu/coroutine.h 2023-01-19 10:18:28 +01:00
semihosting semihosting: Allow optional use of semihosting from userspace 2022-09-13 17:18:21 +01:00
standard-headers linux-headers: Update to v6.2-rc8 2023-02-16 12:13:46 -07:00
sysemu block: Mark bdrv_co_is_inserted() and callers GRAPH_RDLOCK 2023-02-23 19:49:25 +01:00
tcg tcg: Split out tcg_gen_nonatomic_cmpxchg_i{32,64} 2023-02-04 06:19:42 -10:00
ui Do not include "qemu/error-report.h" in headers that do not need it 2023-02-14 09:11:27 +01:00
user include: Include headers where needed 2023-01-08 01:54:22 -05:00
elf.h include/elf.h: add s390x note types 2022-10-26 12:54:59 +04:00
glib-compat.h compiler.h: replace QEMU_NORETURN with G_NORETURN 2022-04-21 17:03:51 +04:00
qemu-io.h
qemu-main.h ui/cocoa: Run qemu_init in the main thread 2022-09-23 14:36:33 +02:00