From 8121d03fd48c5107a2ef04b3d9991e1441e92995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 22 Apr 2021 15:43:30 +0300 Subject: MDEV-25404 fixup: Fix ssux_lock_low::u_wr_upgrade() The U-to-X upgrade turned out to be incorrect. A debug assertion failed in wr_wait(), called from mtr_defer_drop_ahi() in a stress test with innodb_adaptive_hash_index=ON. A correct upgrade procedure ought to be readers.fetch_add(WRITER-1) to register ourselves as a WRITER (or waiting writer) and to release the reference that was being held for the U lock. Thanks to Matthias Leich for catching the problem. --- storage/innobase/include/srw_lock.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/storage/innobase/include/srw_lock.h b/storage/innobase/include/srw_lock.h index a74cb9a9212..fdac659d494 100644 --- a/storage/innobase/include/srw_lock.h +++ b/storage/innobase/include/srw_lock.h @@ -217,11 +217,9 @@ public: void u_wr_upgrade() { DBUG_ASSERT(writer.is_locked()); - uint32_t lk= 1; - if (!readers.compare_exchange_strong(lk, WRITER, - std::memory_order_acquire, - std::memory_order_relaxed)) - wr_wait(lk); + uint32_t lk= readers.fetch_add(WRITER - 1, std::memory_order_acquire); + if (lk != 1) + wr_wait(lk - 1); } void wr_u_downgrade() { -- cgit v1.2.1