bc19a0a6e4
The following QMP command leads to a crash when iothreads are used: { 'execute': 'device_del', 'arguments': {'id': 'data'} } The backtrace involves the queue restart coroutine where tgm->throttle_state is a NULL pointer because throttle_group_unregister_tgm() has already been called: (gdb) bt full #0 0x00005585a7a3b378 in qemu_mutex_lock_impl (mutex=0xffffffffffffffd0, file=0x5585a7bb3d54 "block/throttle-groups.c", line=412) at util/qemu-thread-posix.c:64 err = <optimized out> __PRETTY_FUNCTION__ = "qemu_mutex_lock_impl" __func__ = "qemu_mutex_lock_impl" #1 0x00005585a79be074 in throttle_group_restart_queue_entry (opaque=0x5585a9de4eb0) at block/throttle-groups.c:412 _f = <optimized out> data = 0x5585a9de4eb0 tgm = 0x5585a9079440 ts = 0x0 tg = 0xffffffffffffff98 is_write = false empty_queue = 255 This coroutine should not execute in the iothread after the throttle group member has been unregistered! The root cause is that the device_del code path schedules the restart coroutine in the iothread while holding the AioContext lock. Therefore the iothread cannot execute the coroutine until after device_del releases the lock - by this time it's too late. This patch adds a reference count to ThrottleGroupMember so we can synchronously wait for restart coroutines to complete. Once they are done it is safe to unregister the ThrottleGroupMember. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Alberto Garcia <berto@igalia.com> Message-id: 20190114133257.30299-2-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> |
||
---|---|---|
.. | ||
accounting.c | ||
backup.c | ||
blkdebug.c | ||
blklogwrites.c | ||
blkreplay.c | ||
blkverify.c | ||
block-backend.c | ||
bochs.c | ||
cloop.c | ||
commit.c | ||
copy-on-read.c | ||
create.c | ||
crypto.c | ||
crypto.h | ||
curl.c | ||
dirty-bitmap.c | ||
dmg-bz2.c | ||
dmg-lzfse.c | ||
dmg.c | ||
dmg.h | ||
file-posix.c | ||
file-win32.c | ||
gluster.c | ||
io.c | ||
iscsi-opts.c | ||
iscsi.c | ||
linux-aio.c | ||
Makefile.objs | ||
mirror.c | ||
nbd-client.c | ||
nbd-client.h | ||
nbd.c | ||
nfs.c | ||
null.c | ||
nvme.c | ||
parallels.c | ||
parallels.h | ||
qapi.c | ||
qcow2-bitmap.c | ||
qcow2-cache.c | ||
qcow2-cluster.c | ||
qcow2-refcount.c | ||
qcow2-snapshot.c | ||
qcow2.c | ||
qcow2.h | ||
qcow.c | ||
qed-check.c | ||
qed-cluster.c | ||
qed-l2-cache.c | ||
qed-table.c | ||
qed.c | ||
qed.h | ||
quorum.c | ||
raw-format.c | ||
rbd.c | ||
replication.c | ||
sheepdog.c | ||
snapshot.c | ||
ssh.c | ||
stream.c | ||
throttle-groups.c | ||
throttle.c | ||
trace-events | ||
vdi.c | ||
vhdx-endian.c | ||
vhdx-log.c | ||
vhdx.c | ||
vhdx.h | ||
vmdk.c | ||
vpc.c | ||
vvfat.c | ||
vxhs.c | ||
win32-aio.c | ||
write-threshold.c |