| Bug #72755 | InnoDB mutex spin loop is missing GCC barrier | ||
|---|---|---|---|
| Submitted: | 27 May 2014 2:22 | Modified: | 30 May 2014 6:22 |
| Reporter: | Stewart Smith | Email Updates: | |
| Status: | Verified | Impact on me: | |
| Category: | MySQL Server: InnoDB storage engine | Severity: | S3 (Non-critical) |
| Version: | 5.6 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
| Tags: | innodb mutex | ||
[27 May 2014 8:39]
MySQL Verification Team
Hello Stewart, Thank you for the report. Thanks, Umesh
[29 May 2014 5:39]
Yasufumi Kinoshita
I think "asm volatile("":::"memory");" is not needed here.
Did you actually test the code difference with it and without it?
ut_delay() is function of the another object file ut0ut.o.
And it contains global fake variable access not to be over-optimized.
lock_word is volatile type specified.
I don't think compiler do over-optimization sync0sync.o more to kill the loop.
Or only for srv_spin_wait_delay==0 case?
Or do you use something link-time re-optimization?
Anyway this doesn't seem current problem.
[30 May 2014 6:08]
Stewart Smith
I think you're right that for MySQL 5.6 this is not currently a problem. I've been doing benchmarks with spin_wait_delay=0 on 5.6, but even with spin_wait_delay!=0, the fake variable access is not the most optimal way to implement a delay loop as it generates needless memory traffic - the GCC barrier will force GCC not to optimize the loop away and won't generate excess memory traffic to a global variable (that on Intel will have to be synchronized between CPUs on access). While I haven't attempted to benchmark it on 5.6, on MySQL 5.7 the memory traffic generated by the MySQL mutex_delay function did show up in a profile and I have a 5.7 patch I'll post very shortly (as in, right now :)
[30 May 2014 6:22]
Stewart Smith
For 5.7: http://bugs.mysql.com/bug.php?id=72805 which is generic code, not InnoDB specific.
[14 Apr 2016 0:17]
Daniel Black
Commit 5e3efb03 (Bug#20045167) uses a compile barrier as UT_DELAY in the ut_delay loop for arches without a delay/pause instruction.

Description: The spinloop attempting to grab a mutex in innodb lokos like this: while (mutex_get_lock_word(mutex) != 0 && i < SYNC_SPIN_ROUNDS) { if (srv_spin_wait_delay) { ut_delay(ut_rnd_interval(0, srv_spin_wait_delay)); } i++; } A problem with this is that GCC could optimize this away to nothing if it was sufficiently smart, and indeed, if you remove the ut_delay call, it likely will. It's quite possible that it does do it already with some configurations, and other compilers may do so too. How to repeat: Code analysis! Suggested fix: Add a GCC barrier inside the loop, like this: asm volatile("":::"memory"); which forces it not to optimize the loop away to nothing. I've done this as part of my patch for http://bugs.mysql.com/bug.php?id=72754