qemu-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]