Skip to content

Commit

Permalink
i#6662 public traces, part 9: TLB simulator with v2p (#6961)
Browse files Browse the repository at this point in the history
We want to provide a virtual to physical mapping for
the release of public traces to be used with our TLB
simulator.
We enable the TLB simulator to operate on the physical
addresses provided by a v2p.textproto file, which is
read by the previously added v2p_reader.

Adds an end-to-end test "tool.drcacheoff.tlb_simulator_v2p"
and a v2p.textproto mapping to
clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw.

Adds unit tests to check that the addresses used by the TLB
simulator are the actual physical ones.

Issue #6662
  • Loading branch information
edeiana authored Sep 18, 2024
1 parent 0a7eafb commit fd99b5e
Show file tree
Hide file tree
Showing 23 changed files with 542 additions and 30 deletions.
7 changes: 7 additions & 0 deletions api/docs/release.dox
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,13 @@ Further non-compatibility-affecting changes include:
input_workload_t::times_of_interest to the drmemtrace scheduler.
- Added v2p_reader_t to parse a virtual-to-physical mapping in textproto format and
v2p_info_t to hold that mapping in memory.
- Added -v2p_file option to drcachesim TLB tool to set the path to a v2p.textproto file,
which provides a virtual to physical mapping of addresses for an offline trace. This
option overwrites both -page_size and
#dynamorio::drmemtrace::TRACE_MARKER_TYPE_PAGE_SIZE (if present) with the page size in
v2p.textproto. Option -use_physical (in offline mode) must also be set to use the
mapping in v2p.textproto (note that -use_physical during tracing is not necessary, nor
related to -use_physical offline).
- Added -trace_instr_intervals_file option to the drmemtrace trace analysis tools
framework. The file must be in CSV format containing a <start,duration> tracing
interval per line where start and duration are expressed in number of instructions.
Expand Down
2 changes: 1 addition & 1 deletion clients/drcachesim/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -805,7 +805,7 @@ if (BUILD_TESTS)

add_executable(tool.drcachesim.unit_tests tests/drcachesim_unit_tests.cpp
tests/cache_replacement_policy_unit_test.cpp tests/config_reader_unit_test.cpp
tests/v2p_reader_unit_test.cpp)
tests/v2p_reader_unit_test.cpp tests/tlb_simulator_unit_test.cpp)
target_link_libraries(tool.drcachesim.unit_tests drmemtrace_simulator
# Link test_helpers first, or else the zlib main takes over.
drmemtrace_static drmemtrace_analyzer test_helpers ${zlib_libs})
Expand Down
7 changes: 6 additions & 1 deletion clients/drcachesim/analyzer_multi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@
* DAMAGE.
*/

