| 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: | |
| Category: | MySQL Server | Severity: | S3 (Non-critical) |
| Version: | 5.7 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
[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.

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