Bug #80426 innodb uses gcc atomic builtins incorrectly, results in PowerPC64 assertions
Submitted: 18 Feb 2016 10:17 Modified: 23 Mar 2018 13:02
Reporter: Anton Blanchard (OCA) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:5.7 OS:Any
Assigned to: CPU Architecture:Any

[18 Feb 2016 10:17] Anton Blanchard
Description:
We are seeing innodb assertions on 5.7 when running benchmarks on PowerPC64 Linux. After some investigation it was found that the memory barrier is in the wrong place on mutex_enter().

10f11aa8:    li      r4,1
10f11aac:    lwsync                  <------------- here
10f11ab0:    ldarx   r5,0,r3
10f11ab4:    stdcx.  r4,0,r3
10f11ab8:    bne     10f11ab0 <_Z5antonv+0xa0>
                                     <------------- should be here
10f11abc:    cmpldi  r5,0
10f11ac0:    beq     10f11ae0 <_Z5antonv+0xd0>

mutex_enter() -> CAS() -> os_atomic_val_compare_and_swap()

And in os_atomic_val_compare_and_swap():

      __atomic_compare_exchange(ptr, &old_val, &new_val, false,
                                __ATOMIC_RELEASE, __ATOMIC_ACQUIRE);

The prototype for __atomic_compare_exchange() is:

bool __atomic_compare_exchange (type *ptr, type *expected, type *desired, bool weak, int success_memorder, int failure_memorder)

So we are specifying release semantics on a lock acquire, which is wrong. I'm also not sure why we are specifying a failure_memorder.

A similar issue is in tas_lock() -> TAS -> os_atomic_test_and_set()

Where os_atomic_test_and_set():

      __atomic_exchange(ptr, &new_val,  &ret, __ATOMIC_RELEASE);

How to repeat:
This regularly fails:

./mysql-test-run.pl rpl.rpl_innodb_bug28430
[7 Nov 2017 5:06] Daniel Black
fixed in https://github.com/mysql/mysql-server/commit/8870f822d86644fe4578be7025c76478f42100fa

(release 5.7.13). Thanks Shaohua and Sunny.

tested on 5.7.20 with no failures. Previously would of failed ~1/20 tests.

$ (cd  mysql-test/; ./mtr --mem --parallel=20 --repeat=200 rpl.rpl_innodb_bug28430 )
...

--------------------------------------------------------------------------
The servers were restarted 0 times
Spent 399.771 of 271 seconds executing testcases

Completed: All 400 tests were successful.

1 tests were skipped, 0 by the test itself.
[23 Mar 2018 13:02] MySQL Verification Team
Closed according last comment.