[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 4/5] coroutine-lock: reimplement CoRwLock to fix downgrade bu
From: |
Paolo Bonzini |
Subject: |
Re: [PATCH 4/5] coroutine-lock: reimplement CoRwLock to fix downgrade bug |
Date: |
Wed, 17 Mar 2021 13:00:26 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.7.0 |
On 17/03/21 11:40, David Edmondson wrote:
Isn't this...
* ... Also, @qemu_co_rwlock_upgrade
* only overrides CoRwlock fairness if there are no concurrent readers, so
* another writer might run while @qemu_co_rwlock_upgrade blocks.
...now incorrect?
Maybe, but for sure the comment was too hard to parse.
+ if (lock->owner == 1 && QSIMPLEQ_EMPTY(&lock->tickets)) {
+ lock->owner = -1;
+ qemu_co_mutex_unlock(&lock->mutex);
+ } else {
+ lock->owner--;
+ qemu_co_rwlock_sleep(false, lock);
Doesn't this need something for the case where lock->owner hits 0?
You're right, we need to call qemu_co_rwlock_maybe_wake_one if lock goes
to 0. The "else" branch would have to be
if (--lock->owner == 0) {
qemu_co_rwlock_maybe_wake_one(lock);
qemu_co_mutex_lock(&lock->mutex);
}
qemu_co_rwlock_sleep(false, lock);
In the end it's actually simpler to just inline qemu_co_rwlock_sleep,
which also leads to the following slightly more optimized code for the
"else" branch:
CoRwTicket my_ticket = { false, qemu_coroutine_self() };
lock->owner--;
QSIMPLEQ_INSERT_TAIL(&lock->tickets, &my_ticket, next);
qemu_co_rwlock_maybe_wake_one(lock);
qemu_coroutine_yield();
assert(lock->owner == -1);
I'll add a testcase, too. You don't even need two upgraders, for example:
rdlock
yield
wrlock
upgrade
<queued> <dequeued>
unlock
<dequeued>
unlock
In fact even for this simple case, the old implementation got it wrong!
(The new one also did, but the fix is easy).
There are a couple other improvements that can be made:
qemu_co_rwlock_unlock can also call qemu_co_rwlock_maybe_wake_one
unconditionally, the "if" around the call is unnecessary; and I'll
rename "owner" to "owners".
Anyway, there is nothing that really made you scream, so that's good.
Paolo
- [PATCH v3 0/5] coroutine rwlock downgrade fix, minor VDI changes, Paolo Bonzini, 2021/03/16
- [PATCH 5/5] test-coroutine: Add rwlock downgrade test, Paolo Bonzini, 2021/03/16
- [PATCH 1/5] block/vdi: When writing new bmap entry fails, don't leak the buffer, Paolo Bonzini, 2021/03/16
- [PATCH 4/5] coroutine-lock: reimplement CoRwLock to fix downgrade bug, Paolo Bonzini, 2021/03/16
- [PATCH 3/5] coroutine/mutex: Store the coroutine in the CoWaitRecord only once, Paolo Bonzini, 2021/03/16
- [PATCH 2/5] block/vdi: Don't assume that blocks are larger than VdiHeader, Paolo Bonzini, 2021/03/16