[llvm] ceb196d - [llvm-exegesis] Validate that address annotations are aligned (#75554)

via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 15 09:45:34 PST 2023


Author: Aiden Grossman
Date: 2023-12-15T09:45:30-08:00
New Revision: ceb196d9903f4db7250bbc6c8da13eeae1b85886

URL: https://github.com/llvm/llvm-project/commit/ceb196d9903f4db7250bbc6c8da13eeae1b85886
DIFF: https://github.com/llvm/llvm-project/commit/ceb196d9903f4db7250bbc6c8da13eeae1b85886.diff

LOG: [llvm-exegesis] Validate that address annotations are aligned (#75554)

This patch adds in validation at two different levels that address
annotations are page aligned. This is necessary as otherwise the mmap
calls will fail as MAP_FIXED/MAP_FIXED_NOREPLACE require page aligned
addresses. This happens silently in the subprocess. This patch adds
validation at snippet parsing time to give feedback to the user and also
adds asserts at code generation/address usage time to ensure that other
users of the Exegesis APIs conform to the same requirements.

Added: 
    llvm/test/tools/llvm-exegesis/X86/latency/memory-annotations-alignment-page-boundary.s
    llvm/test/tools/llvm-exegesis/X86/latency/memory-annotations-snippet-alignment-page-boundary.s

Modified: 
    llvm/tools/llvm-exegesis/lib/Assembler.cpp
    llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
    llvm/tools/llvm-exegesis/lib/SnippetFile.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/llvm-exegesis/X86/latency/memory-annotations-alignment-page-boundary.s b/llvm/test/tools/llvm-exegesis/X86/latency/memory-annotations-alignment-page-boundary.s
new file mode 100644
index 00000000000000..121ac7c90af824
--- /dev/null
+++ b/llvm/test/tools/llvm-exegesis/X86/latency/memory-annotations-alignment-page-boundary.s
@@ -0,0 +1,14 @@
+# REQUIRES: exegesis-can-measure-latency, x86_64-linux
+
+# Test that we error out if the requested address is not aligned to a page
+# boundary. Here we test out mapping at 2^12+4, which is off from a page
+# boundary by four bytes.
+
+# RUN: not llvm-exegesis -mtriple=x86_64-unknown-unknown -mode=latency -snippets-file=%s -execution-mode=subprocess 2>&1 | FileCheck %s
+
+# LLVM-EXEGESIS-MEM-DEF test1 4096 414D47
+# LLVM-EXEGESIS-MEM-MAP test1 65540
+
+nop
+
+# CHECK: invalid comment 'LLVM-EXEGESIS-MEM-MAP  test1 65540', expected <ADDRESS> to be a multiple of the platform page size. 

diff  --git a/llvm/test/tools/llvm-exegesis/X86/latency/memory-annotations-snippet-alignment-page-boundary.s b/llvm/test/tools/llvm-exegesis/X86/latency/memory-annotations-snippet-alignment-page-boundary.s
new file mode 100644
index 00000000000000..4f5dfb9a9f5a74
--- /dev/null
+++ b/llvm/test/tools/llvm-exegesis/X86/latency/memory-annotations-snippet-alignment-page-boundary.s
@@ -0,0 +1,13 @@
+# REQUIRES: exegesis-can-measure-latency, x86_64-linux
+
+# Test that we error out if the requested snippet address is not aligned to
+# a page boundary. Here we test out mapping at 2^12+4 which is off from a page
+# boundary by four bytes.
+
+# RUN: not llvm-exegesis -mtriple=x86_64-unknown-unknown -mode=latency -snippets-file=%s -execution-mode=subprocess 2>&1 | FileCheck %s
+
+# LLVM-EXEGESIS-SNIPPET-ADDRESS 65540
+
+nop
+
+# CHECK: invalid comment 'LLVM-EXEGESIS-SNIPPET-ADDRESS 65540, expected <ADDRESS> to be a multiple of the platform page size.

diff  --git a/llvm/tools/llvm-exegesis/lib/Assembler.cpp b/llvm/tools/llvm-exegesis/lib/Assembler.cpp
index e17d239faa47e2..c2fad7c731a7d2 100644
--- a/llvm/tools/llvm-exegesis/lib/Assembler.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Assembler.cpp
@@ -36,6 +36,10 @@
 #include "perfmon/perf_event.h"
 #endif // HAVE_LIBPFM
 
+#ifdef __linux__
+#include <unistd.h>
+#endif
+
 namespace llvm {
 namespace exegesis {
 
@@ -53,6 +57,13 @@ static bool generateSnippetSetupCode(
   if (GenerateMemoryInstructions) {
     BBF.addInstructions(ET.generateMemoryInitialSetup());
     for (const MemoryMapping &MM : Key.MemoryMappings) {
+#ifdef __linux__
+      // The frontend that generates that parses the memory mapping information
+      // from the user should validate that the requested address is a multiple
+      // of the page size. Assert that this is true here.
+      assert(MM.Address % getpagesize() == 0 &&
+             "Memory mappings need to be aligned to page boundaries.");
+#endif
       BBF.addInstructions(ET.generateMmap(
           MM.Address, Key.MemoryValues.at(MM.MemoryValueName).SizeBytes,
           ET.getAuxiliaryMemoryStartAddress() +

diff  --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
index 41960c23a10d19..12e774e1a4b8d6 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
@@ -418,6 +418,12 @@ class SubProcessFunctionExecutorImpl
       exit(ChildProcessExitCodeE::RSeqDisableFailed);
 #endif // GLIBC_INITS_RSEQ
 
+    // The frontend that generates the memory annotation structures should
+    // validate that the address to map the snippet in at is a multiple of
+    // the page size. Assert that this is true here.
+    assert(Key.SnippetAddress % getpagesize() == 0 &&
+           "The snippet address needs to be aligned to a page boundary.");
+
     size_t FunctionDataCopySize = this->Function.FunctionBytes.size();
     void *MapAddress = NULL;
     int MapFlags = MAP_PRIVATE | MAP_ANONYMOUS;

diff  --git a/llvm/tools/llvm-exegesis/lib/SnippetFile.cpp b/llvm/tools/llvm-exegesis/lib/SnippetFile.cpp
index 286c606cd6fb19..7258fcb4279c7d 100644
--- a/llvm/tools/llvm-exegesis/lib/SnippetFile.cpp
+++ b/llvm/tools/llvm-exegesis/lib/SnippetFile.cpp
@@ -23,6 +23,10 @@
 #include "llvm/Support/SourceMgr.h"
 #include <string>
 
+#ifdef __linux__
+#include <unistd.h>
+#endif // __linux__
+
 namespace llvm {
 namespace exegesis {
 namespace {
@@ -118,6 +122,19 @@ class BenchmarkCodeStreamer : public MCStreamer, public AsmCommentConsumer {
       MemoryMapping MemMap;
       MemMap.MemoryValueName = Parts[0].trim().str();
       MemMap.Address = std::stol(Parts[1].trim().str());
+
+#ifdef __linux__
+      // Validate that the annotation is a multiple of the platform's page
+      // size.
+      if (MemMap.Address % getpagesize() != 0) {
+        errs() << "invalid comment 'LLVM-EXEGESIS-MEM-MAP " << CommentText
+               << "', expected <ADDRESS> to be a multiple of the platform page "
+                  "size.";
+        ++InvalidComments;
+        return;
+      }
+#endif // __linux__
+
       // validate that the annotation refers to an already existing memory
       // definition
       auto MemValIT = Result->Key.MemoryValues.find(Parts[0].trim().str());
@@ -142,6 +159,20 @@ class BenchmarkCodeStreamer : public MCStreamer, public AsmCommentConsumer {
         ++InvalidComments;
         return;
       }
+
+#ifdef __linux__
+      // Validate that the address in the annotation is a multiple of the
+      // platform's page size.
+      if (Result->Key.SnippetAddress % getpagesize() != 0) {
+        errs() << "invalid comment 'LLVM-EXEGESIS-SNIPPET-ADDRESS "
+               << CommentText
+               << ", expected <ADDRESS> to be a multiple of the platform page "
+                  "size.";
+        ++InvalidComments;
+        return;
+      }
+#endif // __linux__
+
       return;
     }
   }


        


More information about the llvm-commits mailing list