#include "analysis_tool.h"
#include "analyzer.h"
#include "analyzer_multi.h"
#include "common/options.h"
#include "common/utils.h"
#include "common/directory_iterator.h"
#include "tlb_simulator.h"
#include "tracer/raw2trace_directory.h"
#include "tracer/raw2trace.h"
#include "reader/file_reader.h"
Expand Down Expand Up @@ -214,7 +216,10 @@ analyzer_multi_t::create_analysis_tool_from_options(const std::string &tool)
knobs.verbose = op_verbose.get_value();
knobs.cpu_scheduling = op_cpu_scheduling.get_value();
knobs.use_physical = op_use_physical.get_value();
return tlb_simulator_create(knobs);
knobs.v2p_file =
get_aux_file_path(op_v2p_file.get_value(), DRMEMTRACE_V2P_FILENAME);
analysis_tool_t *tlb_simulator = tlb_simulator_create(knobs);
return tlb_simulator;
} else if (tool == HISTOGRAM) {
return histogram_tool_create(op_line_size.get_value(), op_report_top.get_value(),
op_verbose.get_value());
Expand Down
10 changes: 10 additions & 0 deletions clients/drcachesim/common/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,16 @@ droption_t<unsigned int> op_virt2phys_freq(
"The units are the number of memory accesses per forced access. A value of 0 "
"uses the cached values for the entire application execution.");

droption_t<std::string> op_v2p_file(
DROPTION_SCOPE_FRONTEND, "v2p_file", "", "Path to v2p.textproto for simulator tools",
"The " TLB " simulator can use v2p.textproto to translate virtual addresses to "
"physical ones during offline analysis. If the file is named v2p.textproto and is in "
"the same directory as the trace file, or a raw/ subdirectory below the trace file, "
"this parameter can be omitted. This option overwrites both -page_size and the page "
"size marker in the trace (if present) with the page size in v2p.textproto. The "
"option -use_physical (in offline mode) must be set to use the v2p.textproto "
"mapping. Note that -use_physical does not need to be set during tracing.");

droption_t<bool> op_cpu_scheduling(
DROPTION_SCOPE_CLIENT, "cpu_scheduling", false,
"Map threads to cores matching recorded cpu execution",
Expand Down
1 change: 1 addition & 0 deletions clients/drcachesim/common/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ extern dynamorio::droption::droption_t<bool> op_instr_only_trace;
extern dynamorio::droption::droption_t<bool> op_coherence;
extern dynamorio::droption::droption_t<bool> op_use_physical;
extern dynamorio::droption::droption_t<unsigned int> op_virt2phys_freq;
extern dynamorio::droption::droption_t<std::string> op_v2p_file;
extern dynamorio::droption::droption_t<bool> op_cpu_scheduling;
extern dynamorio::droption::droption_t<dynamorio::droption::bytesize_t> op_max_trace_size;
extern dynamorio::droption::droption_t<dynamorio::droption::bytesize_t>
Expand Down
7 changes: 7 additions & 0 deletions clients/drcachesim/common/trace_entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -1479,6 +1479,13 @@ typedef struct _pt_data_buf_t pt_data_buf_t;
*/
#define DRMEMTRACE_KALLSYMS_FILENAME "kallsyms"

/**
* The name of the file in -offline mode where virtual to physical information is stored.
* This file contains a mapping from virtual to physical addresses, the page size used,
* the number of pages, and the number of bytes mapped.
*/
#define DRMEMTRACE_V2P_FILENAME "v2p.textproto"

} // namespace drmemtrace
} // namespace dynamorio

Expand Down
20 changes: 4 additions & 16 deletions clients/drcachesim/reader/v2p_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,10 @@
#include "v2p_reader.h"

#include <cstdint>
#include <sstream>
#include <stdint.h>

#include <cstdlib>
#include <fstream>
#include <string>
#include <sstream>
#include <unordered_map>
#include <vector>

Expand Down Expand Up @@ -76,19 +74,8 @@ v2p_reader_t::get_value_from_line(std::string line, uint64_t &value)
}

