summaryrefslogtreecommitdiff
path: root/storage/innobase/sync
diff options
context:
space:
mode:
authorSergey Vojtovich <svoj@mariadb.org>2014-08-29 16:14:11 +0400
committerSergey Vojtovich <svoj@mariadb.org>2014-08-29 16:14:11 +0400
commitc01c819209fdf09b4ba95f34d87d0617776f47cd (patch)
tree5ed1163d77307ab95e36b54688e75ac04731f6d2 /storage/innobase/sync
parent40497577ffd9f85557b15e08ad913f627b2e9530 (diff)
downloadmariadb-git-c01c819209fdf09b4ba95f34d87d0617776f47cd.tar.gz
Backport from 10.0:
MDEV-6483 - Deadlock around rw_lock_debug_mutex on PPC64 This problem affects only debug builds on PPC64. There are at least two race conditions around rw_lock_debug_mutex_enter and rw_lock_debug_mutex_exit: - rw_lock_debug_waiters was loaded/stored without setting appropriate locks/memory barriers. - there is a gap between calls to os_event_reset() and os_event_wait() and in such case we're supposed to pass return value of the former to the latter. Fixed by replacing self-cooked spinlocks with system mutexes. These days system mutexes offer much better performance. OTOH performance is not that critical for debug builds.
Diffstat (limited to 'storage/innobase/sync')
-rw-r--r--storage/innobase/sync/sync0rw.c32
-rw-r--r--storage/innobase/sync/sync0sync.c7
2 files changed, 5 insertions, 34 deletions
diff --git a/storage/innobase/sync/sync0rw.c b/storage/innobase/sync/sync0rw.c
index 21e3d57287a..50531455a4c 100644
--- a/storage/innobase/sync/sync0rw.c
+++ b/storage/innobase/sync/sync0rw.c
@@ -180,18 +180,12 @@ UNIV_INTERN mysql_pfs_key_t rw_lock_mutex_key;
To modify the debug info list of an rw-lock, this mutex has to be
acquired in addition to the mutex protecting the lock. */
-UNIV_INTERN mutex_t rw_lock_debug_mutex;
+UNIV_INTERN os_fast_mutex_t rw_lock_debug_mutex;
# ifdef UNIV_PFS_MUTEX
UNIV_INTERN mysql_pfs_key_t rw_lock_debug_mutex_key;
# endif
-/* If deadlock detection does not get immediately the mutex,
-it may wait for this event */
-UNIV_INTERN os_event_t rw_lock_debug_event;
-/* This is set to TRUE, if there may be waiters for the event */
-UNIV_INTERN ibool rw_lock_debug_waiters;
-
/******************************************************************//**
Creates a debug info struct. */
static
@@ -736,22 +730,7 @@ void
rw_lock_debug_mutex_enter(void)
/*===========================*/
{
-loop:
- if (0 == mutex_enter_nowait(&rw_lock_debug_mutex)) {
- return;
- }
-
- os_event_reset(rw_lock_debug_event);
-
- rw_lock_debug_waiters = TRUE;
-
- if (0 == mutex_enter_nowait(&rw_lock_debug_mutex)) {
- return;
- }
-
- os_event_wait(rw_lock_debug_event);
-
- goto loop;
+ os_fast_mutex_lock(&rw_lock_debug_mutex);
}
/******************************************************************//**
@@ -761,12 +740,7 @@ void
rw_lock_debug_mutex_exit(void)
/*==========================*/
{
- mutex_exit(&rw_lock_debug_mutex);
-
- if (rw_lock_debug_waiters) {
- rw_lock_debug_waiters = FALSE;
- os_event_set(rw_lock_debug_event);
- }
+ os_fast_mutex_unlock(&rw_lock_debug_mutex);
}
/******************************************************************//**
diff --git a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
index cd81cccfc5a..3ae77616faf 100644
--- a/storage/innobase/sync/sync0sync.c
+++ b/storage/innobase/sync/sync0sync.c
@@ -1535,11 +1535,7 @@ sync_init(void)
SYNC_NO_ORDER_CHECK);
#ifdef UNIV_SYNC_DEBUG
- mutex_create(rw_lock_debug_mutex_key, &rw_lock_debug_mutex,
- SYNC_NO_ORDER_CHECK);
-
- rw_lock_debug_event = os_event_create(NULL);
- rw_lock_debug_waiters = FALSE;
+ os_fast_mutex_init(rw_lock_debug_mutex_key, &rw_lock_debug_mutex);
#endif /* UNIV_SYNC_DEBUG */
}
@@ -1607,6 +1603,7 @@ sync_close(void)
sync_order_checks_on = FALSE;
sync_thread_level_arrays_free();
+ os_fast_mutex_free(&rw_lock_debug_mutex);
#endif /* UNIV_SYNC_DEBUG */
sync_initialized = FALSE;