Merge pull request #5788 from vjpai/make_clang_great_again_v2

Update clang for the Dockerfile used in tsan tests, fix a newly exposed bug
diff --git a/Makefile b/Makefile
index 8af8ade..c7f7c9c 100644
--- a/Makefile
+++ b/Makefile
@@ -188,8 +188,8 @@
 CXX_tsan = clang++
 LD_tsan = clang
 LDXX_tsan = clang++
-CPPFLAGS_tsan = -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument -fPIE -pie -DGPR_NO_DIRECT_SYSCALLS
-LDFLAGS_tsan = -fsanitize=thread -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
+CPPFLAGS_tsan = -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
+LDFLAGS_tsan = -fsanitize=thread
 DEFINES_tsan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=5
 
 VALID_CONFIG_stapprof = 1
@@ -225,8 +225,8 @@
 CXX_etsan = clang++
 LD_etsan = clang
 LDXX_etsan = clang++
-CPPFLAGS_etsan = -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument -fPIE -pie -DGPR_NO_DIRECT_SYSCALLS
-LDFLAGS_etsan = -fsanitize=thread -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
+CPPFLAGS_etsan = -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
+LDFLAGS_etsan = -fsanitize=thread
 DEFINES_etsan = _DEBUG DEBUG GRPC_EXECUTION_CONTEXT_SANITIZER
 DEFINES_etsan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=5
 
diff --git a/build.yaml b/build.yaml
index 03ee95a..deec44f 100644
--- a/build.yaml
+++ b/build.yaml
@@ -2471,8 +2471,6 @@
   - gpr_test_util
   - gpr
   - grpc++_test_config
-  exclude_configs:
-  - tsan
   platforms:
   - mac
   - linux
@@ -2492,8 +2490,6 @@
   - gpr_test_util
   - gpr
   - grpc++_test_config
-  exclude_configs:
-  - tsan
   platforms:
   - mac
   - linux
@@ -2826,11 +2822,11 @@
   etsan:
     CC: clang
     CPPFLAGS: -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument
-      -fPIE -pie -DGPR_NO_DIRECT_SYSCALLS
+      -DGPR_NO_DIRECT_SYSCALLS
     CXX: clang++
     DEFINES: _DEBUG DEBUG GRPC_EXECUTION_CONTEXT_SANITIZER
     LD: clang
-    LDFLAGS: -fsanitize=thread -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
+    LDFLAGS: -fsanitize=thread
     LDXX: clang++
     compile_the_world: true
     test_environ:
@@ -2882,10 +2878,10 @@
   tsan:
     CC: clang
     CPPFLAGS: -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument
-      -fPIE -pie -DGPR_NO_DIRECT_SYSCALLS
+      -DGPR_NO_DIRECT_SYSCALLS
     CXX: clang++
     LD: clang
-    LDFLAGS: -fsanitize=thread -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
+    LDFLAGS: -fsanitize=thread
     LDXX: clang++
     compile_the_world: true
     test_environ:
diff --git a/src/core/iomgr/fd_posix.c b/src/core/iomgr/fd_posix.c
index 4ba7c5d..3edafa0 100644
--- a/src/core/iomgr/fd_posix.c
+++ b/src/core/iomgr/fd_posix.c
@@ -72,6 +72,9 @@
 static gpr_mu fd_freelist_mu;
 
 static void freelist_fd(grpc_fd *fd) {
+  // Note that this function must be called after a release store (or
+  // full-barrier operation) on refst so that prior actions on the fd are
+  // ordered before the fd becomes visible to the freelist
   gpr_mu_lock(&fd_freelist_mu);
   fd->freelist_next = fd_freelist;
   fd_freelist = fd;
@@ -92,7 +95,6 @@
     gpr_mu_init(&r->mu);
   }
 
-  gpr_atm_rel_store(&r->refst, 1);
   r->shutdown = 0;
   r->read_closure = CLOSURE_NOT_READY;
   r->write_closure = CLOSURE_NOT_READY;
@@ -104,6 +106,11 @@
   r->on_done_closure = NULL;
   r->closed = 0;
   r->released = 0;
+  // The last operation on r before returning it should be a release-store
+  // so that all the above fields are globally visible before the value of
+  // r could escape to another thread. Our refcount itself needs a release-store
+  // so use this
+  gpr_atm_rel_store(&r->refst, 1);
   return r;
 }
 