std::string
v2p_reader_t::create_v2p_info_from_file(std::string path_to_file, v2p_info_t &v2p_info)
v2p_reader_t::create_v2p_info_from_file(std::istream &v2p_file, v2p_info_t &v2p_info)
{
if (path_to_file.empty()) {
return "ERROR: Path to v2p.textproto is empty.";
}

std::stringstream error_ss;
std::ifstream file(path_to_file);
if (!file.is_open()) {
error_ss << "ERROR: Failed to open " << path_to_file << ".";
return error_ss.str();
}

const std::string page_size_key = "page_size";
const std::string page_count_key = "page_count";
const std::string bytes_mapped_key = "bytes_mapped";
Expand All @@ -98,8 +85,9 @@ v2p_reader_t::create_v2p_info_from_file(std::string path_to_file, v2p_info_t &v2
addr_t virtual_address = 0;
uint64_t value = 0;
std::string error_str;
std::stringstream error_ss;
std::string line;
while (std::getline(file, line)) {
while (std::getline(v2p_file, line)) {
// Ignore comments in v2p.textproto file.
if (starts_with(line, "#"))
continue;
Expand Down
3 changes: 2 additions & 1 deletion clients/drcachesim/reader/v2p_reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include "trace_entry.h"

#include <cstdint>
#include <istream>
#include <string>
#include <unordered_map>

Expand All @@ -68,7 +69,7 @@ class v2p_reader_t {
v2p_reader_t() = default;

std::string
create_v2p_info_from_file(std::string path_to_file, v2p_info_t &v2p_info);
create_v2p_info_from_file(std::istream &v2p_file, v2p_info_t &v2p_info);

private:
std::string
Expand Down
26 changes: 26 additions & 0 deletions clients/drcachesim/simulator/simulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <stdint.h>

#include <iostream>
#include <istream>
#include <unordered_map>
#include <utility>
#include <vector>
Expand All @@ -45,6 +46,7 @@
#include "options.h"
#include "utils.h"
#include "trace_entry.h"
#include "v2p_reader.h"

namespace dynamorio {
namespace drmemtrace {
Expand Down Expand Up @@ -87,6 +89,26 @@ simulator_t::init_knobs(unsigned int num_cores, uint64_t skip_refs, uint64_t war
}
}

std::string
simulator_t::create_v2p_from_file(std::istream &v2p_file)
{
// If we are not using physical addresses, we don't need a virtual to physical mapping
// at all.
if (!knob_use_physical_)
return "";

v2p_reader_t v2p_reader;
v2p_info_t v2p_info;
std::string error_str = v2p_reader.create_v2p_info_from_file(v2p_file, v2p_info);
if (!error_str.empty()) {
return error_str;
}
virt2phys_ = v2p_info.v2p_map;
page_size_ = static_cast<size_t>(v2p_info.page_size);
use_v2p_file_ = true;
return "";
}

std::string
simulator_t::initialize_stream(memtrace_stream_t *serial_stream)
{
Expand Down Expand Up @@ -138,6 +160,10 @@ simulator_t::process_memref(const memref_t &memref)
}
if (!knob_use_physical_)
return true;
// If we already have a virtual to physical mapping in a v2p file use that one and
// ignore the one in the trace, if any.
if (use_v2p_file_)
return true;
if (memref.marker.marker_type == TRACE_MARKER_TYPE_PAGE_SIZE) {
if (page_size_ != 0 && page_size_ != memref.marker.marker_value) {
ERRMSG("Error: conflicting page size markers");
Expand Down
11 changes: 11 additions & 0 deletions clients/drcachesim/simulator/simulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <stddef.h>
#include <stdint.h>

#include <istream>
#include <unordered_map>
#include <vector>

Expand Down Expand Up @@ -71,24 +72,32 @@ class simulator_t : public analysis_tool_t {
bool
process_memref(const memref_t &memref) override;

virtual std::string
create_v2p_from_file(std::istream &v2p_file);

protected:
// Initialize knobs. Success or failure is indicated by setting/resetting
// the success variable.
void
init_knobs(unsigned int num_cores, uint64_t skip_refs, uint64_t warmup_refs,
double warmup_fraction, uint64_t sim_refs, bool cpu_scheduling,
bool use_physical, unsigned int verbose);

void
print_core(int core) const;

int
find_emptiest_core(std::vector<int> &counts) const;

virtual int
core_for_thread(memref_tid_t tid);

virtual void
handle_thread_exit(memref_tid_t tid);

addr_t
virt2phys(addr_t virt) const;

memref_t
memref2phys(memref_t memref) const;

Expand Down Expand Up @@ -133,6 +142,8 @@ class simulator_t : public analysis_tool_t {
size_t page_size_ = 0;
std::unordered_map<addr_t, addr_t> virt2phys_;
addr_t prior_phys_addr_ = 0;
// Indicates whether the simulator uses a v2p file for virtual to physical mapping.
bool use_v2p_file_ = false;
};

} // namespace drmemtrace
Expand Down
41 changes: 40 additions & 1 deletion clients/drcachesim/simulator/tlb_simulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

#include <stddef.h>

#include <fstream>
#include <iostream>
#include <string>
#include <vector>
Expand All @@ -55,7 +56,27 @@ namespace drmemtrace {
analysis_tool_t *
tlb_simulator_create(const tlb_simulator_knobs_t &knobs)
{
return new tlb_simulator_t(knobs);
if (knobs.v2p_file.empty())
return new tlb_simulator_t(knobs);

std::ifstream fin;
fin.open(knobs.v2p_file);
if (!fin.is_open()) {
ERRMSG("Failed to open the v2p file '%s'\n", knobs.v2p_file.c_str());
return nullptr;
}

tlb_simulator_t *sim = new tlb_simulator_t(knobs);
std::string error_str = sim->create_v2p_from_file(fin);
fin.close();

if (!error_str.empty()) {
delete sim;
ERRMSG("ERROR: v2p_reader failed with: %s\n", error_str.c_str());
return nullptr;
}

return sim;
}

tlb_simulator_t::tlb_simulator_t(const tlb_simulator_knobs_t &knobs)
Expand Down Expand Up @@ -132,6 +153,24 @@ tlb_simulator_t::~tlb_simulator_t()
delete[] lltlbs_;
}

std::string
tlb_simulator_t::create_v2p_from_file(std::istream &v2p_file)
{
// If we are not using physical addresses, we don't need a virtual to physical mapping
// at all.
if (!knobs_.use_physical)
return "";

std::string error_str = simulator_t::create_v2p_from_file(v2p_file);
if (!error_str.empty()) {
return error_str;
}
// Overwrite tlb_simulator_t.knobs_.page size with simulator_t.page_size, which is
// set to be the page size in v2p_file.
knobs_.page_size = page_size_;
return "";
}

bool
tlb_simulator_t::process_memref(const memref_t &memref)
{
Expand Down
2 changes: 2 additions & 0 deletions clients/drcachesim/simulator/tlb_simulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class tlb_simulator_t : public simulator_t {
process_memref(const memref_t &memref) override;
bool
print_results() override;
std::string
create_v2p_from_file(std::istream &v2p_file) override;

protected:
// Create a tlb_t object with a specific replacement policy.
Expand Down
2 changes: 2 additions & 0 deletions clients/drcachesim/simulator/tlb_simulator_create.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ struct tlb_simulator_knobs_t {
, sim_refs(1ULL << 63)
, cpu_scheduling(false)
, use_physical(false)
, v2p_file("")
, verbose(0)
{
}
Expand All @@ -86,6 +87,7 @@ struct tlb_simulator_knobs_t {
uint64_t sim_refs;
bool cpu_scheduling;
bool use_physical;
std::string v2p_file;
unsigned int verbose;
};

Expand Down
4 changes: 2 additions & 2 deletions clients/drcachesim/tests/config_reader_unit_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ check_cache(const std::map<std::string, cache_params_t> &caches, std::string nam
}

void
unit_test_config_reader(const char *testdir)
unit_test_config_reader(const std::string &testdir)
{
cache_simulator_knobs_t knobs;
std::map<std::string, cache_params_t> caches;
std::string file_path = std::string(testdir) + "/single_core.conf";
std::string file_path = testdir + "/single_core.conf";

std::ifstream file_stream;
file_stream.open(file_path);
Expand Down
4 changes: 3 additions & 1 deletion clients/drcachesim/tests/config_reader_unit_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@
#ifndef _CONFIG_READER_UNIT_TEST_H_
#define _CONFIG_READER_UNIT_TEST_H_ 1

#include <string>

namespace dynamorio {
namespace drmemtrace {

void
unit_test_config_reader(const char *testdir);
unit_test_config_reader(const std::string &testdir);

} // namespace drmemtrace
} // namespace dynamorio
Expand Down
6 changes: 4 additions & 2 deletions clients/drcachesim/tests/drcachesim_unit_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <assert.h>
#include "config_reader_unit_test.h"
#include "v2p_reader_unit_test.h"
#include "tlb_simulator_unit_test.h"
#include "cache_replacement_policy_unit_test.h"
#include "simulator/cache.h"
#include "simulator/cache_lru.h"
Expand Down Expand Up @@ -842,8 +843,9 @@ test_main(int argc, const char *argv[])

unit_test_exclusive_cache();
unit_test_cache_accessors();
unit_test_config_reader(argv[1]);
unit_test_v2p_reader(argv[1]);
unit_test_config_reader(std::string(argv[1]));
unit_test_v2p_reader(std::string(argv[1]));
unit_test_tlb_simulator(std::string(argv[1]));
unit_test_cache_associativity();
unit_test_cache_size();
unit_test_cache_line_size();
Expand Down
Loading

0 comments on commit fd99b5e

Please sign in to comment.