From 8cd1ba599b7c8f116723ec7e66170523edf4a93f Mon Sep 17 00:00:00 2001 From: Wenlei He Date: Tue, 3 Sep 2019 10:01:26 -0700 Subject: [PATCH] [BOLT] Ignore LBR from kernel interrupts Summary: This change adds a switch (`ignore-interrupt-lbr`) to ignores LBR from perf input that is result of kernel interrupts. These asynchronous flow of user/kernel transition will make BOLT think that profile is stale, thus bailout optimization for functions. Ideally, user mode filter need to be set for `perf record` so we don't have asynchronous LBRs. However these are identifiable as kernel address space is known, so we can ignore any LBRs that come from or go into kernel addresses during aggregation. This is under a switch and off by default in case we need to BOLT kernel module. (cherry picked from FBD17170107) --- bolt/src/DataAggregator.cpp | 14 ++++++++++++++ bolt/src/DataAggregator.h | 7 +++++++ 2 files changed, 21 insertions(+) diff --git a/bolt/src/DataAggregator.cpp b/bolt/src/DataAggregator.cpp index 357da964f3b3..8f2e0e38c372 100644 --- a/bolt/src/DataAggregator.cpp +++ b/bolt/src/DataAggregator.cpp @@ -110,6 +110,13 @@ WriteAutoFDOData("autofdo", cl::ZeroOrMore, cl::cat(AggregatorCategory)); +static cl::opt +IgnoreInterruptLBR("ignore-interrupt-lbr", + cl::desc("Ignore kernel interrupt LBR that happens asynchronously"), + cl::init(false), + cl::ZeroOrMore, + cl::cat(AggregatorCategory)); + } namespace { @@ -898,6 +905,8 @@ ErrorOr DataAggregator::parseBranchSample() { if (std::error_code EC = LBRRes.getError()) return EC; auto LBR = LBRRes.get(); + if (ignoreKernelInterrupt(LBR)) + continue; if (!BC->HasFixedLoadAddress) adjustLBR(LBR, MMapInfoIter->second); Res.LBR.push_back(LBR); @@ -1081,6 +1090,11 @@ bool DataAggregator::hasData() { return true; } +bool DataAggregator::ignoreKernelInterrupt(LBREntry &LBR) const { + return opts::IgnoreInterruptLBR && + (LBR.From >= KernelBaseAddr || LBR.To >= KernelBaseAddr); +} + std::error_code DataAggregator::printLBRHeatMap() { outs() << "PERF2BOLT: parse branch events...\n"; NamedRegionTimer T("parseBranch", "Parsing branch events", TimerGroupName, diff --git a/bolt/src/DataAggregator.h b/bolt/src/DataAggregator.h index 331839f70a4f..0594e63fca4e 100644 --- a/bolt/src/DataAggregator.h +++ b/bolt/src/DataAggregator.h @@ -136,6 +136,10 @@ class DataAggregator : public DataReader { PerfProcessInfo MMapEventsPPI; PerfProcessInfo TaskEventsPPI; + /// Kernel VM starts at fixed based address + /// https://www.kernel.org/doc/Documentation/x86/x86_64/mm.txt + static constexpr uint64_t KernelBaseAddr = 0xffff800000000000; + /// Current list of created temporary files std::vector TempFiles; @@ -389,6 +393,9 @@ class DataAggregator : public DataReader { adjustAddress(LBR.To, MMI); } + /// Ignore kernel/user transition LBR if requested + bool ignoreKernelInterrupt(LBREntry &LBR) const; + public: DataAggregator(raw_ostream &Diag, StringRef BinaryName) : DataReader(Diag), BinaryName(llvm::sys::path::filename(BinaryName)) {}