Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
gettime: use atomic operations to access t->seq
fio on Windows with a 16 or 32 CPUs frequently fails while running ./fio --cpuclock-test even though "reliable_tsc: yes" is reported. Using clang's thread sanitizer via CC=clang ./configure --extra-cflags="-fsanitize=thread" and running the same on Linux also generates multiple warnings similar to the following on a VM with 16 cores: WARNING: ThreadSanitizer: data race (pid=23780) Atomic write of size 4 at 0x7ffecb865a3c by thread T15 (mutexes: write M169): #0 __tsan_atomic32_fetch_add /home/clang-3.9/llvm/projects/compiler-rt/lib/tsan/rtl/tsan_interface_atomic.cc:591 (fio+0x000000471505) axboe#1 atomic32_inc_return /home/fio/gettime.c:567:13 (fio+0x0000004c56c1) axboe#2 clock_thread_fn /home/fio/gettime.c:607 (fio+0x0000004c56c1) Previous read of size 4 at 0x7ffecb865a3c by thread T4 (mutexes: write M147): #0 clock_thread_fn /home/fio/gettime.c:611:19 (fio+0x0000004c56e2) Location is stack of main thread. Mutex M169 (0x7d700000f6a0) created at: #0 pthread_mutex_init /home/clang-3.9/llvm/projects/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:1119 (fio+0x00000043b695) axboe#1 fio_monotonic_clocktest /home/fio/gettime.c:694:3 (fio+0x0000004c4c12) axboe#2 parse_cmd_line /home/fio/init.c:2710:15 (fio+0x0000004ce8e5) axboe#3 parse_options /home/fio/init.c:2828:14 (fio+0x0000004cf3da) axboe#4 main /home/fio/fio.c:47:6 (fio+0x00000054b991) Mutex M147 (0x7d700000f178) created at: #0 pthread_mutex_init /home/clang-3.9/llvm/projects/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:1119 (fio+0x00000043b695) axboe#1 fio_monotonic_clocktest /home/fio/gettime.c:694:3 (fio+0x0000004c4c12) axboe#2 parse_cmd_line /home/fio/init.c:2710:15 (fio+0x0000004ce8e5) axboe#3 parse_options /home/fio/init.c:2828:14 (fio+0x0000004cf3da) axboe#4 main /home/fio/fio.c:47:6 (fio+0x00000054b991) Thread T15 (tid=23796, running) created by main thread at: #0 pthread_create /home/clang-3.9/llvm/projects/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:902 (fio+0x00000042c9a6) axboe#1 fio_monotonic_clocktest /home/fio/gettime.c:697:7 (fio+0x0000004c4c38) axboe#2 parse_cmd_line /home/fio/init.c:2710:15 (fio+0x0000004ce8e5) axboe#3 parse_options /home/fio/init.c:2828:14 (fio+0x0000004cf3da) axboe#4 main /home/fio/fio.c:47:6 (fio+0x00000054b991) Thread T4 (tid=23785, finished) created by main thread at: #0 pthread_create /home/clang-3.9/llvm/projects/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:902 (fio+0x00000042c9a6) axboe#1 fio_monotonic_clocktest /home/fio/gettime.c:697:7 (fio+0x0000004c4c38) axboe#2 parse_cmd_line /home/fio/init.c:2710:15 (fio+0x0000004ce8e5) axboe#3 parse_options /home/fio/init.c:2828:14 (fio+0x0000004cf3da) axboe#4 main /home/fio/fio.c:47:6 (fio+0x00000054b991) SUMMARY: ThreadSanitizer: data race /home/fio/gettime.c:567:13 in atomic32_inc_return Fix the above by doing the following: - Add a configure check for __sync_val_compare_and_swap and add a helper atomic32_cas_return that uses it. - Add comments noting that the atomic32_* functions act as full barriers. - Don't access t->seq directly when protecting a critical region and instead use the atomic32_* helpers to update/read it. The above fixes the sanitizer warnings and makes the test pass on Windows. Fixes: axboe#479 Signed-off-by: Sitsofe Wheeler <sitsofe@yahoo.com>
- Loading branch information
@axboe I've got to know - where did my attempt go wrong (you can see the full branch over on https://github.com/sitsofe/fio/tree/cycletest-broken)? Because the operations wrapping
tsc
were atomic I presumed their results would be visible on all CPUs simultaneously and that they would themselves act as full barriers. As such they wouldn't they protect the critical region correctly?