[compiler-rt] r177517 - tsan: special handling of .rodata (don't try to find races, don't keep shadow, dont' put into traces)

Dmitry Vyukov dvyukov at google.com
Wed Mar 20 06:21:50 PDT 2013


Author: dvyukov
Date: Wed Mar 20 08:21:50 2013
New Revision: 177517

URL: http://llvm.org/viewvc/llvm-project?rev=177517&view=rev
Log:
tsan: special handling of .rodata (don't try to find races, don't keep shadow, dont' put into traces)


Modified:
    compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc?rev=177517&r1=177516&r2=177517&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc Wed Mar 20 08:21:50 2013
@@ -51,6 +51,8 @@ extern "C" struct mallinfo __libc_mallin
 
 namespace __tsan {
 
+const uptr kPageSize = 4096;
+
 #ifndef TSAN_GO
 ScopedInRtl::ScopedInRtl()
     : thr_(cur_thread()) {
@@ -162,6 +164,62 @@ static void ProtectRange(uptr beg, uptr
 #endif
 
 #ifndef TSAN_GO
+// Mark shadow for .rodata sections with the special kShadowRodata marker.
+// Accesses to .rodata can't race, so this saves time, memory and trace space.
+static void MapRodata() {
+  // First create temp file.
+  const char *tmpdir = GetEnv("TMPDIR");
+  if (tmpdir == 0)
+    tmpdir = GetEnv("TEST_TMPDIR");
+#ifdef P_tmpdir
+  if (tmpdir == 0)
+    tmpdir = P_tmpdir;
+#endif
+  if (tmpdir == 0)
+    return;
+  char filename[256];
+  internal_snprintf(filename, sizeof(filename), "%s/tsan.rodata.%u",
+                    tmpdir, GetPid());
+  fd_t fd = internal_open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
+  if (fd == kInvalidFd)
+    return;
+  // Fill the file with kShadowRodata.
+  const uptr kMarkerSize = 512 * 1024 / sizeof(u64);
+  InternalScopedBuffer<u64> marker(kMarkerSize);
+  for (u64 *p = marker.data(); p < marker.data() + kMarkerSize; p++)
+    *p = kShadowRodata;
+  internal_write(fd, marker.data(), marker.size());
+  // Map the file into memory.
+  void *page = internal_mmap(0, kPageSize, PROT_READ | PROT_WRITE,
+                             MAP_PRIVATE | MAP_ANONYMOUS, fd, 0);
+  if (page == MAP_FAILED) {
+    internal_close(fd);
+    internal_unlink(filename);
+    return;
+  }
+  // Map the file into shadow of .rodata sections.
+  MemoryMappingLayout proc_maps;
+  uptr start, end, offset, prot;
+  char name[128];
+  while (proc_maps.Next(&start, &end, &offset, name, ARRAY_SIZE(name), &prot)) {
+    if (name[0] != 0 && name[0] != '['
+        && (prot & MemoryMappingLayout::kProtectionRead)
+        && (prot & MemoryMappingLayout::kProtectionExecute)
+        && !(prot & MemoryMappingLayout::kProtectionWrite)
+        && IsAppMem(start)) {
+      // Assume it's .rodata
+      char *shadow_start = (char*)MemToShadow(start);
+      char *shadow_end = (char*)MemToShadow(end);
+      for (char *p = shadow_start; p < shadow_end; p += marker.size()) {
+        internal_mmap(p, Min<uptr>(marker.size(), shadow_end - p),
+                      PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, 0);
+      }
+    }
+  }
+  internal_close(fd);
+  internal_unlink(filename);
+}
+
 void InitializeShadowMemory() {
   uptr shadow = (uptr)MmapFixedNoReserve(kLinuxShadowBeg,
     kLinuxShadowEnd - kLinuxShadowBeg);
@@ -188,6 +246,8 @@ void InitializeShadowMemory() {
       kLinuxAppMemBeg, kLinuxAppMemEnd,
       (kLinuxAppMemEnd - kLinuxAppMemBeg) >> 30);
   DPrintf("stack        %zx\n", (uptr)&shadow);
+
+  MapRodata();
 }
 #endif
 

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc?rev=177517&r1=177516&r2=177517&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc Wed Mar 20 08:21:50 2013
@@ -457,6 +457,16 @@ void MemoryAccess(ThreadState *thr, uptr
   }
 #endif
 
+  if (*shadow_mem == kShadowRodata) {
+    // Access to .rodata section, no races here.
+    // Measurements show that it can be 10-20% of all memory accesses.
+    StatInc(thr, StatMop);
+    StatInc(thr, kAccessIsWrite ? StatMopWrite : StatMopRead);
+    StatInc(thr, (StatType)(StatMop1 + kAccessSizeLog));
+    StatInc(thr, StatMopRodata);
+    return;
+  }
+
   FastState fast_state = thr->fast_state;
   if (fast_state.GetIgnoreBit())
     return;

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc?rev=177517&r1=177516&r2=177517&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc Wed Mar 20 08:21:50 2013
@@ -298,6 +298,13 @@ void MemoryAccessRange(ThreadState *thr,
 
   StatInc(thr, StatMopRange);
 
+  if (*shadow_mem == kShadowRodata) {
+    // Access to .rodata section, no races here.
+    // Measurements show that it can be 10-20% of all memory accesses.
+    StatInc(thr, StatMopRangeRodata);
+    return;
+  }
+
   FastState fast_state = thr->fast_state;
   if (fast_state.GetIgnoreBit())
     return;

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc?rev=177517&r1=177516&r2=177517&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc Wed Mar 20 08:21:50 2013
@@ -38,6 +38,8 @@ void StatOutput(u64 *stat) {
   name[StatMop8]                         = "            size 8                ";
   name[StatMopSame]                      = "  Including same                  ";
   name[StatMopRange]                     = "  Including range                 ";
+  name[StatMopRodata]                    = "  Including .rodata               ";
+  name[StatMopRangeRodata]               = "  Including .rodata range         ";
   name[StatShadowProcessed]              = "Shadow processed                  ";
   name[StatShadowZero]                   = "  Including empty                 ";
   name[StatShadowNonZero]                = "  Including non empty             ";

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h?rev=177517&r1=177516&r2=177517&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h Wed Mar 20 08:21:50 2013
@@ -27,6 +27,8 @@ enum StatType {
   StatMop8,
   StatMopSame,
   StatMopRange,
+  StatMopRodata,
+  StatMopRangeRodata,
   StatShadowProcessed,
   StatShadowZero,
   StatShadowNonZero,  // Derived.





More information about the llvm-commits mailing list