qemu/include
Paolo Bonzini 050de36b13 coroutine-lock: Reimplement CoRwlock to fix downgrade bug
An invariant of the current rwlock is that if multiple coroutines hold a
reader lock, all must be runnable. The unlock implementation relies on
this, choosing to wake a single coroutine when the final read lock
holder exits the critical section, assuming that it will wake a
coroutine attempting to acquire a write lock.

The downgrade implementation violates this assumption by creating a
read lock owning coroutine that is exclusively runnable - any other
coroutines that are waiting to acquire a read lock are *not* made
runnable when the write lock holder converts its ownership to read
only.

More in general, the old implementation had lots of other fairness bugs.
The root cause of the bugs was that CoQueue would wake up readers even
if there were pending writers, and would wake up writers even if there
were readers.  In that case, the coroutine would go back to sleep *at
the end* of the CoQueue, losing its place at the head of the line.

To fix this, keep the queue of waiters explicitly in the CoRwlock
instead of using CoQueue, and store for each whether it is a
potential reader or a writer.  This way, downgrade can look at the
first queued coroutines and wake it only if it is a reader, causing
all other readers in line to be released in turn.

Reported-by: David Edmondson <david.edmondson@oracle.com>
Reviewed-by: David Edmondson <david.edmondson@oracle.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 20210325112941.365238-5-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2021-03-31 10:44:21 +01:00
..
authz Prefer 'on' | 'off' over 'yes' | 'no' for bool options 2021-01-29 17:07:53 +00:00
block emulated nvme updates and fixes 2021-03-18 19:55:37 +00:00
chardev chardev: do not use machine_init_done 2020-12-15 12:51:51 -05:00
crypto crypto: add reload for QCryptoTLSCredsClass 2021-03-23 08:48:21 +01:00
disas Hexagon (disas) disassembler 2021-02-18 07:48:22 -08:00
exec exec: Build page-vary-common.c with -fno-lto 2021-03-23 19:36:47 -06:00
fpu softfloat: Define comparison operations for bfloat16 2020-08-29 19:25:42 -07:00
hw s390x: move S390_ADAPTER_SUPPRESSIBLE 2021-03-26 09:33:50 +01:00
io io: add qio_channel_readv_full_all_eof & qio_channel_readv_full_all helpers 2021-02-10 09:23:28 +00:00
libdecnumber include: Make headers more self-contained 2019-08-16 13:31:51 +02:00
migration migration: introduce a delete_snapshot wrapper 2021-02-08 11:19:51 +00:00
monitor migrate: remove QMP/HMP commands for speed, downtime and cache size 2021-03-18 09:22:55 +00:00
net net: Add a 'do_not_pad" to NetClientState 2021-03-22 17:34:31 +08:00
qapi qapi: Implement deprecated-input=reject for QMP command arguments 2021-03-19 16:05:11 +01:00
qemu coroutine-lock: Reimplement CoRwlock to fix downgrade bug 2021-03-31 10:44:21 +01:00
qom qom: move user_creatable_add_opts logic to vl.c and QAPIfy it 2021-03-19 10:18:17 +01:00
scsi scsi: inline sg_io_sense_from_errno() into the callers. 2021-03-06 11:42:56 +01:00
semihosting semihosting: Move include/hw/semihosting/ -> include/semihosting/ 2021-03-10 15:34:12 +00:00
standard-headers m68k pull request 20210315 2021-03-17 10:38:27 +00:00
sysemu m68k: add the virtio devices aliases 2021-03-24 14:25:48 +00:00
tcg tcg/tci: Implement the disassembler properly 2021-03-17 07:24:44 -06:00
ui include/ui/console.h: Delete is_surface_bgr() 2021-03-23 08:48:21 +01:00
user trace: switch position of headers to what Meson requires 2020-08-21 06:18:24 -04:00
elf.h Remove deprecated target tilegx 2021-03-09 11:26:32 +01:00
glib-compat.h glib-compat: add g_unix_get_passwd_entry_qemu() 2020-11-02 19:52:08 -06:00
qemu-common.h qemu-common.h: Update copyright string to 2021 2021-03-09 22:19:24 +01:00
qemu-io.h Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
trace-tcg.h