[Commits] Rev 4292: MDEV-6450 - MariaDB crash on Power8 when built with advance tool in lp:maria/10.0

Sergey Vojtovich svoj at mariadb.org
Fri Jul 18 14:16:33 EEST 2014


At lp:maria/10.0

------------------------------------------------------------
revno: 4292
revision-id: svoj at mariadb.org-20140718111625-uch1ssbh8kf6i4ib
parent: jplindst at mariadb.org-20140715075753-24ptezu36xn4q37v
committer: Sergey Vojtovich <svoj at mariadb.org>
branch nick: 10.0
timestamp: Fri 2014-07-18 15:16:25 +0400
message:
  MDEV-6450 - MariaDB crash on Power8 when built with advance tool
              chain
  
  InnoDB mutex_exit() function calls __sync_test_and_set() to release
  the lock. According to manual this function is supposed to create
  "acquire" memory barrier whereas in fact we need "release" memory
  barrier at mutex_exit().
  
  The problem isn't repeatable with gcc because it creates
  "acquire-release" memory barrier for __sync_test_and_set().
  ATC creates just "acquire" barrier.
  
  Fixed by creating proper barrier at mutex_exit() by using
  __sync_lock_release() instead of __sync_test_and_set().
=== modified file 'storage/innobase/include/os0sync.h'
--- a/storage/innobase/include/os0sync.h	2014-05-07 15:32:23 +0000
+++ b/storage/innobase/include/os0sync.h	2014-07-18 11:16:25 +0000
@@ -434,6 +434,9 @@ Returns the old value of *ptr, atomicall
 # define os_atomic_test_and_set_ulint(ptr, new_val) \
 	__sync_lock_test_and_set(ptr, new_val)
 
+# define os_atomic_lock_release_byte(ptr) \
+	__sync_lock_release(ptr)
+
 #elif defined(HAVE_IB_SOLARIS_ATOMICS)
 
 # define HAVE_ATOMIC_BUILTINS
@@ -515,6 +518,9 @@ Returns the old value of *ptr, atomicall
 # define os_atomic_test_and_set_ulint(ptr, new_val) \
 	atomic_swap_ulong(ptr, new_val)
 
+# define os_atomic_lock_release_byte(ptr) \
+	(void) atomic_swap_uchar(ptr, 0)
+
 #elif defined(HAVE_WINDOWS_ATOMICS)
 
 # define HAVE_ATOMIC_BUILTINS
@@ -637,6 +643,9 @@ clobbered */
 # define os_atomic_test_and_set_ulong(ptr, new_val) \
 	InterlockedExchange(ptr, new_val)
 
+# define os_atomic_lock_release_byte(ptr) \
+	(void) InterlockedExchange(ptr, 0)
+
 #else
 # define IB_ATOMICS_STARTUP_MSG \
 	"Mutexes and rw_locks use InnoDB's own implementation"

=== modified file 'storage/innobase/include/sync0sync.ic'
--- a/storage/innobase/include/sync0sync.ic	2014-05-07 15:32:23 +0000
+++ b/storage/innobase/include/sync0sync.ic	2014-07-18 11:16:25 +0000
@@ -108,10 +108,7 @@ mutex_reset_lock_word(
 	ib_mutex_t*	mutex)	/*!< in: mutex */
 {
 #if defined(HAVE_ATOMIC_BUILTINS)
-	/* In theory __sync_lock_release should be used to release the lock.
-	Unfortunately, it does not work properly alone. The workaround is
-	that more conservative __sync_lock_test_and_set is used instead. */
-	os_atomic_test_and_set_byte(&mutex->lock_word, 0);
+	os_atomic_lock_release_byte(&mutex->lock_word);
 #else
 	mutex->lock_word = 0;
 

=== modified file 'storage/xtradb/include/os0sync.h'
--- a/storage/xtradb/include/os0sync.h	2014-05-07 15:33:33 +0000
+++ b/storage/xtradb/include/os0sync.h	2014-07-18 11:16:25 +0000
@@ -434,6 +434,9 @@ Returns the old value of *ptr, atomicall
 # define os_atomic_test_and_set_ulint(ptr, new_val) \
 	__sync_lock_test_and_set(ptr, new_val)
 
+# define os_atomic_lock_release_byte(ptr) \
+	__sync_lock_release(ptr)
+
 #elif defined(HAVE_IB_SOLARIS_ATOMICS)
 
 # define HAVE_ATOMIC_BUILTINS
@@ -515,6 +518,9 @@ Returns the old value of *ptr, atomicall
 # define os_atomic_test_and_set_ulint(ptr, new_val) \
 	atomic_swap_ulong(ptr, new_val)
 
+# define os_atomic_lock_release_byte(ptr) \
+	(void) atomic_swap_uchar(ptr, 0)
+
 #elif defined(HAVE_WINDOWS_ATOMICS)
 
 # define HAVE_ATOMIC_BUILTINS
@@ -637,6 +643,9 @@ clobbered */
 # define os_atomic_test_and_set_ulong(ptr, new_val) \
 	InterlockedExchange(ptr, new_val)
 
+# define os_atomic_lock_release_byte(ptr) \
+	(void) InterlockedExchange(ptr, 0)
+
 #else
 # define IB_ATOMICS_STARTUP_MSG \
 	"Mutexes and rw_locks use InnoDB's own implementation"

=== modified file 'storage/xtradb/include/sync0sync.ic'
--- a/storage/xtradb/include/sync0sync.ic	2014-05-07 15:33:33 +0000
+++ b/storage/xtradb/include/sync0sync.ic	2014-07-18 11:16:25 +0000
@@ -111,10 +111,7 @@ mutex_reset_lock_word(
 	ib_mutex_t*	mutex)	/*!< in: mutex */
 {
 #if defined(HAVE_ATOMIC_BUILTINS)
-	/* In theory __sync_lock_release should be used to release the lock.
-	Unfortunately, it does not work properly alone. The workaround is
-	that more conservative __sync_lock_test_and_set is used instead. */
-	os_atomic_test_and_set_byte(&mutex->lock_word, 0);
+	os_atomic_lock_release_byte(&mutex->lock_word);
 #else
 	mutex->lock_word = 0;
 



More information about the commits mailing list