summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-04-22 15:43:30 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2021-04-22 15:43:30 +0300
commit8121d03fd48c5107a2ef04b3d9991e1441e92995 (patch)
tree07a7cab57bae88bb5054483e8363f86b3847ff72
parent54c460ace606157f2a23706ec98e9de70aba767e (diff)
downloadmariadb-git-bb-10.6-MDEV-25404.tar.gz
MDEV-25404 fixup: Fix ssux_lock_low::u_wr_upgrade()bb-10.6-MDEV-25404
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.
-rw-r--r--storage/innobase/include/srw_lock.h8
1 files 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()
{