diff --git a/templates/tools/dockerfile/clang_update.include b/templates/tools/dockerfile/clang_update.include
new file mode 100644
index 0000000..83ab3e0
--- /dev/null
+++ b/templates/tools/dockerfile/clang_update.include
@@ -0,0 +1,32 @@
+#=================
+# Update clang to a version with improved tsan
+
+RUN apt-get update && apt-get -y install python cmake && apt-get clean
+
+RUN git clone -n -b release_38 http://llvm.org/git/llvm.git && ${'\\'}
+  cd llvm && git checkout ad57503 && cd ..
+RUN git clone -n -b release_38 http://llvm.org/git/clang.git && ${'\\'}
+  cd clang && git checkout ad2c56e && cd ..
+RUN git clone -n -b release_38 http://llvm.org/git/compiler-rt.git && ${'\\'}
+  cd compiler-rt && git checkout 3176922 && cd ..
+RUN git clone -n -b release_38 ${'\\'}
+  http://llvm.org/git/clang-tools-extra.git && cd clang-tools-extra && ${'\\'}
+  git checkout c288525 && cd ..
+RUN git clone -n -b release_38 http://llvm.org/git/libcxx.git && ${'\\'}
+  cd libcxx && git checkout fda3549  && cd ..
+RUN git clone -n -b release_38 http://llvm.org/git/libcxxabi.git && ${'\\'}
+  cd libcxxabi && git checkout 8d4e51d && cd ..
+
+RUN mv clang llvm/tools
+RUN mv compiler-rt llvm/projects
+RUN mv clang-tools-extra llvm/tools/clang/tools
+RUN mv libcxx llvm/projects
+RUN mv libcxxabi llvm/projects
+
+RUN mkdir llvm-build
+RUN cd llvm-build && cmake ${'\\'}
+  -DCMAKE_BUILD_TYPE:STRING=Release ${'\\'}
+  -DCMAKE_INSTALL_PREFIX:STRING=/usr ${'\\'}
+  -DLLVM_TARGETS_TO_BUILD:STRING=X86 ${'\\'}
+  ../llvm
+RUN make -C llvm-build && make -C llvm-build install && rm -rf llvm-build
diff --git a/templates/tools/dockerfile/test/cxx_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/cxx_jessie_x64/Dockerfile.template
index 842c534..eb11ce3 100644
--- a/templates/tools/dockerfile/test/cxx_jessie_x64/Dockerfile.template
+++ b/templates/tools/dockerfile/test/cxx_jessie_x64/Dockerfile.template
@@ -33,7 +33,7 @@
   
   <%include file="../../apt_get_basic.include"/>
   <%include file="../../cxx_deps.include"/>
+  <%include file="../../clang_update.include"/>
   <%include file="../../run_tests_addons.include"/>
   # Define the default command.
   CMD ["bash"]
-  
\ No newline at end of file
diff --git a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile
index e3ed39d..b848f23 100644
--- a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile
@@ -67,6 +67,39 @@
 # C++ dependencies
 RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang && apt-get clean
 
+#=================
+# Update clang to a version with improved tsan
+
+RUN apt-get update && apt-get -y install python cmake && apt-get clean
+
+RUN git clone -n -b release_38 http://llvm.org/git/llvm.git && \
+  cd llvm && git checkout ad57503 && cd ..
+RUN git clone -n -b release_38 http://llvm.org/git/clang.git && \
+  cd clang && git checkout ad2c56e && cd ..
+RUN git clone -n -b release_38 http://llvm.org/git/compiler-rt.git && \
+  cd compiler-rt && git checkout 3176922 && cd ..
+RUN git clone -n -b release_38 \
+  http://llvm.org/git/clang-tools-extra.git && cd clang-tools-extra && \
+  git checkout c288525 && cd ..
+RUN git clone -n -b release_38 http://llvm.org/git/libcxx.git && \
+  cd libcxx && git checkout fda3549  && cd ..
+RUN git clone -n -b release_38 http://llvm.org/git/libcxxabi.git && \
+  cd libcxxabi && git checkout 8d4e51d && cd ..
+
+RUN mv clang llvm/tools
+RUN mv compiler-rt llvm/projects
+RUN mv clang-tools-extra llvm/tools/clang/tools
+RUN mv libcxx llvm/projects
+RUN mv libcxxabi llvm/projects
+
+RUN mkdir llvm-build
+RUN cd llvm-build && cmake \
+  -DCMAKE_BUILD_TYPE:STRING=Release \
+  -DCMAKE_INSTALL_PREFIX:STRING=/usr \
+  -DLLVM_TARGETS_TO_BUILD:STRING=X86 \
+  ../llvm
+RUN make -C llvm-build && make -C llvm-build install && rm -rf llvm-build
+
 # Prepare ccache
 RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
 RUN ln -s /usr/bin/ccache /usr/local/bin/g++
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 6c6de6a..bd652f2 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -2317,9 +2317,7 @@
       "posix"
     ], 
     "cpu_cost": 0.5, 
-    "exclude_configs": [
-      "tsan"
-    ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "gtest": false, 
     "language": "c++", 
@@ -2338,9 +2336,7 @@
       "posix"
     ], 
     "cpu_cost": 10, 
-    "exclude_configs": [
-      "tsan"
-    ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "gtest": false, 
     "language": "c++",